diff --git a/librtaputil/librtaputil.c b/librtaputil/librtaputil.c index c42597c..b87c4a2 100644 --- a/librtaputil/librtaputil.c +++ b/librtaputil/librtaputil.c @@ -6,6 +6,9 @@ #include "rtaputil.h" +#define DEBUG + + BOOL run = TRUE ; @@ -81,8 +84,8 @@ char frequency_to_channel(unsigned short channel) -/* Retourne une date au format struct timeval en mili-secondes */ -unsigned long timeval_to_ms(struct timeval d) +/* Convertit une date au format struct timeval en une valeur entière en millisecondes, et retourne le résultat */ +unsigned long long timeval_to_ms(struct timeval d) { return d.tv_sec * 1000 + d.tv_usec / 1000 ; } @@ -92,10 +95,11 @@ unsigned long timeval_to_ms(struct timeval d) /* Retourne le temps (en millisecondes) écoulé entre deux dates */ unsigned long sub_date(struct timeval sup, struct timeval inf) { - unsigned long sup_ms = sup.tv_sec * 1000 + sup.tv_usec / 1000 ; - unsigned long inf_ms = inf.tv_sec * 1000 + inf.tv_usec / 1000 ; - - return abs(sup_ms - inf_ms) ; + unsigned long sub = abs(timeval_to_ms(sup) - timeval_to_ms(inf)) ; +#ifdef DEBUG + printf("sub_date() : sub=%lu\n", sub) ; +#endif + return sub ; } @@ -211,6 +215,8 @@ int iface_mode_monitor(char *iface) } } + close(sockfd) ; + return 0 ; } @@ -232,6 +238,8 @@ int iface_set_channel(char *iface, int channel) return ERR_SETTING_CHANNEL ; } + close(sockfd) ; + return 0 ; } @@ -256,6 +264,8 @@ int iface_channel_hop(char *iface) if (channel > 1000) // Si la valeur est en Hz, channel = frequency_to_channel(channel) ; // on la convertit en numéro de canal (avec notre fonction maison, toujours un peu gruik). + close(sockfd) ; + /* Changement de canal */ if (channel == 4) // Si le canal est déjà à 4, return iface_set_channel(iface, 11) ; // on le passe à 11 ; diff --git a/librtaputil/rtaputil.h b/librtaputil/rtaputil.h index f3b5ff8..8b246d7 100644 --- a/librtaputil/rtaputil.h +++ b/librtaputil/rtaputil.h @@ -54,7 +54,7 @@ typedef struct _couple_message unsigned char ap_mac_addr_bytes[6] ; // Adresse MAC de l'AP émetteur de l'info en octets unsigned char mobile_mac_addr_bytes[6] ; // Adresse MAC du mobile en octets struct timeval request_time ; // Identifiant du paquet = date sur le client - struct timeval start_time ; // Heure d'arrivée du premier paquet du couple + struct timeval start_time ; // Heure d'arrivée du paquet sur l'AP unsigned char antenna_signal_dbm ; // Puissance du signal reçu par l'AP du mobile /* Données pour la calibration */ float x_position ; @@ -130,6 +130,13 @@ typedef struct _couple_message #define RTAP_FCS 14 +/* Taille des en-têtes des paquets (en octets) */ +#define IEEE80211_HEADER_SIZE 24 +#define LLC_HEADER_SIZE 8 +#define IP_HEADER_SIZE 20 +#define UDP_HEADER_SIZE 8 + + /* Fréquences des canaux Wi-Fi en Hz */ #define CHANNEL_1 2412 #define CHANNEL_2 2417 @@ -158,11 +165,12 @@ BOOL run ; #define ERR_READING_MODE 104 #define ERR_BAD_SIGNAL 111 + /* En-têtes de fonctions */ // Fonctions utilitaires char* mac_bytes_to_string(unsigned char *mac_binary) ; char frequency_to_channel(unsigned short channel) ; -unsigned long timeval_to_ms(struct timeval date) ; +unsigned long long timeval_to_ms(struct timeval date) ; unsigned long sub_date(struct timeval sup, struct timeval inf) ; BOOL mac_cmp(unsigned char *mac1, unsigned char *mac2) ; @@ -178,4 +186,12 @@ int iface_set_channel(char *iface, int channel) ; int iface_channel_hop(char *iface) ; +/* Macros */ + +/* Prend les flags de l'en-tête IEEE 802.11 en paramètre, + * retourne 0 si le bit Retry est absent, ou une valeur positive s'il est présent. + */ +#define IS_RETRY(IEEE80211_FLAGS) ((IEEE80211_FLAGS) & 0x08) + + #endif diff --git a/loc-bts/ap/apd.c b/loc-bts/ap/apd.c index 6c754cd..2d9f545 100644 --- a/loc-bts/ap/apd.c +++ b/loc-bts/ap/apd.c @@ -5,6 +5,7 @@ #include "ap.h" +#define DEBUG unsigned char mac[6] ; // Adresse MAC de l'AP @@ -48,13 +49,14 @@ int main(int argc, char *argv[]) + /* Fonction du thread, qui surveille la liste et envoie les infos au serveur de localisation au bout du timeout */ void* keep_mode_monitor(char *iface) { while (run) { iface_mode_monitor(iface) ; // Passage de l'interface en mode Monitor. - sleep(5) ; // Pause de 5 secondes. + sleep(1) ; // Pause de 1 secondes. } return NULL ; @@ -120,6 +122,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p ssize_t nsent ; // Retour de sendto BOOL check[15] ; // Champs présents unsigned char raw_packet_type ; // Type du packet reçu (beacon, data...) + unsigned char raw_packet_flags ; // Flags de l'en-tête IEEE 802.11 char packet_type ; // Type de demande de localisation (demande, calibration) unsigned short dst_port ; // Port destination du paquet capturé int i ; // Compteur @@ -128,18 +131,31 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p raw_packet_type = data[rtap_bytes] ; // Au bout de l'en-tête rtap il y a celle du 802.11 dont le premier determine le type (beacon ou pas) memcpy((unsigned char*) &dst_port, &data[rtap_bytes+24+8+20+3], 1) ; // On récupère le port de destination (mais il faut retourner les deux octets) memcpy(&((unsigned char*) &dst_port)[1], &data[rtap_bytes+24+8+20+2], 1) ; // (20 : longueur de l'en-tête IP, le port de destination étant les troisièmes et quatrièmes octet suivant). + raw_packet_flags = data[rtap_bytes+1] ; // On récupère les flags 802.11, qui sont dans l'en-tête 802.11. + +#ifdef DEBUG + if (raw_packet_type == RAW_PACKET_TYPE_DATA + && data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + 9] == RAW_PACKET_PROTO_UDP + && dst_port == LOC_REQUEST_DEFAULT_PORT) + { + printf("raw_packet_flags : %02x\n", raw_packet_flags) ; + if (IS_RETRY(raw_packet_flags)) + printf("Retry : pas à traiter\n") ; + } +#endif if (raw_packet_type == RAW_PACKET_TYPE_DATA // Si le paquet est de type data, - && data[rtap_bytes+24+8+9] == RAW_PACKET_PROTO_UDP // et de protocole UDP (24 : en-tête 802.11, 8 : en-tête LLC, 9 : position du champ "Protocol" de l'en-tête IP), - && dst_port == LOC_REQUEST_DEFAULT_PORT) // et le port de destination est le bon. + && data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + 9] == RAW_PACKET_PROTO_UDP // et de protocole UDP (9 : position du champ "Protocol" de l'en-tête IP), + && dst_port == LOC_REQUEST_DEFAULT_PORT // et le port de destination est le bon, + && ! IS_RETRY(raw_packet_flags)) // et ce n'est pas un Retry. { memcpy(couple.ap_mac_addr_bytes, mac, 6); // On copie la MAC de l'AP memcpy(couple.mobile_mac_addr_bytes, &data[rtap_bytes+10], 6); // L'adresse MAC source est 10 octets plus loin que le type de paquet gettimeofday(&couple.start_time, NULL) ; - packet_type = data[rtap_bytes+24+8+20+8] ; + packet_type = data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE] ; - memcpy(&couple.request_time, &data[rtap_bytes+24+8+20+8+1], sizeof(struct timeval)); + memcpy(&couple.request_time, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 1], sizeof(struct timeval)); switch(packet_type) @@ -156,10 +172,10 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p case PACKET_TYPE_CALIBRATION : if (print_values) printf("\nPaquet de calibration reçu.\n") ; - couple.direction = data[rtap_bytes+24+8+20+8 + 9]; - memcpy(&couple.x_position, &data[rtap_bytes+24+8+20+8+10], sizeof(float)); - memcpy(&couple.y_position, &data[rtap_bytes+24+8+20+8+14], sizeof(float)); - memcpy(&couple.z_position, &data[rtap_bytes+24+8+20+8+18], sizeof(float)); + couple.direction = data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 9]; + memcpy(&couple.x_position, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 10], sizeof(float)); + memcpy(&couple.y_position, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 14], sizeof(float)); + memcpy(&couple.z_position, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 18], sizeof(float)); break ; default : @@ -258,8 +274,8 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p *** Couple à envoyer ***\n\ \tMAC AP : %s\n\ \tMAC mobile : %s\n\ -\tNuméro de séquence (heure de la demande) : %lu\n\ -\tHeure d'arrivée de la demande de localisation sur l'AP : %lu\n\ +\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\ \tSignal : %d dBm\n\ \tPosition X : %f\n\ \tPosition Y : %f\n\ diff --git a/loc-bts/client/locclient.c b/loc-bts/client/locclient.c index ad813a2..1a3f203 100644 --- a/loc-bts/client/locclient.c +++ b/loc-bts/client/locclient.c @@ -5,7 +5,7 @@ #include "../../librtaputil/rtaputil.h" -//#define DEBUG +#define DEBUG /* Codes d'erreurs */ #define ERR_CREATING_SOCKET 1 @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) if(argc == ARGC_NORMAL) // Paquet normal { - printf("Envoi normal effectué à : %lu\n", timeval_to_ms(request_time)) ; + printf("Envoi normal effectué à : %llu\n", timeval_to_ms(request_time)) ; buf_size = sizeof(char) + sizeof(struct timeval) ; buf = malloc(buf_size) ; buf[0] = PACKET_TYPE_NORMAL ; // Type de paquet = demande @@ -95,7 +95,7 @@ int main(int argc, char *argv[]) else if(argc == ARGC_CALIB) // Paquet calibration { - printf("Envoi Calibration effectué à : %lu\n", timeval_to_ms(request_time)) ; + printf("Envoi Calibration effectué à : %llu\n", timeval_to_ms(request_time)) ; buf_offset = 0 ; buf_size = sizeof(char) * 2 + sizeof(struct timeval) + sizeof(float) * 3 ; @@ -121,6 +121,9 @@ int main(int argc, char *argv[]) /* Envoi des infos au serveur d'aggrégation */ nsent = sendto(sockfd, (void *) buf, buf_size, 0, (struct sockaddr *) &server, (socklen_t) sizeof(server)) ; +#ifdef DEBUG + printf("Paquets envoyés : .") ; +#endif if (nsent != (ssize_t) buf_size) { perror("Erreur lors de l'envoi des infos au serveur ") ; @@ -132,7 +135,13 @@ int main(int argc, char *argv[]) int i ; for (i = 0 ; i < NBPKT_CALIB - 1 ; i++) { + usleep(50000) ; // On attend 50 ms entre chaque paquet. + nsent = sendto(sockfd, (void *) buf, buf_size, 0, (struct sockaddr *) &server, (socklen_t) sizeof(server)) ; +#ifdef DEBUG + putchar('.') ; + fflush(stdout) ; +#endif if (nsent != (ssize_t) buf_size) { perror("Erreur lors de l'envoi des infos au serveur ") ; @@ -140,6 +149,10 @@ int main(int argc, char *argv[]) } } } +#ifdef DEBUG + putchar('\n') ; +#endif + (void) close(sockfd) ; diff --git a/loc-bts/rtapaggregate/rtapaggregate.h b/loc-bts/rtapaggregate/rtapaggregate.h index ba1fc5a..0890d86 100644 --- a/loc-bts/rtapaggregate/rtapaggregate.h +++ b/loc-bts/rtapaggregate/rtapaggregate.h @@ -9,8 +9,8 @@ #include "../../librtaputil/rtaputil.h" -#define AGGREGATE_TIMEOUT 500 // Timeout d'agrégation (en mili-secondes) -#define KEEP_TIMEOUT 2000 // Temps que l'on conserve les données dans la liste (en mili-secondes) +#define AGGREGATE_TIMEOUT 1500 // Timeout d'agrégation (en millisecondes) +#define KEEP_TIMEOUT 3000 // Temps que l'on conserve les données dans la liste (en millisecondes) #define CHECK_INTERVAL 500000 // Temps entre deux vérifications de la liste (en micro-secondes) @@ -37,16 +37,20 @@ typedef struct _couple_info_list /* Liste chaînée des couples MAC / séquence */ typedef struct _couple_list { + /* Numéro de séquence de la demande de localisation du mobile */ unsigned char mobile_mac_addr_bytes[6] ; // Adresse MAC du mobile en octets - struct timeval request_time ; // Numéro de séquence de la demande de localisation du mobile (heure de la demande sur le mobile) - struct timeval start_time ; // Heure d'arrivée du premier paquet du couple - couple_info_list *info ; // Liste des informations pour ce couple - struct _couple_list *next ; + struct timeval request_time ; // Heure de la demande sur le mobile + /* Données pour la calibration */ float x_position ; float y_position ; float z_position ; DIRECTION direction ; // Orientation de la demande de localisation + + /* Autres données */ + struct timeval start_time ; // Heure d'arrivée du premier paquet du couple sur le serveur d'agrégation + couple_info_list *info ; // Liste des informations pour ce couple + struct _couple_list *next ; } couple_list ; diff --git a/loc-bts/rtapaggregate/rtapaggregated.c b/loc-bts/rtapaggregate/rtapaggregated.c index 238974d..a13846f 100644 --- a/loc-bts/rtapaggregate/rtapaggregated.c +++ b/loc-bts/rtapaggregate/rtapaggregated.c @@ -5,6 +5,8 @@ #include "rtapaggregate.h" +#define DEBUG + char *out_file ; @@ -30,12 +32,10 @@ int main(int argc, char **argv) run = TRUE ; - /* Fichier de sortie */ out_file = malloc((strlen(argv[ARGV_OUTPUT_FILE]) + 1) * sizeof(char)) ; strcpy(out_file, argv[ARGV_OUTPUT_FILE]) ; - /* Mise en place des gestionnaires de signaux */ sigemptyset(&action.sa_mask) ; action.sa_handler = sigint_handler ; @@ -73,8 +73,8 @@ int main(int argc, char **argv) *** Message reçu du client ***\n\ \tMAC AP : %s\n\ \tMAC mobile : %s\n\ -\tNuméro de séquence (heure de la demande) : %lu\n\ -\tHeure d'arrivée de la demande de localisation sur l'AP : %lu\n\ +\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\ \tSignal : %d dBm\n\ \tPosition X : %f\n\ \tPosition Y : %f\n\ @@ -107,6 +107,7 @@ int main(int argc, char **argv) + /* 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) { @@ -115,6 +116,7 @@ void* monitor_couple_list(couple_list **couples) struct timeval current_time ; FILE *fd = NULL ; char *ap_mac_string ; + unsigned long sub ; // Résultat de sub_date(). fd = fopen(out_file, "a") ; // Ouverture du fichier de sortie en ajout if (fd == NULL) // Si ouverture échouée, @@ -133,11 +135,19 @@ void* monitor_couple_list(couple_list **couples) while (couple_ptr != NULL) // Parcours de la liste { + sub = sub_date(couple_ptr->start_time, current_time) ; + if (couple_ptr->info != NULL) // Si le couple atteint n'a pas déjà été traité { - if (sub_date(couple_ptr->start_time, current_time) > AGGREGATE_TIMEOUT) // Si le timeout est atteint, + if (sub > AGGREGATE_TIMEOUT) // Si le timeout est atteint, { - printf("* Timeout dépassé.\n") ; + printf("* Timeout dépassé.") ; +#ifdef DEBUG + printf(" sub=%lu > AGGREGATE_TIMEOUT=%d\n", sub, AGGREGATE_TIMEOUT) ; +#else + putchar('\n') ; +#endif + 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 couple_info_ptr = couple_ptr->info ; @@ -158,11 +168,16 @@ void* monitor_couple_list(couple_list **couples) } } - else if (sub_date(couple_ptr->start_time, current_time) > KEEP_TIMEOUT) // Si le couple a été traité et que le temps de garde est écoulé + else if (sub > KEEP_TIMEOUT) // Si le couple a été traité et que le temps de garde est écoulé { couple_list *couple_tmp = couple_ptr ; - printf("* Délai de garde dépassé.\n") ; + printf("* Délai de garde dépassé.") ; +#ifdef DEBUG + printf(" sub=%lu > KEEP_TIMEOUT=%d\n", sub, KEEP_TIMEOUT) ; +#else + putchar('\n') ; +#endif couple_ptr = couple_ptr->next ; @@ -199,12 +214,17 @@ void got_couple_info(couple_list **couples, couple_message message) { couple_list *tmp_couple = NULL ; couple_info_list *tmp_info = NULL ; + struct timeval start_time ; // Heure de réception du paquet + gettimeofday(&start_time, NULL) ; + + /* Initialisation d'un nouveau sous-maillon */ 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 ; + /* Ajout dans la liste */ tmp_couple = *couples ; if (*couples == NULL) // Si la liste de couples n'existe pas encore, { @@ -212,7 +232,7 @@ void got_couple_info(couple_list **couples, couple_message message) 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 ; - tmp_couple->start_time = message.start_time ; + tmp_couple->start_time = start_time ; tmp_couple->x_position = message.x_position ; tmp_couple->y_position = message.y_position ; tmp_couple->z_position = message.z_position ; @@ -237,7 +257,7 @@ void got_couple_info(couple_list **couples, couple_message message) 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 ; - tmp_couple->start_time = message.start_time ; + tmp_couple->start_time = start_time ; tmp_couple->x_position = message.x_position ; tmp_couple->y_position = message.y_position ; tmp_couple->z_position = message.z_position ; diff --git a/loc-mobile/TODO b/loc-mobile/TODO index b8c4cf5..4980a79 100644 --- a/loc-mobile/TODO +++ b/loc-mobile/TODO @@ -1 +1,2 @@ * Mettre l'interface Wi-Fi en paramètre du programme mobile. +* Envoyer les requêtes en broadcast. diff --git a/loc-mobile/mobile/mobile.c b/loc-mobile/mobile/mobile.c index 3c6d25b..c95f53d 100644 --- a/loc-mobile/mobile/mobile.c +++ b/loc-mobile/mobile/mobile.c @@ -255,6 +255,10 @@ int main(int argc, char **argv) iface_mode_monitor("eth2") ; // Passage de l'interface Wi-Fi en mode Monitor. FIXME ! mettre l'interface Wi-Fi en paramètre du programme (wifi_iface != capture_iface, cf. apd.c). + + /**** THREAAAAAAAAAD !!!!!!!! ****/ + + if ((ret = capture(capture_iface, capture_time, &results, options[NUM_OPT_VERB])) != 0) // Capture de paquets. return ret ; // On quitte avec le code d'erreur si la capture a mal fini.