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
2009-04-15 14:15:49 +02:00
cfg_t * cfg ; // Structure contenant la configuration
2008-02-14 08:54:51 +01:00
2009-05-29 17:02:20 +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
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()
2009-05-29 17:02:20 +02:00
char * mobile_ip_string ;
BOOL ref ;
2008-02-14 08:54:51 +01:00
2009-04-15 14:15:49 +02:00
cfg_opt_t opts [ ] = { // Options reconnues par confuse dans le fichier de config
CFG_INT ( " listening_port " , AGGREGATE_DEFAULT_PORT , CFGF_NONE ) , // Port d'écoute
2009-05-29 17:02:20 +02:00
CFG_INT ( " send_port " , POSITIONER_DEFAULT_PORT , CFGF_NONE ) , // Port de sortie
CFG_STR ( " ip_positioner " , " " , CFGF_NONE ) , // Adresse IP du serveur de géolocalisation
2009-04-15 14:15:49 +02:00
CFG_STR ( " output_file " , " " , CFGF_NONE ) , // Fichier de sortie
CFG_INT ( " aggregate_timeout " , DEFAULT_AGGREGATE_TIMEOUT , CFGF_NONE ) , // Timeout d'agrégation (en millisecondes)
CFG_INT ( " keep_timeout " , DEFAULT_KEEP_TIMEOUT , CFGF_NONE ) , // Temps que l'on conserve les données dans la liste (en millisecondes)
CFG_INT ( " check_interval " , DEFAULT_CHECK_INTERVAL , CFGF_NONE ) , // Temps entre deux vérifications de la liste (en micro-secondes)
2009-05-29 17:02:20 +02:00
CFG_STR ( " host_db " , DEFAULT_HOST_DB , CFGF_NONE ) ,
CFG_STR ( " db_name " , DEFAULT_DB_NAME , CFGF_NONE ) ,
CFG_STR ( " user_db " , DEFAULT_USER_DB , CFGF_NONE ) ,
CFG_STR ( " pass_db " , DEFAULT_PASS_DB , CFGF_NONE ) ,
2009-04-15 14:15:49 +02:00
CFG_END ( ) } ;
char * config_file ; // Nom du fichier de configuration
int opt ; // Retour de getopt
/* L'option -f sert à spécifier un fichier de configuration alternatif,
* on regarde en premier si elle est présente */
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 ) ;
}
else // Si -f n'est pas présente, on utilise le fichier de config par défaut
{
config_file = malloc ( ( strlen ( DEFAULT_CONFIG_FILE ) + 1 ) * sizeof ( char ) ) ;
strcpy ( config_file , DEFAULT_CONFIG_FILE ) ;
}
/* Lecture du fichier de configuration */
cfg = cfg_init ( opts , CFGF_NONE ) ; // Initialisation des options
if ( cfg_parse ( cfg , config_file ) = = CFG_PARSE_ERROR )
{
free ( config_file ) ;
return ERR_PARSING_CONFIG_FILE ;
}
free ( config_file ) ;
/* Lecture des arguments de la ligne de commandes */
optind = 1 ; // On reprend l'analyse des arguments au début
while ( ( opt = getopt ( argc , argv , OPTIONS ) ) ! = - 1 )
{
switch ( opt )
{
case ' f ' : // Fichier de configuration
// Déjà traité.
break ;
case ' l ' :
cfg_setint ( cfg , " listening_port " , strtol ( optarg , NULL , 0 ) ) ;
break ;
case ' o ' :
cfg_setstr ( cfg , " output_file " , optarg ) ;
break ;
case ' a ' :
cfg_setint ( cfg , " aggregate_timeout " , strtol ( optarg , NULL , 0 ) ) ;
break ;
case ' k ' :
cfg_setint ( cfg , " keep_timeout " , strtol ( optarg , NULL , 0 ) ) ;
break ;
case ' c ' :
cfg_setint ( cfg , " check_interval " , strtol ( optarg , NULL , 0 ) ) ;
break ;
2009-05-29 17:02:20 +02:00
case ' i ' :
cfg_setstr ( cfg , " ip_positioner " , optarg ) ;
break ;
case ' u ' :
cfg_setstr ( cfg , " user_db " , optarg ) ;
break ;
case ' n ' :
cfg_setstr ( cfg , " db_name " , optarg ) ;
break ;
case ' p ' :
cfg_setstr ( cfg , " pass_db " , optarg ) ;
break ;
case ' h ' :
cfg_setstr ( cfg , " host_db " , optarg ) ;
break ;
2009-04-15 14:15:49 +02:00
default :
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
}
/* Vérification des arguments */
// output_file //
if ( cfg_getstr ( cfg , " output_file " ) [ 0 ] = = ' \0 ' )
{
fprintf ( stderr , " Erreur ! Vous devez spécifier un fichier de sortie. \n " ) ;
2008-02-14 08:54:51 +01:00
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
2009-05-29 17:02:20 +02:00
// ip_positioner //
if ( cfg_getstr ( cfg , " ip_positioner " ) [ 0 ] = = ' \0 ' )
{
fprintf ( stderr , " Erreur ! Vous devez spécifier l'adresse IP du serveur de géolocalisation. \n " ) ;
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
2009-04-15 14:15:49 +02:00
// aggregate_timeout //
if ( cfg_getint ( cfg , " aggregate_timeout " ) < 0 )
{
# ifdef DEBUG
fprintf ( stderr , " Attention ! aggregate_timeout n'admet pas de valeur négative : application de la valeur par défaut. \n " ) ;
# endif // DEBUG
cfg_setint ( cfg , " aggregate_timeout " , DEFAULT_AGGREGATE_TIMEOUT ) ;
}
// keep_timeout //
if ( cfg_getint ( cfg , " keep_timeout " ) < 0 )
{
# ifdef DEBUG
fprintf ( stderr , " Attention ! keep_timeout n'admet pas de valeur négative : application de la valeur par défaut. \n " ) ;
# endif // DEBUG
cfg_setint ( cfg , " keep_timeout " , DEFAULT_KEEP_TIMEOUT ) ;
}
// check_interval //
if ( cfg_getint ( cfg , " check_interval " ) < 0 )
{
# ifdef DEBUG
fprintf ( stderr , " Attention ! check_interval n'admet pas de valeur négative : application de la valeur par défaut. \n " ) ;
# endif // DEBUG
cfg_setint ( cfg , " check_interval " , DEFAULT_CHECK_INTERVAL ) ;
}
2008-02-14 08:54:51 +01:00
2009-04-15 14:15:49 +02:00
# ifdef DEBUG
/* Affichage de la configuration */
fprintf ( stderr , " Configuration : \n " ) ;
cfg_print ( cfg , stderr ) ;
# endif // DEBUG
2008-02-14 08:54:51 +01:00
2009-04-15 14:15:49 +02:00
run = TRUE ;
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 */
2009-04-15 14:15:49 +02:00
if ( ( sockfd = create_udp_listening_socket ( cfg_getint ( cfg , " listening_port " ) ) ) < 0 )
2008-02-14 08:54:51 +01:00
{
2009-04-15 14:15:49 +02:00
fprintf ( stderr , " Erreur ! Impossible d'écouter sur le port %ld. \n " , cfg_getint ( cfg , " listening_port " ) ) ;
return ERR_CREATING_SOCKET ;
2008-02-14 08:54:51 +01:00
}
/* 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 ) ;
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 ) ;
ref = ( message . x_position ! = 0 & & message . y_position ! = 0 & & message . z_position ! = 0 ) ? TRUE : FALSE ;
2008-02-14 08:54:51 +01:00
2009-05-29 17:02:20 +02:00
Db_write_request ( message , ref ) ;
if ( ! ref ) got_couple_info ( & couples , message ) ;
2008-02-14 08:54:51 +01:00
}
( void ) close ( sockfd ) ; // Fermeture de la socket
2009-04-15 14:15:49 +02:00
free_couple_list ( & couples ) ; // Nettoyage de la liste
cfg_free ( cfg ) ; // Nettoyage de la configuration
2008-02-14 08:54:51 +01:00
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().
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
sockfd = create_udp_sending_socket ( cfg_getstr ( cfg , " ip_positioner " ) , cfg_getint ( cfg , " send_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 ) ;
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 ) ;
}
2009-05-29 17:02:20 +02:00
int Db_write_request ( couple_message message , BOOL ref )
{
char * buf = ( char * ) malloc ( 100 * sizeof ( char ) ) ;
sprintf ( buf , " hostaddr = '%s' dbname = '%s' user = '%s' password = '%s' " , cfg_getstr ( cfg , " host_db " ) , cfg_getstr ( cfg , " db_name " ) , cfg_getstr ( cfg , " user_db " ) , cfg_getstr ( cfg , " pass_db " ) ) ;
const char * conninfo = buf ;
PGconn * conn ;
int id_ap , id_mobile , id_request , id_point = - 1 ;
conn = PQconnectdb ( conninfo ) ;
if ( PQstatus ( conn ) ! = CONNECTION_OK ) {
printf ( " Connection à la base de donnée échouée : %s \n " , PQerrorMessage ( conn ) ) ;
PQfinish ( conn ) ;
return 1 ;
}
if ( ( id_ap = DbAccessPoint ( message , conn ) ) < 0 ) return 1 ;
if ( ( id_mobile = DbMobile ( message , conn ) ) < 0 ) return 1 ;
if ( ( id_request = DbRequest ( message , conn , id_mobile , & id_point , ref ) ) < 0 ) return 1 ;
DbPacket ( message , conn , id_ap , id_request , ref ) ;
PQfinish ( conn ) ;
return 0 ;
}
int DbAccessPoint ( couple_message message , PGconn * conn )
{
char * buf = ( char * ) malloc ( 200 * sizeof ( char ) ) ;
char * ap_mac_string ;
int id_ap ;
PGresult * res ;
/** Recherche de l'AP conserné **/
ap_mac_string = mac_bytes_to_string ( message . ap_mac_addr_bytes ) ;
sprintf ( buf , " SELECT id_ap, ap_addr FROM ap WHERE ap_addr = '%s'; " , ap_mac_string ) ;
res = PQexec ( conn , buf ) ;
if ( PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) {
printf ( " Commande incorrect : %s \n " , PQerrorMessage ( conn ) ) ;
return - 1 ;
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
} else if ( PQntuples ( res ) = = 0 ) {
PQclear ( res ) ;
sprintf ( buf , " SELECT * FROM ap; " ) ;
res = PQexec ( conn , buf ) ;
id_ap = ( PQntuples ( res ) ! = 0 ) ? atoi ( PQgetvalue ( res , PQntuples ( res ) - 1 , 0 ) ) + 1 : 1 ;
sprintf ( buf , " INSERT INTO ap VALUES('%d','%s', '0', '0', '0', '0', '2417000000', '5', '20'); " , id_ap , ap_mac_string ) ;
PQexec ( conn , buf ) ;
2009-05-29 17:02:20 +02:00
} else {
id_ap = atoi ( PQgetvalue ( res , 0 , 0 ) ) ;
}
PQclear ( res ) ;
free ( buf ) ;
return id_ap ;
}
int DbMobile ( couple_message message , PGconn * conn )
{
char * mobile_mac_string , * mobile_ip_string ;
char * buf = ( char * ) malloc ( 200 * sizeof ( char ) ) ;
int id_mobile ;
PGresult * res ;
/** Recherche du mobile conserné **/
mobile_mac_string = mac_bytes_to_string ( message . mobile_mac_addr_bytes ) ;
mobile_ip_string = ip_bytes_to_string ( message . mobile_ip_addr_bytes ) ;
sprintf ( buf , " SELECT * FROM mobile WHERE mobile_addr = '%s'; " , mobile_mac_string ) ;
res = PQexec ( conn , buf ) ;
if ( PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) {
printf ( " Commande incorrect : %s \n " , PQerrorMessage ( conn ) ) ;
return - 1 ;
} else if ( PQntuples ( res ) = = 0 ) {
PQclear ( res ) ;
sprintf ( buf , " SELECT * FROM mobile; " ) ;
res = PQexec ( conn , buf ) ;
id_mobile = ( PQntuples ( res ) ! = 0 ) ? atoi ( PQgetvalue ( res , PQntuples ( res ) - 1 , 0 ) ) + 1 : 1 ;
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
sprintf ( buf , " INSERT INTO mobile(id_mobile, mobile_addr, ip_mobile, last_connect) VALUES('%d','%s','%s','%llu'); " , id_mobile , mobile_mac_string , mobile_ip_string , timeval_to_ms ( message . request_time ) ) ;
2009-05-29 17:02:20 +02:00
PQexec ( conn , buf ) ;
} else {
id_mobile = atoi ( PQgetvalue ( res , 0 , 0 ) ) ;
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
sprintf ( buf , " UPDATE mobile SET last_connect = %llu, ip_mobile = '%s' WHERE id_mobile = %d; " , timeval_to_ms ( message . request_time ) , mobile_ip_string , id_mobile ) ;
2009-05-29 17:02:20 +02:00
PQexec ( conn , buf ) ;
}
PQclear ( res ) ;
free ( buf ) ;
return id_mobile ;
}
int DbRefPoint ( couple_message message , PGconn * conn )
{
char * buf = ( char * ) malloc ( 200 * sizeof ( char ) ) ;
int id_ref_point ;
char d = ' ' ;
PGresult * res ;
switch ( message . direction ) {
case 1 :
d = ' N ' ;
break ;
case 2 :
d = ' E ' ;
break ;
case 3 :
d = ' S ' ;
break ;
case 4 :
d = ' W ' ;
break ;
default :
d = ' ' ;
printf ( " Erreur : direction inconnue \n " ) ;
}
strcpy ( buf , " SELECT * FROM ref_point; " ) ;
res = PQexec ( conn , buf ) ;
id_ref_point = ( PQntuples ( res ) ! = 0 ) ? atoi ( PQgetvalue ( res , PQntuples ( res ) - 1 , 0 ) ) + 1 : 1 ;
sprintf ( buf , " INSERT INTO ref_point(id_ref_point, x, y, z, direction) VALUES('%d','%f','%f','%f','%c'); " , id_ref_point , message . x_position , message . y_position , message . z_position , d ) ;
PQexec ( conn , buf ) ;
return id_ref_point ;
}
int DbRequest ( couple_message message , PGconn * conn , int id_mobile , int * id_point , BOOL ref )
{
char * buf = ( char * ) malloc ( 200 * sizeof ( char ) ) ;
int id_request ;
PGresult * res ;
/** Ajout de la requete si elle n'existe pas **/
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
if ( ref ) sprintf ( buf , " SELECT * FROM ref_request WHERE mobile_time = %llu AND id_mobile = %d; " , timeval_to_ms ( message . request_time ) , id_mobile ) ;
else sprintf ( buf , " SELECT * FROM request WHERE mobile_time = %llu AND id_mobile = %d; " , timeval_to_ms ( message . request_time ) , id_mobile ) ;
2009-05-29 17:02:20 +02:00
res = PQexec ( conn , buf ) ;
if ( PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) {
printf ( " Commande incorrect : %s \n " , PQerrorMessage ( conn ) ) ;
return - 1 ;
} else if ( PQntuples ( res ) = = 0 ) {
PQclear ( res ) ;
if ( ref ) sprintf ( buf , " SELECT * FROM ref_request; " ) ;
else sprintf ( buf , " SELECT * FROM request; " ) ;
res = PQexec ( conn , buf ) ;
id_request = ( PQntuples ( res ) ! = 0 ) ? atoi ( PQgetvalue ( res , PQntuples ( res ) - 1 , 0 ) ) + 1 : 1 ;
if ( ref ) {
if ( ( * id_point = DbRefPoint ( message , conn ) ) < 0 ) return - 1 ;
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
sprintf ( buf , " INSERT INTO ref_request(id_ref_request, mobile_time, id_mobile, id_ref_point) VALUES('%d','%llu','%d','%d'); " , id_request , timeval_to_ms ( message . request_time ) , id_mobile , * id_point ) ;
} else sprintf ( buf , " INSERT INTO request(id_request, mobile_time, id_mobile) VALUES('%d','%llu','%d'); " , id_request , timeval_to_ms ( message . request_time ) , id_mobile ) ;
2009-05-29 17:02:20 +02:00
PQexec ( conn , buf ) ;
} else {
id_request = atoi ( PQgetvalue ( res , 0 , 0 ) ) ;
if ( ref ) * id_point = atoi ( PQgetvalue ( res , 0 , 3 ) ) ;
}
PQclear ( res ) ;
free ( buf ) ;
return id_request ;
}
int DbPacket ( couple_message message , PGconn * conn , int id_ap , int id_request , BOOL ref )
{
char * buf = ( char * ) malloc ( 200 * sizeof ( char ) ) ;
/** Ajout du paquet **/
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
if ( ref ) sprintf ( buf , " INSERT INTO ref_packet(ap_time, power, id_ap, id_ref_request) VALUES('%llu','%d','%d','%d'); " , timeval_to_ms ( message . start_time ) , message . antenna_signal_dbm - 0x100 , id_ap , id_request ) ;
else sprintf ( buf , " INSERT INTO packet(ap_time, power, id_ap, id_request) VALUES ( ' % llu ' , ' % d ' , ' % d ' , ' % d ' ) ; " , timeval_to_ms(message.start_time), message.antenna_signal_dbm - 0x100, id_ap, id_request);
2009-05-29 17:02:20 +02:00
PQexec ( conn , buf ) ;
free ( buf ) ;
return 0 ;
}
2008-02-14 08:54:51 +01:00
/* Affiche le mode d'emploi du programme */
void print_usage ( char * prog )
{
printf ( " Usage : \n \
2009-05-29 17:02:20 +02:00
\ t % s [ - f config_file ] [ - l listening_port ] [ - a aggregate_timeout ] [ - k keep_timeout ] [ - c check_interval ] - o output_file - i ip_positionner \ n \
\ tOptions BdD : \ n \
\ t - h hostaddr \ t : Adresse de l ' host de la BdD \ n \
\ t - n name_db \ t : Nom de la BdD \ n \
\ t - u user \ t : Nom d ' utilisateur pour l ' acces à la BdD \ n \
\ t - p passwd \ t : Mot de passe pour l ' acces à la BdD \ n \
2008-02-14 08:54:51 +01:00
" , prog) ;
}