2008-02-14 08:54:51 +01:00
/*
* This file is part of the rtap localisation project .
*/
2008-10-06 17:27:33 +02:00
# include "owlps-aggregator.h"
2008-02-14 08:54:51 +01:00
2008-03-14 11:31:04 +01:00
2008-02-14 08:54:51 +01:00
2010-07-12 12:50:02 +02:00
char * program_name = NULL ;
cfg_t * cfg = NULL ; // Configuration structure
couple_list * couples = NULL ; // Computed data list
2008-02-14 08:54:51 +01:00
2010-07-12 12:50:02 +02:00
int main ( int argc , char * * argv )
2009-05-29 17:02:20 +02:00
{
2010-07-12 12:50:02 +02:00
int ret = 0 ; // Valeur de retour du programme
struct sigaction action ; // Structure de mise en place des gestionnaires de signaux
pthread_t thread ; // Thread pour la fonction de surveillance de la liste d'informations agrégées
int sockfd ; // Socket d'écoute UDP
program_name = argv [ 0 ] ;
initialise_configuration ( argc , argv ) ;
/* Mise en place des gestionnaires de signaux */
sigemptyset ( & action . sa_mask ) ;
action . sa_handler = sigint_handler ;
sigaction ( SIGINT , & action , NULL ) ;
action . sa_handler = sigterm_handler ;
sigaction ( SIGTERM , & action , NULL ) ;
/* Création de la socket UDP */
if ( ( sockfd = create_udp_listening_socket ( cfg_getint ( cfg , " listening_port " ) ) ) < 0 )
2009-05-29 17:02:20 +02:00
{
2010-07-12 12:50:02 +02:00
fprintf ( stderr , " Erreur ! Impossible d'écouter sur le port %ld. \n " , cfg_getint ( cfg , " listening_port " ) ) ;
return ERR_CREATING_SOCKET ;
2009-05-29 17:02:20 +02:00
}
2010-07-12 12:50:02 +02:00
/* Création du thread */
pthread_create ( & thread , NULL , ( void * ) & monitor_couple_list , & couples ) ;
2009-05-29 17:02:20 +02:00
2010-07-12 12:50:02 +02:00
run = TRUE ;
ret = read_loop ( sockfd ) ;
2009-05-29 17:02:20 +02:00
2010-07-12 12:50:02 +02:00
( void ) close ( sockfd ) ; // Fermeture de la socket
free_couple_list ( & couples ) ; // Nettoyage de la liste
cfg_free ( cfg ) ; // Nettoyage de la configuration
2009-05-29 17:02:20 +02:00
2010-07-12 12:50:02 +02:00
printf ( " %s : fin. \n " , argv [ 0 ] ) ;
2009-05-29 17:02:20 +02:00
return ret ;
}
2008-02-14 08:54:51 +01:00
2010-07-12 12:50:02 +02:00
void initialise_configuration ( int argc , char * * argv )
2008-02-14 08:54:51 +01:00
{
2010-07-12 12:50:02 +02:00
parse_config_file ( argc , argv ) ;
parse_command_line ( argc , argv ) ;
check_configuration ( ) ;
2008-02-14 08:54:51 +01:00
2010-07-12 12:50:02 +02:00
# ifdef DEBUG
/* Configuration printing */
fprintf ( stderr , " Configuration : \n " ) ;
cfg_print ( cfg , stderr ) ;
# endif // DEBUG
}
void parse_config_file ( int argc , char * * argv )
{
// Config file options for confuse
cfg_opt_t opts [ ] =
{
CFG_INT ( " listening_port " , AGGREGATE_DEFAULT_PORT , CFGF_NONE ) ,
// Port and IP address of the localisation server:
CFG_INT ( " positioner_port " , POSITIONER_DEFAULT_PORT , CFGF_NONE ) ,
CFG_STR ( " positioner_ip " , POSITIONER_DEFAULT_IP , CFGF_NONE ) ,
CFG_STR ( " output_file " , " " , CFGF_NONE ) ,
// Timeouts (in milliseconds):
CFG_INT ( " aggregate_timeout " , DEFAULT_AGGREGATE_TIMEOUT , CFGF_NONE ) ,
CFG_INT ( " keep_timeout " , DEFAULT_KEEP_TIMEOUT , CFGF_NONE ) ,
// Time between two list checks (in microseconds):
CFG_INT ( " check_interval " , DEFAULT_CHECK_INTERVAL , CFGF_NONE ) ,
CFG_END ( )
} ;
char * config_file ;
// Option -f specifies a config file, so we search for it first
int opt ;
2009-04-15 14:15:49 +02:00
do
opt = getopt ( argc , argv , OPTIONS ) ;
while ( opt ! = ' f ' & & opt ! = - 1 ) ;
if ( opt = = ' f ' )
2008-02-14 08:54:51 +01:00
{
2009-04-15 14:15:49 +02:00
config_file = malloc ( ( strlen ( optarg ) + 1 ) * sizeof ( char ) ) ;
strcpy ( config_file , optarg ) ;
}
2010-07-12 12:50:02 +02:00
else // If -f isn't found, we use the default config file
2009-04-15 14:15:49 +02:00
{
config_file = malloc ( ( strlen ( DEFAULT_CONFIG_FILE ) + 1 ) * sizeof ( char ) ) ;
strcpy ( config_file , DEFAULT_CONFIG_FILE ) ;
}
2010-07-12 12:50:02 +02:00
/* Parse config file */
cfg = cfg_init ( opts , CFGF_NONE ) ; // Initialise options
2009-04-15 14:15:49 +02:00
if ( cfg_parse ( cfg , config_file ) = = CFG_PARSE_ERROR )
{
free ( config_file ) ;
2010-07-12 12:50:02 +02:00
exit ( ERR_PARSING_CONFIG_FILE ) ;
2009-04-15 14:15:49 +02:00
}
free ( config_file ) ;
2010-07-12 12:50:02 +02:00
}
void parse_command_line ( int argc , char * * argv )
{
int opt ;
optind = 1 ; // Rewind argument parsing
2009-04-15 14:15:49 +02:00
while ( ( opt = getopt ( argc , argv , OPTIONS ) ) ! = - 1 )
{
switch ( opt )
{
2009-07-02 13:12:51 +02:00
case ' a ' :
cfg_setint ( cfg , " aggregate_timeout " , strtol ( optarg , NULL , 0 ) ) ;
break ;
case ' c ' :
cfg_setint ( cfg , " check_interval " , strtol ( optarg , NULL , 0 ) ) ;
break ;
2010-07-12 12:50:02 +02:00
case ' f ' : // Config file
break ; // (already parsed)
2010-07-09 16:57:37 +02:00
case ' i ' :
2009-07-02 13:12:51 +02:00
cfg_setstr ( cfg , " positioner_ip " , optarg ) ;
2009-04-15 14:15:49 +02:00
break ;
case ' k ' :
cfg_setint ( cfg , " keep_timeout " , strtol ( optarg , NULL , 0 ) ) ;
break ;
2009-07-02 13:12:51 +02:00
case ' l ' :
cfg_setint ( cfg , " listening_port " , strtol ( optarg , NULL , 0 ) ) ;
2009-05-29 17:02:20 +02:00
break ;
2009-07-02 13:12:51 +02:00
case ' o ' :
cfg_setstr ( cfg , " output_file " , optarg ) ;
break ;
2009-05-29 17:02:20 +02:00
case ' p ' :
2009-07-02 13:12:51 +02:00
cfg_setint ( cfg , " positioner_port " , strtol ( optarg , NULL , 0 ) ) ;
2009-05-29 17:02:20 +02:00
break ;
2009-04-15 14:15:49 +02:00
default :
2010-07-12 12:50:02 +02:00
print_usage ( ) ;
exit ( ERR_BAD_USAGE ) ;
2009-04-15 14:15:49 +02:00
}
}
2010-07-12 12:50:02 +02:00
}
2009-04-15 14:15:49 +02:00
2010-07-12 12:50:02 +02:00
void check_configuration ( )
{
2009-04-15 14:15:49 +02:00
// output_file //
if ( cfg_getstr ( cfg , " output_file " ) [ 0 ] = = ' \0 ' )
{
2010-07-12 12:50:02 +02:00
fprintf ( stderr , " Error! You must specify an output file. \n " ) ;
print_usage ( ) ;
exit ( ERR_BAD_USAGE ) ;
2008-02-14 08:54:51 +01:00
}
2010-07-12 12:50:02 +02:00
2009-07-02 13:12:51 +02:00
// positioner_ip //
if ( cfg_getstr ( cfg , " positioner_ip " ) [ 0 ] = = ' \0 ' )
2009-05-29 17:02:20 +02:00
{
2010-07-12 12:50:02 +02:00
fprintf ( stderr , " Error! You must specify the IP address of the "
" localisation server. \n " ) ;
print_usage ( ) ;
exit ( ERR_BAD_USAGE ) ;
2009-05-29 17:02:20 +02:00
}
2010-07-12 12:50:02 +02:00
2009-04-15 14:15:49 +02:00
// aggregate_timeout //
if ( cfg_getint ( cfg , " aggregate_timeout " ) < 0 )
{
# ifdef DEBUG
2010-07-12 12:50:02 +02:00
fprintf ( stderr , " Warning! aggregate_timeout cannot be negative: "
" failing back to default value. \n " ) ;
2009-04-15 14:15:49 +02:00
# endif // DEBUG
cfg_setint ( cfg , " aggregate_timeout " , DEFAULT_AGGREGATE_TIMEOUT ) ;
}
2010-07-12 12:50:02 +02:00
2009-04-15 14:15:49 +02:00
// keep_timeout //
if ( cfg_getint ( cfg , " keep_timeout " ) < 0 )
{
# ifdef DEBUG
2010-07-12 12:50:02 +02:00
fprintf ( stderr , " Warning! keep_timeout cannot be negative: "
" failing back to default value. \n " ) ;
2009-04-15 14:15:49 +02:00
# endif // DEBUG
cfg_setint ( cfg , " keep_timeout " , DEFAULT_KEEP_TIMEOUT ) ;
}
2010-07-12 12:50:02 +02:00
2009-04-15 14:15:49 +02:00
// check_interval //
if ( cfg_getint ( cfg , " check_interval " ) < 0 )
{
# ifdef DEBUG
2010-07-12 12:50:02 +02:00
fprintf ( stderr , " Warning! check_interval cannot be negative: "
" failing back to default value. \n " ) ;
2009-04-15 14:15:49 +02:00
# endif // DEBUG
cfg_setint ( cfg , " check_interval " , DEFAULT_CHECK_INTERVAL ) ;
}
2010-07-12 12:50:02 +02:00
}
2008-02-14 08:54:51 +01:00
2010-07-12 12:50:02 +02:00
int read_loop ( int sockfd )
{
int ret = 0 ; // Return value
int nread ; // Retour de recvfrom
struct sockaddr_in client ; // Structure pour le client UDP
socklen_t client_len = sizeof ( client ) ; // Taille du client pour la socket
couple_message message ; // Message lu sur la socket
char * ap_mac_string , * mobile_mac_string ; // Pointeurs pour retour de mac_bytes_to_string()
char * mobile_ip_string ;
2008-02-14 08:54:51 +01:00
while ( run )
{
nread = recvfrom ( sockfd , & message , sizeof ( message ) , 0 , ( struct sockaddr * ) & client , & client_len ) ;
if ( nread < = 0 )
{
if ( run )
{
fprintf ( stderr , " Aucun message reçu du client ! \n " ) ;
ret = ERR_NO_MESSAGE_RECEIVED ;
}
break ;
}
ap_mac_string = mac_bytes_to_string ( message . ap_mac_addr_bytes ) ;
mobile_mac_string = mac_bytes_to_string ( message . mobile_mac_addr_bytes ) ;
2009-05-29 17:02:20 +02:00
mobile_ip_string = ip_bytes_to_string ( message . mobile_ip_addr_bytes ) ;
2008-02-14 08:54:51 +01:00
printf ( " \n \
* * * Message reçu du client * * * \ n \
\ tMAC AP : % s \ n \
\ tMAC mobile : % s \ n \
2009-05-29 17:02:20 +02:00
\ tIP mobile : % s \ n \
2008-03-14 11:31:04 +01:00
\ tNuméro de séquence ( heure de la demande ) : % llu \ n \
\ tHeure d ' arrivée de la demande de localisation sur l ' AP : % llu \ n \
2008-02-14 08:54:51 +01:00
\ tSignal : % d dBm \ n \
\ tPosition X : % f \ n \
\ tPosition Y : % f \ n \
\ tPosition Z : % f \ n \
\ tDirection : % hhd \ n \
" ,
ap_mac_string ,
mobile_mac_string ,
2009-05-29 17:02:20 +02:00
mobile_ip_string ,
2008-02-14 08:54:51 +01:00
timeval_to_ms ( message . request_time ) ,
timeval_to_ms ( message . start_time ) ,
message . antenna_signal_dbm - 0x100 ,
message . x_position ,
message . y_position ,
message . z_position ,
message . direction
) ;
free ( ap_mac_string ) ;
free ( mobile_mac_string ) ;
2009-05-29 17:02:20 +02:00
free ( mobile_ip_string ) ;
2008-02-14 08:54:51 +01:00
2010-07-09 16:57:37 +02:00
got_couple_info ( & couples , message ) ;
2008-02-14 08:54:51 +01:00
}
return ret ;
}
/* Fonction du thread, qui surveille la liste et envoie les infos au serveur de localisation au bout du timeout */
void * monitor_couple_list ( couple_list * * couples )
{
couple_list * couple_ptr , * couple_prev ;
couple_info_list * couple_info_ptr ;
struct timeval current_time ;
FILE * fd = NULL ;
char * ap_mac_string ;
2008-03-14 11:31:04 +01:00
unsigned long sub ; // Résultat de sub_date().
2010-07-09 16:57:37 +02:00
2009-05-29 17:02:20 +02:00
struct sockaddr_in serv ;
struct sockaddr_in client ;
socklen_t serv_len = sizeof ( serv ) ;
request demande ;
couple_info info ;
Incorporation de la dernière version de Julien
Extrait de son courriel :
« Par rapport à la précédente j'ai surtout corrigé des bugs. »
Note : la version du listener portable sur Fonera, envoyée en même temps
par Julien, viendra plus tard (le temps que je l'incorpore).
Détail des changements après analyse du code :
aggregator : correction de bogues.
positioning :
* Ajout d'un fichier de config format boost (cfg/config.cfg).
* Makefile : implantation des cibles "install" et "uninstall" ; la cible
"astyle" devient "style".
* accesspoint.{hh,cc}, area.cc, measurement.hh, point.{hh,cc},
referencepoint.{hh,cc} : cosmétique.
* owlps-positioning.c : correction de la lecture du fichier de config
(ajout d'une option permettant de spécifier un fichier alternatif).
* server.cc : essentiellement correction des requêtes.
* libowlps-positioning.{hh,cc} : passage de "unsigned long long" à
"uint64_t" comme type de retour de timeval_to_ms().
writeInDb :
* Ajout de la gestion d'un fichier de config.
* Ajout de deux scripts pour la BDD.
git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@96 785a6c6c-259e-4ff1-8b91-dc31627914f0
2009-07-01 15:39:58 +02:00
int sockfd ;
2009-05-29 17:02:20 +02:00
2009-07-02 13:12:51 +02:00
sockfd = create_udp_sending_socket ( cfg_getstr ( cfg , " positioner_ip " ) , cfg_getint ( cfg , " positioner_port " ) , & serv , & client ) ;
2008-02-14 08:54:51 +01:00
2009-04-15 14:15:49 +02:00
fd = fopen ( cfg_getstr ( cfg , " output_file " ) , " a " ) ; // Ouverture du fichier de sortie en ajout
2008-02-14 08:54:51 +01:00
if ( fd = = NULL ) // Si ouverture échouée,
{
perror ( " Impossible d'ouvrir le fichier de sortie " ) ;
fprintf ( stderr , " Redirection de la sortie sur la sortie standard. " ) ;
fd = stdout ; // on redirige sur stdout
}
while ( run )
{
couple_ptr = * couples ;
couple_prev = NULL ;
couple_info_ptr = NULL ;
gettimeofday ( & current_time , NULL ) ;
while ( couple_ptr ! = NULL ) // Parcours de la liste
{
2008-03-14 11:31:04 +01:00
sub = sub_date ( couple_ptr - > start_time , current_time ) ;
2008-02-14 08:54:51 +01:00
if ( couple_ptr - > info ! = NULL ) // Si le couple atteint n'a pas déjà été traité
{
2009-04-15 14:15:49 +02:00
if ( sub > ( unsigned long ) cfg_getint ( cfg , " aggregate_timeout " ) ) // Si le timeout est atteint,
2008-02-14 08:54:51 +01:00
{
2008-03-14 11:31:04 +01:00
printf ( " * Timeout dépassé. " ) ;
# ifdef DEBUG
2009-04-15 14:15:49 +02:00
printf ( " sub=%lu > aggregate_timeout=%ld \n " , sub , cfg_getint ( cfg , " aggregate_timeout " ) ) ;
# else // DEBUG
2008-03-14 11:31:04 +01:00
putchar ( ' \n ' ) ;
2009-04-15 14:15:49 +02:00
# endif // DEBUG
2008-03-14 11:31:04 +01:00
2008-07-17 10:21:41 +02:00
# ifdef TIMESTAMP
fprintf ( fd , " %llu; " , timeval_to_ms ( couple_ptr - > request_time ) ) ; // Inscription de la date de la demande (sur le mobile) dans le fichier
# endif // TIMESTAMP
2008-02-26 13:29:27 +01:00
fprintf ( fd , " %0.2f;%0.2f;%0.2f;%hhd " , couple_ptr - > x_position , couple_ptr - > y_position , couple_ptr - > z_position , couple_ptr - > direction ) ; // Inscription des infos du couple dans le fichier
2008-02-14 08:54:51 +01:00
2009-05-29 17:02:20 +02:00
memcpy ( demande . mobile_mac_addr_bytes , couple_ptr - > mobile_mac_addr_bytes , 6 ) ;
demande . request_time = couple_ptr - > request_time ;
demande . nb_couples = 0 ;
2008-02-14 08:54:51 +01:00
couple_info_ptr = couple_ptr - > info ;
2009-05-29 17:02:20 +02:00
while ( couple_info_ptr ! = NULL )
2008-02-14 08:54:51 +01:00
{
2009-05-29 17:02:20 +02:00
demande . nb_couples + + ;
couple_info_ptr = couple_info_ptr - > next ;
}
sendto ( sockfd , ( void * ) & demande , sizeof ( request ) , 0 , ( struct sockaddr * ) & serv , serv_len ) ;
couple_info_ptr = couple_ptr - > info ;
while ( couple_info_ptr ! = NULL ) // On envoi les couples au serveur et on vide la liste
{
// Envoi des infos de l'AP vers le serveur de géolocalisation
memcpy ( info . ap_mac_addr_bytes , couple_info_ptr - > ap_mac_addr_bytes , 6 ) ;
info . antenna_signal_dbm = couple_info_ptr - > antenna_signal_dbm - 0x100 ;
Incorporation de la dernière version de Julien
Extrait de son courriel :
« Par rapport à la précédente j'ai surtout corrigé des bugs. »
Note : la version du listener portable sur Fonera, envoyée en même temps
par Julien, viendra plus tard (le temps que je l'incorpore).
Détail des changements après analyse du code :
aggregator : correction de bogues.
positioning :
* Ajout d'un fichier de config format boost (cfg/config.cfg).
* Makefile : implantation des cibles "install" et "uninstall" ; la cible
"astyle" devient "style".
* accesspoint.{hh,cc}, area.cc, measurement.hh, point.{hh,cc},
referencepoint.{hh,cc} : cosmétique.
* owlps-positioning.c : correction de la lecture du fichier de config
(ajout d'une option permettant de spécifier un fichier alternatif).
* server.cc : essentiellement correction des requêtes.
* libowlps-positioning.{hh,cc} : passage de "unsigned long long" à
"uint64_t" comme type de retour de timeval_to_ms().
writeInDb :
* Ajout de la gestion d'un fichier de config.
* Ajout de deux scripts pour la BDD.
git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@96 785a6c6c-259e-4ff1-8b91-dc31627914f0
2009-07-01 15:39:58 +02:00
sendto ( sockfd , ( void * ) & info , sizeof ( couple_info ) , 0 , ( struct sockaddr * ) & serv , serv_len ) ;
2009-05-29 17:02:20 +02:00
// Inscription des infos de l'AP dans le fichier
2008-02-14 08:54:51 +01:00
ap_mac_string = mac_bytes_to_string ( couple_info_ptr - > ap_mac_addr_bytes ) ;
fprintf ( fd , " ;%s;%d " , ap_mac_string , couple_info_ptr - > antenna_signal_dbm - 0x100 ) ;
free ( ap_mac_string ) ;
// Suppression du maillon
couple_info_ptr = couple_info_ptr - > next ;
free ( couple_ptr - > info ) ;
couple_ptr - > info = couple_info_ptr ;
}
fprintf ( fd , " \n " ) ;
}
}
2009-04-15 14:15:49 +02:00
else if ( sub > ( unsigned long ) cfg_getint ( cfg , " keep_timeout " ) ) // Si le couple a été traité et que le temps de garde est écoulé
2008-02-14 08:54:51 +01:00
{
couple_list * couple_tmp = couple_ptr ;
2008-03-14 11:31:04 +01:00
printf ( " * Délai de garde dépassé. " ) ;
# ifdef DEBUG
2009-04-15 14:15:49 +02:00
printf ( " sub=%lu > keep_timeout=%ld \n " , sub , cfg_getint ( cfg , " keep_timeout " ) ) ;
# else // DEBUG
2008-03-14 11:31:04 +01:00
putchar ( ' \n ' ) ;
2009-04-15 14:15:49 +02:00
# endif // DEBUG
2008-02-14 08:54:51 +01:00
couple_ptr = couple_ptr - > next ;
if ( couple_prev = = NULL ) // Si on est en tête de liste,
* couples = couple_ptr ; // on positionne la tête sur le suivant
else
couple_prev - > next = couple_ptr ; // sinon on positionne le suivant du précédent sur le suivant.
free ( couple_tmp ) ;
continue ; // On saute les instructions pour aller au suivant puisque c'est déjà fait
}
// Couple suivant
couple_prev = couple_ptr ;
couple_ptr = couple_ptr - > next ;
}
fflush ( NULL ) ;
2009-04-15 14:15:49 +02:00
usleep ( cfg_getint ( cfg , " check_interval " ) ) ; // On attend avant de vérifier à nouveau
2008-02-14 08:54:51 +01:00
}
2008-02-22 16:04:49 +01:00
/* Fermeture du fichier */
if ( fclose ( fd ) ! = 0 )
perror ( " Erreur lors de la fermeture du fichier de sortie " ) ;
2008-02-14 08:54:51 +01:00
return NULL ;
}
/* Fonction appelée lors de la réception d'un paquet */
void got_couple_info ( couple_list * * couples , couple_message message )
{
couple_list * tmp_couple = NULL ;
couple_info_list * tmp_info = NULL ;
2008-10-10 15:00:34 +02:00
struct timeval start_time ; // Heure de réception du paquet par l'agrégateur
2008-03-14 11:31:04 +01:00
gettimeofday ( & start_time , NULL ) ;
2008-02-14 08:54:51 +01:00
2008-03-14 11:31:04 +01:00
/* Initialisation d'un nouveau sous-maillon */
2008-02-14 08:54:51 +01:00
tmp_info = malloc ( sizeof ( couple_info_list ) ) ;
memcpy ( tmp_info - > ap_mac_addr_bytes , message . ap_mac_addr_bytes , 6 ) ;
tmp_info - > antenna_signal_dbm = message . antenna_signal_dbm ;
tmp_info - > next = NULL ;
2008-03-14 11:31:04 +01:00
/* Ajout dans la liste */
2008-02-14 08:54:51 +01:00
tmp_couple = * couples ;
if ( * couples = = NULL ) // Si la liste de couples n'existe pas encore,
{
printf ( " Création de la liste des couples. \n " ) ;
tmp_couple = malloc ( sizeof ( couple_list ) ) ; // on la crée.
memcpy ( tmp_couple - > mobile_mac_addr_bytes , message . mobile_mac_addr_bytes , 6 ) ;
2009-09-03 11:09:48 +02:00
if ( timeval_to_ms ( message . request_time ) ! = 0 ) // Paquet explicite
tmp_couple - > request_time = message . request_time ; // Heure d'émission par le mobile
else // Paquet implicite
tmp_couple - > request_time = message . start_time ; // Heure de réception par l'AP
2008-10-10 15:00:34 +02:00
tmp_couple - > start_time = start_time ; // Enregistrement de la date locale de l'agrégateur et non de la date de réception de la demande sur l'AP
2008-02-14 08:54:51 +01:00
tmp_couple - > x_position = message . x_position ;
tmp_couple - > y_position = message . y_position ;
tmp_couple - > z_position = message . z_position ;
tmp_couple - > direction = message . direction ;
tmp_couple - > next = NULL ;
tmp_couple - > info = tmp_info ;
* couples = tmp_couple ;
}
else
2009-09-03 11:09:48 +02:00
{ // Sinon on cherche si le couple existe déjà dans la liste
if ( timeval_to_ms ( message . request_time ) ! = 0 ) // Paquet explicite
{
while ( tmp_couple ! = NULL )
{ // Critère : MAC et heure d'émission identiques.
if ( mac_cmp ( message . mobile_mac_addr_bytes , tmp_couple - > mobile_mac_addr_bytes ) = = 1
& & sub_date ( message . request_time , tmp_couple - > request_time ) = = 0 )
break ; // Si le couple existe déjà, on s'arrête dessus.
tmp_couple = tmp_couple - > next ;
}
}
else // Paquet implicite
{
while ( tmp_couple ! = NULL )
{ // Critère : MAC identiques et décalage des heures de réception par les AP d'au maximum 10 ms.
if ( mac_cmp ( message . mobile_mac_addr_bytes , tmp_couple - > mobile_mac_addr_bytes ) = = 1
& & sub_date ( message . start_time , tmp_couple - > request_time ) < = 10 ) // TODO : définir un paramètre pour le décalage maximal
break ; // Si le couple existe déjà, on s'arrête dessus.
tmp_couple = tmp_couple - > next ;
}
}
2008-02-14 08:54:51 +01:00
if ( tmp_couple = = NULL ) // Si couple inexistant dans la liste
{
printf ( " Création du couple. \n " ) ;
tmp_couple = malloc ( sizeof ( couple_list ) ) ; // on crée un nouveau couple.
memcpy ( tmp_couple - > mobile_mac_addr_bytes , message . mobile_mac_addr_bytes , 6 ) ;
2009-09-03 11:09:48 +02:00
if ( timeval_to_ms ( message . request_time ) ! = 0 ) // Paquet explicite
tmp_couple - > request_time = message . request_time ; // Heure d'émission par le mobile
else // Paquet implicite
tmp_couple - > request_time = message . start_time ; // Heure de réception par l'AP
2008-10-10 15:00:34 +02:00
tmp_couple - > start_time = start_time ; // Enregistrement de la date locale de l'agrégateur et non de la date de réception de la demande sur l'AP
2008-02-14 08:54:51 +01:00
tmp_couple - > x_position = message . x_position ;
tmp_couple - > y_position = message . y_position ;
tmp_couple - > z_position = message . z_position ;
tmp_couple - > direction = message . direction ;
tmp_couple - > next = * couples ;
tmp_couple - > info = tmp_info ;
* couples = tmp_couple ;
}
else // Si couple trouvé dans la liste
{
if ( tmp_couple - > info = = NULL ) // Si on a déjà envoyé les infos de ce couple au serveur
{
printf ( " Demande déjà traitée. \n " ) ;
free ( tmp_info ) ;
}
else
{
printf ( " Ajout des informations au couple. \n " ) ;
tmp_info - > next = tmp_couple - > info ; // on ajoute l'info.
tmp_couple - > info = tmp_info ;
}
}
}
}
/* Vide la liste chaînée de couples */
void free_couple_list ( couple_list * * couples )
{
couple_list * couple_ptr = * couples ;
couple_info_list * couple_info_ptr = NULL ;
if ( * couples ! = NULL )
{
while ( couple_ptr ! = NULL )
{
couple_info_ptr = couple_ptr - > info ;
while ( couple_info_ptr ! = NULL )
{
couple_info_ptr = couple_info_ptr - > next ;
free ( couple_ptr - > info ) ;
couple_ptr - > info = couple_info_ptr ;
}
couple_ptr = couple_ptr - > next ;
free ( * couples ) ;
* couples = couple_ptr ;
}
}
}
2009-09-03 11:09:48 +02:00
# ifdef DEBUG
2008-02-14 08:54:51 +01:00
/* Affiche la liste des couples */
void print_couple_list ( couple_list * couples )
{
couple_list * couple_ptr = couples ;
couple_info_list * info_ptr = NULL ;
char * mobile_mac_string ;
if ( couples = = NULL ) // Si la liste est vide
{
printf ( " Aucun couple. \n " ) ; // on l'affiche.
return ;
}
while ( couple_ptr ! = NULL )
{
info_ptr = couple_ptr - > info ; // On récupère le pointeur de la sous-liste
mobile_mac_string = mac_bytes_to_string ( couple_ptr - > mobile_mac_addr_bytes ) ;
printf ( " MAC du mobile : %s \n \
2008-10-10 15:00:34 +02:00
Numéro de séquence : % llu \ n \
Heure de réception de la demande de localisation : % llu \ n \
2008-02-14 08:54:51 +01:00
\ n " ,
mobile_mac_string ,
2008-10-10 15:00:34 +02:00
timeval_to_ms ( couple_ptr - > request_time ) ,
2009-02-17 14:47:07 +01:00
timeval_to_ms ( couple_ptr - > start_time )
2008-02-14 08:54:51 +01:00
) ;
free ( mobile_mac_string ) ;
while ( info_ptr ! = NULL ) // On parcourt toutes les informations relative au couple courant
{
print_couple_info ( info_ptr ) ;
putchar ( ' \n ' ) ;
info_ptr = info_ptr - > next ;
}
printf ( " \n \n " ) ;
couple_ptr = couple_ptr - > next ;
}
}
/* Affiche un maillon d'une couple_info_list */
void print_couple_info ( couple_info_list * info )
{
char * ap_mac_string ;
if ( info = = NULL )
return ;
ap_mac_string = mac_bytes_to_string ( info - > ap_mac_addr_bytes ) ;
printf ( " \t MAC de l'AP : %s \n \
\ tPuissance du signal : % d dBm \ n " ,
ap_mac_string ,
info - > antenna_signal_dbm - 0x100
) ;
free ( ap_mac_string ) ;
}
2009-09-03 11:09:48 +02:00
# endif // DEBUG
2008-02-14 08:54:51 +01:00
2010-07-12 12:50:02 +02:00
char * ip_bytes_to_string ( unsigned char * ip_binary )
{
int
taille = 16 ,
i = 0 ;
for ( i = 0 ; i < 4 ; + + i )
{
if ( ip_binary [ i ] < 0x64 )
taille - - ;
if ( ip_binary [ i ] < 0x10 )
taille - - ;
}
char * ret = malloc ( sizeof ( char ) * taille ) ;
sprintf ( ret , " %d.%d.%d.%d " , ip_binary [ 0 ] , ip_binary [ 1 ] , ip_binary [ 2 ] , ip_binary [ 3 ] ) ;
ret [ taille - 1 ] = ' \0 ' ;
return ret ;
}
2008-02-14 08:54:51 +01:00
/* Affiche le mode d'emploi du programme */
2010-07-12 12:50:02 +02:00
void print_usage ( )
2008-02-14 08:54:51 +01:00
{
printf ( " Usage : \n \
2010-07-09 16:57:37 +02:00
\ t % s [ - f config_file ] [ - l listening_port ] [ - i positionner_ip ] [ - p positioner_port ] [ - a aggregate_timeout ] [ - k keep_timeout ] [ - c check_interval ] [ - o output_file ] \ n \
2009-07-02 13:12:51 +02:00
Options générales : \ n \
\ t - f config_file : spécifie un fichier de configuration à lire à la place du fichier par défaut . \ n \
Options serveur : \ n \
\ t - l listening_port : seules les demandes envoyées sur ce port seront retenues ( défaut : % d ) . \ n \
\ t - i positionner_ip : adresse IP du serveur de calcul auquel seront transmises les demandes ( défaut : % s ) . \ n \
\ t - p positioner_port : les demandes agrégées seront transmises sur ce port du serveur de calcul ( défaut : % d ) . \ n \
Options d ' agrégation : \ n \
\ t - a aggregate_timeout : temps d ' agrégation ( défaut : % d millisecondes ) \ n \
2010-07-12 12:50:02 +02:00
\ t - k keep_timeout : temps de garde des demandes ( défaut : % d millisecondes ) \ n \
\ t - c check_interval : délai entre deux vérifications des demandes en mémoire , et agrégation ( défaut : % d micro - secondes ) \ n \
2009-07-02 13:12:51 +02:00
" ,
2010-07-12 12:50:02 +02:00
program_name ,
2009-07-02 13:12:51 +02:00
AGGREGATE_DEFAULT_PORT ,
POSITIONER_DEFAULT_IP ,
POSITIONER_DEFAULT_PORT ,
DEFAULT_AGGREGATE_TIMEOUT ,
DEFAULT_KEEP_TIMEOUT ,
2010-07-09 16:57:37 +02:00
DEFAULT_CHECK_INTERVAL
2009-07-02 13:12:51 +02:00
) ;
2008-02-14 08:54:51 +01:00
}