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
# define DEBUG
2008-02-14 08:54:51 +01:00
char * out_file ;
int main ( int argc , char * * argv )
{
int ret = 0 ; // Valeur de retour du programme
couple_list * couples = NULL ; // Liste des données traitées
struct sigaction action ; // Structure de mise en place des gestionnaires de signaux
int sockfd ; // Socket d'écoute UDP
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
pthread_t thread ; // Thread pour la fonction de surveillance de la liste d'informations agrégées
char * ap_mac_string , * mobile_mac_string ; // Pointeurs pour retour de mac_bytes_to_string()
2008-02-22 16:04:49 +01:00
if ( argc ! = ARGC )
2008-02-14 08:54:51 +01:00
{
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
run = TRUE ;
/* Fichier de sortie */
2008-02-22 16:04:49 +01:00
out_file = malloc ( ( strlen ( argv [ ARGV_OUTPUT_FILE ] ) + 1 ) * sizeof ( char ) ) ;
strcpy ( out_file , argv [ ARGV_OUTPUT_FILE ] ) ;
2008-02-14 08:54:51 +01:00
/* 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 ( AGGREGATE_DEFAULT_PORT ) ) < 0 )
{
fprintf ( stderr , " Erreur ! Impossible d'écouter sur le port %d. \n " , AGGREGATE_DEFAULT_PORT ) ;
exit ( ERR_CREATING_SOCKET ) ;
}
/* Création du thread */
pthread_create ( & thread , NULL , ( void * ) & monitor_couple_list , & couples ) ;
/* Lecture sur la socket */
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 ) ;
printf ( " \n \
* * * Message reçu du client * * * \ n \
\ tMAC AP : % s \ n \
\ tMAC 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 ,
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 ) ;
got_couple_info ( & couples , message ) ;
}
( void ) close ( sockfd ) ; // Fermeture de la socket
free_couple_list ( & couples ) ; // Nettoyage
free ( out_file ) ;
printf ( " %s : fin. \n " , argv [ 0 ] ) ;
return ret ;
}
2008-03-14 11:31:04 +01:00
2008-02-14 08:54:51 +01:00
/* 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().
2008-02-14 08:54:51 +01:00
fd = fopen ( out_file , " a " ) ; // Ouverture du fichier de sortie en ajout
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é
{
2008-03-14 11:31:04 +01:00
if ( sub > 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
printf ( " sub=%lu > AGGREGATE_TIMEOUT=%d \n " , sub , AGGREGATE_TIMEOUT ) ;
# else
putchar ( ' \n ' ) ;
# endif
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
couple_info_ptr = couple_ptr - > info ;
while ( couple_info_ptr ! = NULL ) // On vide la liste des infos
{
// Inscription des infos de l'AP dans le fichier
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 " ) ;
}
}
2008-03-14 11:31:04 +01:00
else if ( sub > 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
printf ( " sub=%lu > KEEP_TIMEOUT=%d \n " , sub , KEEP_TIMEOUT ) ;
# else
putchar ( ' \n ' ) ;
# endif
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 ) ;
usleep ( CHECK_INTERVAL ) ; // On attend avant de vérifier à nouveau
}
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 ) ;
tmp_couple - > request_time = message . request_time ;
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
{
while ( tmp_couple ! = NULL ) // Sinon on cherche si le couple existe déjà dans la liste
{
if ( mac_cmp ( message . mobile_mac_addr_bytes , tmp_couple - > mobile_mac_addr_bytes ) = = 1
& & message . request_time . tv_usec = = tmp_couple - > request_time . tv_usec ) // Si le couple existe déjà,
break ; // on s'arrête dessus.
tmp_couple = tmp_couple - > next ;
}
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 ) ;
tmp_couple - > request_time = message . request_time ;
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 ;
}
}
}
/* 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 ) ;
}
/* Affiche le mode d'emploi du programme */
void print_usage ( char * prog )
{
printf ( " Usage : \n \
\ t % s fichier_sortie \ n \
" , prog) ;
}