Import initial (TO)
Travail de l'UV TO52 à l'UTBM, par Matteo Cypriani et Pierre-Frédéric Rossel. Une partie du code provient du travail sur la TX. git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@3 785a6c6c-259e-4ff1-8b91-dc31627914f0
This commit is contained in:
parent
6716b37bb6
commit
29d23523ff
|
@ -0,0 +1,75 @@
|
||||||
|
.PHONY : all librtapanalyser librtaputil rtapaggregate ap client clean purge help install install-librtaputil install-rtapaggregate install-ap install-client
|
||||||
|
|
||||||
|
all : librtaputil rtapaggregate ap client
|
||||||
|
|
||||||
|
install : install-librtaputil install-rtapaggregate install-ap install-client
|
||||||
|
|
||||||
|
uninstall : uninstall-librtaputil uninstall-rtapaggregate uninstall-ap uninstall-client
|
||||||
|
|
||||||
|
librtaputil :
|
||||||
|
@cd librtaputil && make
|
||||||
|
|
||||||
|
rtapaggregate : librtaputil
|
||||||
|
@cd rtapaggregate && make
|
||||||
|
|
||||||
|
ap : librtaputil
|
||||||
|
@cd ap && make
|
||||||
|
|
||||||
|
client : librtaputil
|
||||||
|
@cd client && make
|
||||||
|
|
||||||
|
install-librtaputil : librtaputil
|
||||||
|
@cd librtaputil && make install
|
||||||
|
|
||||||
|
install-rtapaggregate : rtapaggregate install-librtaputil
|
||||||
|
@cd rtapaggregate && make install
|
||||||
|
|
||||||
|
install-ap : ap install-librtaputil
|
||||||
|
@cd ap && make install
|
||||||
|
|
||||||
|
install-client : client install-librtaputil
|
||||||
|
@cd client && make install
|
||||||
|
|
||||||
|
uninstall-librtaputil : librtaputil
|
||||||
|
@cd librtaputil && make uninstall
|
||||||
|
|
||||||
|
uninstall-rtapaggregate : rtapaggregate
|
||||||
|
@cd rtapaggregate && make uninstall
|
||||||
|
|
||||||
|
uninstall-ap : ap
|
||||||
|
@cd ap && make uninstall
|
||||||
|
|
||||||
|
uninstall-client : client
|
||||||
|
@cd client && make uninstall
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@cd rtapaggregate && make clean
|
||||||
|
@cd librtaputil && make clean
|
||||||
|
@cd ap && make clean
|
||||||
|
@cd client && make clean
|
||||||
|
|
||||||
|
purge :
|
||||||
|
@cd rtapaggregate && make purge
|
||||||
|
@cd librtaputil && make purge
|
||||||
|
@cd ap && make purge
|
||||||
|
@cd client && make purge
|
||||||
|
|
||||||
|
help :
|
||||||
|
@echo "Bibliothèques nécessaires à la compilation :\n\
|
||||||
|
libpcap0.8-dev\n\
|
||||||
|
librtaputil1.0 (fournie)\n\
|
||||||
|
\n\
|
||||||
|
Cibles possibles :\n\
|
||||||
|
all (cible par défaut) : Compile tous les modules.\n\
|
||||||
|
<module> : Compile uniquement le module <module> (et ses dépendances).\n\
|
||||||
|
\n\
|
||||||
|
install : Installe tous les modules.\n\
|
||||||
|
install-<module> : Installe uniquement le module <module> (et ses dépendances).\n\
|
||||||
|
\n\
|
||||||
|
uninstall : Désinstalle tous les modules.\n\
|
||||||
|
uninstall-<module> : Désinstalle uniquement le module <module> (et ses dépendances).\n\
|
||||||
|
\n\
|
||||||
|
clean : Supprime les fichiers temporaires.\n\
|
||||||
|
purge : Supprime le résultat de la compilation.\n\
|
||||||
|
\n\
|
||||||
|
Note : l'installation se fait dans l'arborescence /usr/local. Modifiez la variable PREFIX de chaque Makefile pour changer ce comportement."
|
|
@ -0,0 +1,75 @@
|
||||||
|
# Répertoire d'installation
|
||||||
|
PREFIX=/usr/local
|
||||||
|
INSTALL_DIR= $(PREFIX)/sbin
|
||||||
|
INSTALL_LIB= $(PREFIX)/lib
|
||||||
|
INSTALL_INC= $(PREFIX)/include
|
||||||
|
INSTALL_MAN= $(PREFIX)/share/man
|
||||||
|
|
||||||
|
# Compilateur
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
# Commandes d'installation et de désinstallation
|
||||||
|
RM=rm -fv
|
||||||
|
CP=cp -v
|
||||||
|
|
||||||
|
# Cible
|
||||||
|
TARGET=apd
|
||||||
|
HEADER=ap.h
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
|
||||||
|
DEPFLAGS=-MMD
|
||||||
|
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
|
||||||
|
PICFLAG=-fPIC
|
||||||
|
LIBS=-lm -lpcap ../librtaputil/librtaputil.so.1.0
|
||||||
|
|
||||||
|
|
||||||
|
## Cibles de compilation standard ##
|
||||||
|
|
||||||
|
.PHONY : all install uninstall clean purge help
|
||||||
|
|
||||||
|
all : $(TARGET)
|
||||||
|
|
||||||
|
% : %.o
|
||||||
|
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
%.o : %.c $(HEADER)
|
||||||
|
$(CC) $(XCFLAGS) -c $<
|
||||||
|
|
||||||
|
# Compilation du programme
|
||||||
|
$(TARGET) : $(TARGET).o $(HEADER)
|
||||||
|
|
||||||
|
|
||||||
|
## Installation / désinstallation ##
|
||||||
|
|
||||||
|
install : $(TARGET)
|
||||||
|
@$(CP) $(TARGET) $(INSTALL_DIR)
|
||||||
|
@cd $(INSTALL_DIR) ; chown root:root $(TARGET) ; chmod 755 $(TARGET)
|
||||||
|
|
||||||
|
uninstall :
|
||||||
|
@$(RM) $(INSTALL_DIR)/$(TARGET)
|
||||||
|
|
||||||
|
|
||||||
|
## Nettoyage ##
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@$(RM) -fv *~ *.o *.d
|
||||||
|
|
||||||
|
purge : clean
|
||||||
|
@$(RM) -fv $(TARGET)
|
||||||
|
|
||||||
|
|
||||||
|
## Aide ##
|
||||||
|
|
||||||
|
help :
|
||||||
|
@echo "Bibliothèques nécessaires à la compilation :\n\
|
||||||
|
libpcap0.8-dev\n\
|
||||||
|
librtaputil1.0 (fournie)\n\
|
||||||
|
\n\
|
||||||
|
Cibles possibles :\n\
|
||||||
|
$(TARGET) (cible par défaut) : Compile le programme $(TARGET).\n\
|
||||||
|
install : Installe le programme $(TARGET).\n\
|
||||||
|
uninstall : Désinstalle le programme $(TARGET).\n\
|
||||||
|
clean : Supprime les fichiers temporaires.\n\
|
||||||
|
purge : Supprime le résultat de la compilation.\n\
|
||||||
|
\n\
|
||||||
|
Note : l'installation se fait dans l'arborescence $(PREFIX). Modifiez la variable PREFIX du Makefile pour changer ce comportement."
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the rtap localisation project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "../librtaputil/rtaputil.h"
|
||||||
|
#include <pcap.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
// Pour la fonction get_mac_addr() :
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Codes d'erreurs */
|
||||||
|
#define ERR_CREATING_SOCKET 1 // Erreur lors de la création de la socket d'envoi
|
||||||
|
#define ERR_OPENING_IFACE 2 // Erreur lors de l'ouverture de l'interface de capture
|
||||||
|
#define ERR_BAD_USAGE 3 // Mauvais appel au programme
|
||||||
|
|
||||||
|
|
||||||
|
/* En-têtes des fonctions */
|
||||||
|
int capture(char *capture_iface, BOOL print_values) ;
|
||||||
|
void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, int sockfd, struct sockaddr_in *server, BOOL print_values) ;
|
||||||
|
void get_mac_addr(char *eth, unsigned char mac_bytes[6]) ;
|
||||||
|
void print_usage(char *prog) ;
|
|
@ -0,0 +1,311 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the rtap localisation project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ap.h"
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char mac[6] ; // Adresse MAC de l'AP
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct sigaction action ; // Structure de mise en place des gestionnaires de signaux
|
||||||
|
int ret ;
|
||||||
|
char *mac_string ;
|
||||||
|
|
||||||
|
if (argc != 3)
|
||||||
|
{
|
||||||
|
print_usage(argv[0]) ;
|
||||||
|
return ERR_BAD_USAGE ;
|
||||||
|
}
|
||||||
|
|
||||||
|
run = TRUE ;
|
||||||
|
|
||||||
|
/* 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) ;
|
||||||
|
|
||||||
|
get_mac_addr(argv[2], mac) ;
|
||||||
|
mac_string = mac_bytes_to_string(mac) ;
|
||||||
|
printf("Ma mac est : %s\n", mac_string) ;
|
||||||
|
free(mac_string) ;
|
||||||
|
|
||||||
|
ret = capture(argv[1], TRUE) ;
|
||||||
|
|
||||||
|
printf("%s : fin.\n", argv[0]) ;
|
||||||
|
return ret ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Capture des paquets en utilisant l'interface "capture_iface" pendant "capture_time" mili-secondes.
|
||||||
|
Les informations concernant les mobiles effectuant des requêtes sont conservées dans la liste "known_mobiles".
|
||||||
|
Les données capturées sont envoyées au serveur d'aggrégation à travers la socket UDP "socket".
|
||||||
|
*/
|
||||||
|
int capture(char *capture_iface, BOOL print_values)
|
||||||
|
{
|
||||||
|
pcap_t *handle ; // Descripteur de capture de paquets
|
||||||
|
char errbuf[PCAP_ERRBUF_SIZE] ;// Message d'erreur
|
||||||
|
// struct timeval tbegin, tcurrent ;
|
||||||
|
int sockfd ; // Descripteur de la socket vers le serveur d'aggrégation
|
||||||
|
struct sockaddr_in server, client ;
|
||||||
|
|
||||||
|
|
||||||
|
/* Sous-fonction de traitement des paquets capturés */
|
||||||
|
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
|
||||||
|
{
|
||||||
|
read_packet(args, header, packet, sockfd, &server, print_values) ; // On appelle la fonction read_packet() avec les mêmes arguments, plus "print_values" qui indique si on doit afficher le paquet.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handle = pcap_open_live(capture_iface, BUFSIZ, 1, 1000, errbuf) ; // Début de la capture
|
||||||
|
if (handle == NULL) // Le lancement de la capture a-t-il échoué ?
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Impossible d'ouvrir l'interface « %s » : %s\n", capture_iface, errbuf) ;
|
||||||
|
return ERR_OPENING_IFACE ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
|
||||||
|
sockfd = create_udp_sending_socket("127.0.0.1", AGGREGATE_DEFAULT_PORT, &server, &client);
|
||||||
|
if (sockfd < 0)
|
||||||
|
{
|
||||||
|
perror("Erreur ! Impossible de créer la socket vers le serveur d'aggrégation \n");
|
||||||
|
return ERR_CREATING_SOCKET ;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(run)
|
||||||
|
{
|
||||||
|
pcap_loop(handle, 1, got_packet, NULL) ; // Collecte 1 paquet et appelle la fonction got_packet quand pcaploop a recupéré des paquets
|
||||||
|
}
|
||||||
|
|
||||||
|
pcap_close(handle) ; // Arrêt de la capture.
|
||||||
|
(void) close(sockfd) ; // Fermeture de la socket
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Traite un paquet et l'envoie au serveur d'agrégation */
|
||||||
|
void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, int sockfd, struct sockaddr_in *server, BOOL print_values)
|
||||||
|
{
|
||||||
|
unsigned char *data = (unsigned char *) packet ; // Recopie dans data l'adresse du paquet capturé
|
||||||
|
unsigned short int rtap_bytes ; // Taille des données reçues
|
||||||
|
unsigned char c ;
|
||||||
|
int i ;
|
||||||
|
unsigned int rtap_presentflags, rtap_position ;
|
||||||
|
couple_message couple ;
|
||||||
|
ssize_t nsent ; // Retour de sendto
|
||||||
|
BOOL check[15] ; // Champs présents
|
||||||
|
char packet_type ;
|
||||||
|
|
||||||
|
memcpy(&rtap_bytes, &data[2], sizeof(unsigned short int)) ; // Recopie les deux octets à partir du troisième octet de donnée qui est la taille de l'en-tête rtap (change avec des flags)
|
||||||
|
c = 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)
|
||||||
|
if (c == 0x08 // Si le paquet est de type data,
|
||||||
|
&& data[rtap_bytes+24+8+9] == 0x11 // 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),
|
||||||
|
&& data[rtap_bytes+24+8+20+2] == 0x26 && data[rtap_bytes+24+8+20+3] == 0xac) // et le port de destination est 9900 (20 : longueur de l'en-tête IP, le port de destination étant les troisièmes et quatrièmes octet suivant).
|
||||||
|
{
|
||||||
|
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); // Dans le cas du beacon, l'adresse MAC est 10 octets plus loin
|
||||||
|
gettimeofday(&couple.start_time, NULL) ;
|
||||||
|
|
||||||
|
packet_type = data[rtap_bytes+24+8+20+8] ;
|
||||||
|
|
||||||
|
memcpy(&couple.request_time, &data[rtap_bytes+24+8+20+8+1], sizeof(struct timeval));
|
||||||
|
|
||||||
|
|
||||||
|
switch(packet_type)
|
||||||
|
{
|
||||||
|
case PACKET_TYPE_NORMAL :
|
||||||
|
if (print_values)
|
||||||
|
printf("Paquet normal reçu.\n") ;
|
||||||
|
couple.direction = 0 ;
|
||||||
|
couple.x_position = 0 ;
|
||||||
|
couple.y_position = 0 ;
|
||||||
|
couple.z_position = 0 ;
|
||||||
|
break ;
|
||||||
|
|
||||||
|
case PACKET_TYPE_CALIBRATION :
|
||||||
|
if (print_values)
|
||||||
|
printf("Paquet 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));
|
||||||
|
break ;
|
||||||
|
|
||||||
|
default :
|
||||||
|
if (print_values)
|
||||||
|
printf("Paquet bizarre reçu.\n") ;
|
||||||
|
fprintf(stderr, "Erreur ! Type de paquet inconnu (%d).\n", packet_type) ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(&rtap_presentflags, &data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS); // Récupère les flags de l'en-tête rtap
|
||||||
|
|
||||||
|
for (i = 0 ; i < 15 ; i++)
|
||||||
|
check[i] = FALSE ;
|
||||||
|
rtap_position = 8 ; // début des champs déterminés par le present flag
|
||||||
|
|
||||||
|
for(i=0 ; i < 14 ; i++) // on teste les 15 premiers bits du champ flag afin de valider la présence et de les copier
|
||||||
|
{
|
||||||
|
if ((rtap_presentflags % 2) == 1)
|
||||||
|
{
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case RTAP_MACTS:
|
||||||
|
check[RTAP_MACTS] = TRUE ;
|
||||||
|
rtap_position += RTAP_L_MACTS ;
|
||||||
|
break ;
|
||||||
|
case RTAP_FLAGS:
|
||||||
|
check[RTAP_FLAGS] = TRUE;
|
||||||
|
rtap_position += RTAP_L_FLAGS ;
|
||||||
|
break ;
|
||||||
|
case RTAP_RATE:
|
||||||
|
check[RTAP_RATE] = TRUE;
|
||||||
|
rtap_position += RTAP_L_RATE ;
|
||||||
|
break ;
|
||||||
|
case RTAP_CHANNEL:
|
||||||
|
rtap_position += RTAP_L_CHANNEL ;
|
||||||
|
rtap_position += RTAP_L_CHANNELTYPE ;
|
||||||
|
break ;
|
||||||
|
case RTAP_FHSS:
|
||||||
|
check[RTAP_FHSS] = TRUE;
|
||||||
|
rtap_position += RTAP_L_FHSS ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNASIGNALDBM:
|
||||||
|
memcpy(&(couple.antenna_signal_dbm), &data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ;
|
||||||
|
check[RTAP_ANTENNASIGNALDBM] = TRUE;
|
||||||
|
if (print_values)
|
||||||
|
printf("Antenna Signal : %d dBm\n", couple.antenna_signal_dbm - 0x100);
|
||||||
|
rtap_position += RTAP_L_ANTENNASIGNALDBM ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNANOISEDBM:
|
||||||
|
check[RTAP_ANTENNANOISEDBM] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNANOISEDBM ;
|
||||||
|
break ;
|
||||||
|
case RTAP_LOCKQUALITY:
|
||||||
|
check[RTAP_LOCKQUALITY] = TRUE;
|
||||||
|
rtap_position += RTAP_L_LOCKQUALITY ;
|
||||||
|
break ;
|
||||||
|
case RTAP_TXATTENUATION:
|
||||||
|
check[RTAP_TXATTENUATION] = TRUE;
|
||||||
|
rtap_position += RTAP_L_TXATTENUATION ;
|
||||||
|
break ;
|
||||||
|
case RTAP_TXATTENUATIONDB:
|
||||||
|
check[RTAP_TXATTENUATIONDB] = TRUE;
|
||||||
|
rtap_position += RTAP_L_TXATTENUATIONDB ;
|
||||||
|
break ;
|
||||||
|
case RTAP_TXATTENUATIONDBM:
|
||||||
|
check[RTAP_TXATTENUATIONDBM] = TRUE;
|
||||||
|
rtap_position += RTAP_L_TXATTENUATIONDBM ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNA:
|
||||||
|
check[RTAP_ANTENNA] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNA ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNASIGNALDB:
|
||||||
|
check[RTAP_ANTENNASIGNALDB] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNASIGNALDB ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNANOISEDB:
|
||||||
|
check[RTAP_ANTENNANOISEDB] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNANOISEDB ;
|
||||||
|
break ;
|
||||||
|
case RTAP_FCS:
|
||||||
|
check[RTAP_FCS] = TRUE;
|
||||||
|
rtap_position += RTAP_L_FCS ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rtap_presentflags /= 2 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print_values)
|
||||||
|
printf("\n") ;
|
||||||
|
|
||||||
|
if (print_values)
|
||||||
|
{
|
||||||
|
char *ap_mac_string = mac_bytes_to_string(couple.ap_mac_addr_bytes) ;
|
||||||
|
char *mobile_mac_string = mac_bytes_to_string(couple.mobile_mac_addr_bytes) ;
|
||||||
|
printf("\n\
|
||||||
|
*** 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\
|
||||||
|
\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(couple.request_time),
|
||||||
|
timeval_to_ms(couple.start_time),
|
||||||
|
couple.antenna_signal_dbm - 0x100,
|
||||||
|
couple.x_position,
|
||||||
|
couple.y_position,
|
||||||
|
couple.z_position,
|
||||||
|
couple.direction
|
||||||
|
) ;
|
||||||
|
free(ap_mac_string) ;
|
||||||
|
free(mobile_mac_string) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Envoi du couple au serveur d'aggrégation */
|
||||||
|
nsent = sendto(sockfd, (void *) &couple, sizeof(couple), 0, (struct sockaddr *) server, (socklen_t) sizeof(*server)) ;
|
||||||
|
if (nsent != (ssize_t) sizeof(couple))
|
||||||
|
{
|
||||||
|
perror("Erreur lors de l'envoi du couple au serveur ") ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Fonction permettant de récupérer sa propre adresse MAC (interface 'eth') dans le tableau 'mac_bytes' */
|
||||||
|
void get_mac_addr(char *eth, unsigned char mac_bytes[6])
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
int sockfd ;
|
||||||
|
|
||||||
|
bzero(mac_bytes, sizeof(unsigned char) * 6) ; // RàZ
|
||||||
|
|
||||||
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
|
||||||
|
if(sockfd < 0)
|
||||||
|
printf("Can't open socket\n") ;
|
||||||
|
|
||||||
|
strncpy(ifr.ifr_name, eth, IFNAMSIZ) ;
|
||||||
|
|
||||||
|
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
memcpy(mac_bytes, ifr.ifr_hwaddr.sa_data, 6) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Affiche le mode d'emploi du programme */
|
||||||
|
void print_usage(char *prog)
|
||||||
|
{
|
||||||
|
printf("Usage :\n\
|
||||||
|
\t%s rtap_iface wifi_iface\n\
|
||||||
|
- rtap_iface est l'interface de capture radiotap.\n\
|
||||||
|
- wifi_iface est l'interface physique correspondant à rtap_iface.\n\
|
||||||
|
", prog) ;
|
||||||
|
}
|
|
@ -0,0 +1,303 @@
|
||||||
|
/*
|
||||||
|
* This is the rtapanalyser library, Wi-Fi packet sniffer and analyser,
|
||||||
|
* thanks to the radiotap header of each packet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ap.h"
|
||||||
|
|
||||||
|
extern BOOL run ;
|
||||||
|
|
||||||
|
unsigned char *mac ;
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
struct sigaction action ; // Structure de mise en place des gestionnaires de signaux
|
||||||
|
int sockfd ; // Descripteur de la socket vers le serveur d'aggrégation
|
||||||
|
struct sockaddr_in server, client ;
|
||||||
|
sockfd = create_udp_sending_socket("127.0.0.1", AGGREGATE_DEFAULT_PORT, &server, &client);
|
||||||
|
mac = malloc(sizeof(unsigned char) * 6) ; // Adresse MAC de l'AP
|
||||||
|
|
||||||
|
/* 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) ;
|
||||||
|
|
||||||
|
get_mac_addr("eth1", mac) ;
|
||||||
|
printf("ma mac est %s\n", mac_bytes_to_string(mac)) ;
|
||||||
|
|
||||||
|
while (run)
|
||||||
|
{
|
||||||
|
couple_message couple ;
|
||||||
|
memcpy(couple.ap_mac_addr_bytes, mac, 6); // On copie la MAC de l'AP
|
||||||
|
gettimeofday(&couple.start_time, NULL) ;
|
||||||
|
memcpy(&couple.request_time, &couple.mobile_mac_addr_bytes[3], sizeof(struct timeval));
|
||||||
|
couple.request_time.tv_usec = abs(couple.request_time.tv_usec) ;
|
||||||
|
memcpy(&couple.mobile_mac_addr_bytes, &couple.start_time, 6); // Dans le cas du beacon, l'adresse MAC est 10 octets plus loin
|
||||||
|
couple.antenna_signal_dbm = couple.mobile_mac_addr_bytes[0] ;
|
||||||
|
couple.x_position = 4644.647 ;
|
||||||
|
couple.y_position = 43.788 ;
|
||||||
|
couple.z_position = 553.99 ;
|
||||||
|
couple.direction = SOUTH ;
|
||||||
|
|
||||||
|
printf("\ncouple à envoyer :\nAP MAC : %s\nMobile MAC : %s\nRequest time : %ld\nsignal : %u\nX : %f\nY : %f\nZ : %f\nDirection : %hhd\n", mac_bytes_to_string(couple.ap_mac_addr_bytes), mac_bytes_to_string(couple.mobile_mac_addr_bytes), couple.request_time.tv_usec, couple.antenna_signal_dbm, couple.x_position, couple.y_position, couple.z_position, couple.direction) ;
|
||||||
|
|
||||||
|
/* Envoi du couple au serveur d'aggrégation */
|
||||||
|
sendto(sockfd, (void *) &couple, sizeof(couple), 0, (struct sockaddr *) &server, (socklen_t) sizeof(server)) ;
|
||||||
|
|
||||||
|
sleep(1) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//capture("rtap0", TRUE) ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
memcpy(mac, "abcdef", 6) ;
|
||||||
|
printf("%lu\n", get_mobile_sequence(&known_mobiles, mac));
|
||||||
|
printf("%lu\n", get_mobile_sequence(&known_mobiles, mac));
|
||||||
|
memcpy(mac, "azerty", 6) ;
|
||||||
|
printf("%lu\n", get_mobile_sequence(&known_mobiles, mac));
|
||||||
|
memcpy(mac, "ghijkl", 6) ;
|
||||||
|
printf("%lu\n", get_mobile_sequence(&known_mobiles, mac));
|
||||||
|
printf("%lu\n", get_mobile_sequence(&known_mobiles, mac));
|
||||||
|
printf("%lu\n", get_mobile_sequence(&known_mobiles, mac));
|
||||||
|
*/
|
||||||
|
|
||||||
|
printf("apd : fin\n") ;
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Capture des paquets en utilisant l'interface "capture_iface" pendant "capture_time" mili-secondes.
|
||||||
|
Les informations concernant les mobiles effectuant des requêtes sont conservées dans la liste "known_mobiles".
|
||||||
|
Les données capturées sont envoyées au serveur d'aggrégation à travers la socket UDP "socket".
|
||||||
|
*/
|
||||||
|
int capture(char *capture_iface, BOOL print_values)
|
||||||
|
{
|
||||||
|
pcap_t *handle ; // Descripteur de capture de paquets
|
||||||
|
char errbuf[PCAP_ERRBUF_SIZE] ;// Message d'erreur
|
||||||
|
// struct timeval tbegin, tcurrent ;
|
||||||
|
int sockfd ; // Descripteur de la socket vers le serveur d'aggrégation
|
||||||
|
struct sockaddr_in server, client ;
|
||||||
|
|
||||||
|
|
||||||
|
/* Sous-fonction de traitement des paquets capturés */
|
||||||
|
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
|
||||||
|
{
|
||||||
|
read_packet(args, header, packet, sockfd, &server, print_values) ; // On appelle la fonction read_packet() avec les mêmes arguments, plus "print_values" qui indique si on doit afficher le paquet.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handle = pcap_open_live(capture_iface, BUFSIZ, 1, 1000, errbuf) ; // Début de la capture
|
||||||
|
if (handle == NULL) // Le lancement de la capture a-t-il échoué ?
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Impossible d'ouvrir l'interface « %s » : %s\n", capture_iface, errbuf) ;
|
||||||
|
return(ERR_OPENING_IFACE) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
|
||||||
|
sockfd = create_udp_sending_socket("127.0.0.1", AGGREGATE_DEFAULT_PORT, &server, &client);
|
||||||
|
if (sockfd < 0)
|
||||||
|
{
|
||||||
|
perror("Erreur ! Impossible de créer la socket vers le serveur d'aggrégation \n");
|
||||||
|
exit(-1); // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
while(run)
|
||||||
|
{
|
||||||
|
pcap_loop(handle, 1, got_packet, NULL) ; // Collecte 1 paquet et appelle la fonction got_packet quand pcaploop a recupéré des paquets
|
||||||
|
}
|
||||||
|
|
||||||
|
pcap_close(handle) ; // Arrêt de la capture.
|
||||||
|
(void) close(sockfd) ; // Fermeture de la socket
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Traite un paquet et l'envoie au serveur d'agrégation */
|
||||||
|
void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, int sockfd, struct sockaddr_in *server, BOOL print_values)
|
||||||
|
{
|
||||||
|
unsigned char *data = (unsigned char *) packet ; // Recopie dans data l'adresse du paquet capturé
|
||||||
|
unsigned short int rtap_bytes ; // Taille des données reçues
|
||||||
|
unsigned char c ;
|
||||||
|
int i ;
|
||||||
|
unsigned int rtap_presentflags, rtap_position ;
|
||||||
|
couple_message couple ;
|
||||||
|
ssize_t nsent ; // Retour de sendto
|
||||||
|
BOOL check[15] ; // Champs présents
|
||||||
|
char packet_type ;
|
||||||
|
//char offset = 1 ;
|
||||||
|
char direction ; // Direction de la calibration
|
||||||
|
float posX, posY, posZ;
|
||||||
|
FILE *fd ;
|
||||||
|
|
||||||
|
memcpy(&rtap_bytes, &data[2], sizeof(unsigned short int)) ; // Recopie les deux octets à partir du troisième octet de donnée qui est la taille de l'en-tête rtap (change avec des flags)
|
||||||
|
c = 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)
|
||||||
|
if (c == 0x08 // Si le paquet est de type data,
|
||||||
|
&& data[rtap_bytes+24+8+9] == 0x11 // 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),
|
||||||
|
&& data[rtap_bytes+24+8+20+2] == 0x26 && data[rtap_bytes+24+8+20+3] == 0xac) // et le port de destination est 9900 (20 : longueur de l'en-tête IP, le port de destination étant les troisièmes et quatrièmes octet suivant).
|
||||||
|
{
|
||||||
|
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); // Dans le cas du beacon, l'adresse MAC est 10 octets plus loin
|
||||||
|
gettimeofday(&couple.start_time, NULL) ;
|
||||||
|
|
||||||
|
packet_type = data[rtap_bytes+24+8+20+8] ;
|
||||||
|
|
||||||
|
memcpy(&couple.request_time, &data[rtap_bytes+24+8+20+8+1], sizeof(struct timeval));
|
||||||
|
|
||||||
|
|
||||||
|
printf("coin\n");
|
||||||
|
|
||||||
|
if (packet_type == 0)
|
||||||
|
printf("Paquet normal\n") ;
|
||||||
|
else if (packet_type == 1)
|
||||||
|
{
|
||||||
|
printf("Paquet de calibration\n") ;
|
||||||
|
|
||||||
|
direction = data[rtap_bytes+24+8+20+8 + 9];
|
||||||
|
|
||||||
|
memcpy(&posX, &data[rtap_bytes+24+8+20+8+10], sizeof(float));
|
||||||
|
memcpy(&posY, &data[rtap_bytes+24+8+20+8+14], sizeof(float));
|
||||||
|
memcpy(&posZ, &data[rtap_bytes+24+8+20+8+18], sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print_values)
|
||||||
|
printf("[%s]\n", mac_bytes_to_string(couple.mobile_mac_addr_bytes)) ;
|
||||||
|
|
||||||
|
memcpy(&rtap_presentflags, &data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS); // Récupère les flags de l'en-tête rtap
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0 ; i < 15 ; i++)
|
||||||
|
check[i] = FALSE ;
|
||||||
|
rtap_position = 8 ; // début des champs déterminés par le present flag
|
||||||
|
|
||||||
|
for(i=0 ; i < 14 ; i++) // on teste les 15 premiers bits du champ flag afin de valider la présence et de les copier
|
||||||
|
{
|
||||||
|
if((rtap_presentflags % 2) == 1)
|
||||||
|
{
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case RTAP_MACTS:
|
||||||
|
check[RTAP_MACTS] = TRUE ;
|
||||||
|
rtap_position += RTAP_L_MACTS ;
|
||||||
|
break ;
|
||||||
|
case RTAP_FLAGS:
|
||||||
|
// memcpy(&(tmp_ss->flags), &data[rtap_position], RTAP_L_FLAGS) ;
|
||||||
|
check[RTAP_FLAGS] = TRUE;
|
||||||
|
rtap_position += RTAP_L_FLAGS ;
|
||||||
|
break ;
|
||||||
|
case RTAP_RATE:
|
||||||
|
check[RTAP_RATE] = TRUE;
|
||||||
|
rtap_position += RTAP_L_RATE ;
|
||||||
|
break ;
|
||||||
|
case RTAP_CHANNEL:
|
||||||
|
rtap_position += RTAP_L_CHANNEL ;
|
||||||
|
rtap_position += RTAP_L_CHANNELTYPE ;
|
||||||
|
break ;
|
||||||
|
case RTAP_FHSS:
|
||||||
|
check[RTAP_FHSS] = TRUE;
|
||||||
|
rtap_position += RTAP_L_FHSS ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNASIGNALDBM:
|
||||||
|
memcpy(&(couple.antenna_signal_dbm), &data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ;
|
||||||
|
check[RTAP_ANTENNASIGNALDBM] = TRUE;
|
||||||
|
if (print_values)
|
||||||
|
printf("Antenna Signal : %d dBm\n", couple.antenna_signal_dbm - 0x100);
|
||||||
|
rtap_position += RTAP_L_ANTENNASIGNALDBM ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNANOISEDBM:
|
||||||
|
check[RTAP_ANTENNANOISEDBM] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNANOISEDBM ;
|
||||||
|
break ;
|
||||||
|
case RTAP_LOCKQUALITY:
|
||||||
|
check[RTAP_LOCKQUALITY] = TRUE;
|
||||||
|
rtap_position += RTAP_L_LOCKQUALITY ;
|
||||||
|
break ;
|
||||||
|
case RTAP_TXATTENUATION:
|
||||||
|
check[RTAP_TXATTENUATION] = TRUE;
|
||||||
|
rtap_position += RTAP_L_TXATTENUATION ;
|
||||||
|
break ;
|
||||||
|
case RTAP_TXATTENUATIONDB:
|
||||||
|
check[RTAP_TXATTENUATIONDB] = TRUE;
|
||||||
|
rtap_position += RTAP_L_TXATTENUATIONDB ;
|
||||||
|
break ;
|
||||||
|
case RTAP_TXATTENUATIONDBM:
|
||||||
|
check[RTAP_TXATTENUATIONDBM] = TRUE;
|
||||||
|
rtap_position += RTAP_L_TXATTENUATIONDBM ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNA:
|
||||||
|
check[RTAP_ANTENNA] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNA ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNASIGNALDB:
|
||||||
|
check[RTAP_ANTENNASIGNALDB] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNASIGNALDB ;
|
||||||
|
break ;
|
||||||
|
case RTAP_ANTENNANOISEDB:
|
||||||
|
check[RTAP_ANTENNANOISEDB] = TRUE;
|
||||||
|
rtap_position += RTAP_L_ANTENNANOISEDB ;
|
||||||
|
break ;
|
||||||
|
case RTAP_FCS:
|
||||||
|
check[RTAP_FCS] = TRUE;
|
||||||
|
rtap_position += RTAP_L_FCS ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rtap_presentflags /= 2 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (packet_type == 1)
|
||||||
|
{
|
||||||
|
// coord direction mac_ap puissance
|
||||||
|
printf("hey\n") ;
|
||||||
|
fd = fopen("./calibration.out", "a") ;
|
||||||
|
fprintf(fd, "%f, %f, %f, %d, %s, %d\n", posX, posY, posZ, direction, mac_bytes_to_string(mac), couple.antenna_signal_dbm - 0x100) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print_values)
|
||||||
|
printf("\n") ;
|
||||||
|
|
||||||
|
printf("couple à envoyer :\nAP MAC : %s\nMobile MAC : %s\nRequest time : %ld\n", mac_bytes_to_string(couple.ap_mac_addr_bytes), mac_bytes_to_string(couple.mobile_mac_addr_bytes), couple.request_time.tv_usec) ;
|
||||||
|
|
||||||
|
/* Envoi du couple au serveur d'aggrégation */
|
||||||
|
nsent = sendto(sockfd, (void *) &couple, sizeof(couple), 0, (struct sockaddr *) server, (socklen_t) sizeof(*server)) ;
|
||||||
|
if (nsent != (ssize_t) sizeof(couple))
|
||||||
|
{
|
||||||
|
perror("Erreur lors de l'envoi du couple au serveur ") ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Fonction permettant de récupérer sa propre adresse MAC (interface 'eth') dans le tableau 'mac_bytes' */
|
||||||
|
void get_mac_addr(char *eth, unsigned char mac_bytes[6])
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
int sockfd ;
|
||||||
|
|
||||||
|
bzero(mac_bytes, sizeof(unsigned char) * 6) ; // RàZ
|
||||||
|
|
||||||
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
|
||||||
|
if(sockfd < 0)
|
||||||
|
printf("Can't open socket\n") ;
|
||||||
|
|
||||||
|
strncpy(ifr.ifr_name, eth, IFNAMSIZ) ;
|
||||||
|
|
||||||
|
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
memcpy(mac_bytes, ifr.ifr_hwaddr.sa_data, 6) ;
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
# Répertoire d'installation
|
||||||
|
PREFIX=/usr/local
|
||||||
|
INSTALL_DIR= $(PREFIX)/bin
|
||||||
|
INSTALL_LIB= $(PREFIX)/lib
|
||||||
|
INSTALL_INC= $(PREFIX)/include
|
||||||
|
INSTALL_MAN= $(PREFIX)/share/man
|
||||||
|
|
||||||
|
# Compilateur
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
# Commandes d'installation et de désinstallation
|
||||||
|
RM=rm -fv
|
||||||
|
CP=cp -v
|
||||||
|
|
||||||
|
# Cible
|
||||||
|
TARGET=locclient
|
||||||
|
HEADER=
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
|
||||||
|
DEPFLAGS=-MMD
|
||||||
|
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
|
||||||
|
PICFLAG=-fPIC
|
||||||
|
LIBS=../librtaputil/librtaputil.so.1.0
|
||||||
|
|
||||||
|
|
||||||
|
## Cibles de compilation standard ##
|
||||||
|
|
||||||
|
.PHONY : all install uninstall clean purge help
|
||||||
|
|
||||||
|
all : $(TARGET)
|
||||||
|
|
||||||
|
% : %.o
|
||||||
|
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
%.o : %.c $(HEADER)
|
||||||
|
$(CC) $(XCFLAGS) -c $<
|
||||||
|
|
||||||
|
# Compilation du programme
|
||||||
|
$(TARGET) : $(TARGET).o $(HEADER)
|
||||||
|
|
||||||
|
|
||||||
|
## Installation / désinstallation ##
|
||||||
|
|
||||||
|
install : $(TARGET)
|
||||||
|
@$(CP) $(TARGET) $(INSTALL_DIR)
|
||||||
|
@cd $(INSTALL_DIR) ; chown root:root $(TARGET) ; chmod 755 $(TARGET)
|
||||||
|
|
||||||
|
uninstall :
|
||||||
|
@$(RM) $(INSTALL_DIR)/$(TARGET)
|
||||||
|
|
||||||
|
|
||||||
|
## Nettoyage ##
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@$(RM) -fv *~ *.o *.d
|
||||||
|
|
||||||
|
purge : clean
|
||||||
|
@$(RM) -fv $(TARGET)
|
||||||
|
|
||||||
|
|
||||||
|
## Aide ##
|
||||||
|
|
||||||
|
help :
|
||||||
|
@echo "Bibliothèques nécessaires à la compilation :\n\
|
||||||
|
librtaputil1.0 (fournie)\n\
|
||||||
|
\n\
|
||||||
|
Cibles possibles :\n\
|
||||||
|
$(TARGET) (cible par défaut) : Compile le programme $(TARGET).\n\
|
||||||
|
install : Installe le programme $(TARGET).\n\
|
||||||
|
uninstall : Désinstalle le programme $(TARGET).\n\
|
||||||
|
clean : Supprime les fichiers temporaires.\n\
|
||||||
|
purge : Supprime le résultat de la compilation.\n\
|
||||||
|
\n\
|
||||||
|
Note : l'installation se fait dans l'arborescence $(PREFIX). Modifiez la variable PREFIX du Makefile pour changer ce comportement."
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the rtap localisation project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "../librtaputil/rtaputil.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Codes d'erreurs */
|
||||||
|
#define ERR_CREATING_SOCKET 1
|
||||||
|
#define ERR_BAD_NUMBER_OF_ARGS 2
|
||||||
|
#define ERR_SENDING_INFO 3
|
||||||
|
|
||||||
|
|
||||||
|
/* Affiche le mode d'emploi du programme */
|
||||||
|
void print_usage(char *prog)
|
||||||
|
{
|
||||||
|
printf("Usage :\n\
|
||||||
|
\t- Demande de localisation : %s ip_serveur\n\
|
||||||
|
\t- Requête de calibration : %s ip_serveur direction x y z\n\
|
||||||
|
", prog, prog) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct timeval request_time ;
|
||||||
|
char *buf = NULL ;
|
||||||
|
int buf_offset ;
|
||||||
|
ssize_t nsent ; // Retour de sendto
|
||||||
|
struct sockaddr_in server, client ;
|
||||||
|
int sockfd ;
|
||||||
|
int buf_size ;
|
||||||
|
int i ;
|
||||||
|
|
||||||
|
gettimeofday(&request_time, NULL) ;
|
||||||
|
|
||||||
|
if(argc == 2) // Paquet normal
|
||||||
|
{
|
||||||
|
printf("Envoi normal effectué à : %lu\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
|
||||||
|
memcpy(&buf[1], &request_time, sizeof(request_time)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(argc == 6) // Paquet calibration
|
||||||
|
{
|
||||||
|
printf("Envoi Calibration effectué à : %lu\n", timeval_to_ms(request_time)) ;
|
||||||
|
|
||||||
|
buf_offset = 0 ;
|
||||||
|
buf_size = sizeof(char) * 2 + sizeof(struct timeval) + sizeof(float) * 3 ;
|
||||||
|
buf = malloc(buf_size) ;
|
||||||
|
|
||||||
|
buf[buf_offset++] = PACKET_TYPE_CALIBRATION ; // Type de paquet = calibration
|
||||||
|
memcpy(&buf[buf_offset], &request_time, sizeof(request_time)) ;
|
||||||
|
buf_offset += sizeof(request_time) ;
|
||||||
|
buf[buf_offset++] = atoi(argv[2]) ; // Direction
|
||||||
|
float posX = atof(argv[3]) ;
|
||||||
|
float posY = atof(argv[4]) ;
|
||||||
|
float posZ = atof(argv[5]) ;
|
||||||
|
memcpy(&buf[buf_offset], &posX, sizeof(float)) ;
|
||||||
|
buf_offset += sizeof(float) ;
|
||||||
|
memcpy(&buf[buf_offset], &posY, sizeof(float)) ;
|
||||||
|
buf_offset += sizeof(float) ;
|
||||||
|
memcpy(&buf[buf_offset], &posZ, sizeof(float)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_usage(argv[0]) ;
|
||||||
|
return ERR_BAD_NUMBER_OF_ARGS ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
|
||||||
|
sockfd = create_udp_sending_socket(argv[1], AGGREGATE_DEFAULT_PORT, &server, &client) ;
|
||||||
|
if (sockfd < 0)
|
||||||
|
{
|
||||||
|
perror("Erreur ! Impossible de créer la socket vers le serveur d'aggrégation \n");
|
||||||
|
return ERR_CREATING_SOCKET ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Envoi des infos au serveur d'aggrégation */
|
||||||
|
nsent = sendto(sockfd, (void *) buf, buf_size, 0, (struct sockaddr *) &server, (socklen_t) sizeof(server)) ;
|
||||||
|
if (nsent != (ssize_t) buf_size)
|
||||||
|
{
|
||||||
|
perror("Erreur lors de l'envoi des infos au serveur ") ;
|
||||||
|
return ERR_SENDING_INFO ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 6)
|
||||||
|
for (i = 0 ; i < 19 ; i++)
|
||||||
|
{
|
||||||
|
nsent = sendto(sockfd, (void *) buf, buf_size, 0, (struct sockaddr *) &server, (socklen_t) sizeof(server)) ;
|
||||||
|
if (nsent != (ssize_t) buf_size)
|
||||||
|
{
|
||||||
|
perror("Erreur lors de l'envoi des infos au serveur ") ;
|
||||||
|
return ERR_SENDING_INFO ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) close(sockfd) ;
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
# Répertoire d'installation
|
||||||
|
PREFIX=/usr/local
|
||||||
|
INSTALL_DIR= $(PREFIX)/sbin
|
||||||
|
INSTALL_LIB= $(PREFIX)/lib
|
||||||
|
INSTALL_INC= $(PREFIX)/include
|
||||||
|
INSTALL_MAN= $(PREFIX)/share/man
|
||||||
|
|
||||||
|
# Compilateur
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
# Autres outils
|
||||||
|
AR = ar
|
||||||
|
RANLIB = ranlib
|
||||||
|
|
||||||
|
# Commandes d'installation et de désinstallation
|
||||||
|
RM=rm -fv
|
||||||
|
CP=cp -v
|
||||||
|
|
||||||
|
# Variables générales
|
||||||
|
LIB_CIBLE=librtaputil
|
||||||
|
VERSION=1.0
|
||||||
|
|
||||||
|
# Cibles à construire
|
||||||
|
STATIC=$(LIB_CIBLE).a
|
||||||
|
DYNAMIC=$(LIB_CIBLE).so.$(VERSION)
|
||||||
|
#PROGS=
|
||||||
|
HEADER=rtaputil.h
|
||||||
|
#HEADERS=
|
||||||
|
|
||||||
|
# Composition de la bibliothèque
|
||||||
|
OBJS=$(LIB_CIBLE).o
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
|
||||||
|
DEPFLAGS=-MMD
|
||||||
|
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
|
||||||
|
PICFLAG=-fPIC
|
||||||
|
LIBS=
|
||||||
|
#STRIPFLAGS= -Wl,-s
|
||||||
|
|
||||||
|
|
||||||
|
## Cibles de compilation standard ##
|
||||||
|
|
||||||
|
.PHONY : all dynamic static install install-dynamic install-static install-header uninstall uninstall-dynamic uninstall-static uninstall-header clean purge help
|
||||||
|
|
||||||
|
all : dynamic static
|
||||||
|
dynamic : $(DYNAMIC)
|
||||||
|
static : $(STATIC)
|
||||||
|
|
||||||
|
% : %.o
|
||||||
|
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^
|
||||||
|
%.o : %.c $(HEADER)
|
||||||
|
$(CC) $(XCFLAGS) -c $<
|
||||||
|
%.so : %.c $(HEADER)
|
||||||
|
$(CC) $(XCFLAGS) $(PICFLAG) -c -o $@ $<
|
||||||
|
|
||||||
|
# Compilation de la bibliothèque dynamique
|
||||||
|
$(DYNAMIC) : $(OBJS:.o=.so)
|
||||||
|
$(CC) -shared -o $@ -Wl,-soname,$@ $(STRIPFLAGS) $(LIBS) -lc $^
|
||||||
|
|
||||||
|
# Compilation de la bibliothèque statique
|
||||||
|
$(STATIC) : $(OBJS:.o=.so)
|
||||||
|
$(RM) $@
|
||||||
|
$(AR) cru $@ $^
|
||||||
|
$(RANLIB) $@
|
||||||
|
|
||||||
|
|
||||||
|
## Installation ##
|
||||||
|
|
||||||
|
install : install-static install-dynamic
|
||||||
|
|
||||||
|
install-dynamic : install-header $(DYNAMIC)
|
||||||
|
@$(CP) $(DYNAMIC) $(INSTALL_LIB) &&\
|
||||||
|
chmod 644 $(INSTALL_LIB)/$(DYNAMIC) &&\
|
||||||
|
chown root:root $(INSTALL_LIB)/$(DYNAMIC) &&\
|
||||||
|
echo -e "\n!!! Installation de la bibliothèque dynamique effectuée avec succès.\n!!! Ajoutez une ligne « $(INSTALL_LIB) » dans le fichier /etc/ld.so.conf\n ou dans un nouveau fichier de /etc/ld.so.conf.d/, si ce n'est déjà fait.\n!!! Exécutez ldconfig ensuite.\n"
|
||||||
|
|
||||||
|
install-static : install-header $(STATIC)
|
||||||
|
@$(CP) $(STATIC) $(INSTALL_LIB) &&\
|
||||||
|
chmod 644 $(INSTALL_LIB)/$(STATIC) &&\
|
||||||
|
chown root:root $(INSTALL_LIB)/$(STATIC)
|
||||||
|
|
||||||
|
install-header : $(HEADER)
|
||||||
|
@$(CP) $(HEADER) $(INSTALL_INC) &&\
|
||||||
|
chmod 644 $(INSTALL_INC)/$(HEADER) &&\
|
||||||
|
chown root:root $(INSTALL_INC)/$(HEADER)
|
||||||
|
|
||||||
|
|
||||||
|
## Désinstallation ##
|
||||||
|
|
||||||
|
uninstall : uninstall-dynamic uninstall-static
|
||||||
|
|
||||||
|
uninstall-dynamic : uninstall-header
|
||||||
|
@$(RM) $(INSTALL_LIB)/$(DYNAMIC)
|
||||||
|
ldconfig
|
||||||
|
|
||||||
|
uninstall-static : uninstall-header
|
||||||
|
@$(RM) $(INSTALL_LIB)/$(STATIC)
|
||||||
|
|
||||||
|
uninstall-header :
|
||||||
|
@$(RM) $(INSTALL_INC)/$(HEADER)
|
||||||
|
|
||||||
|
|
||||||
|
## Nettoyage ##
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@$(RM) *~ *.o $(LIB_CIBLE).so *.d
|
||||||
|
|
||||||
|
purge : clean
|
||||||
|
@$(RM) $(DYNAMIC) $(STATIC) $(PROGS)
|
||||||
|
|
||||||
|
|
||||||
|
## Aide ##
|
||||||
|
|
||||||
|
help :
|
||||||
|
@echo "Aucune bibliothèques nécessaires à la compilation.\n\
|
||||||
|
\n\
|
||||||
|
Cibles possibles :\n\
|
||||||
|
all (cible par défaut) : Compile la bibliothèque et le programme d'exemple (tx).\n\
|
||||||
|
dynamic : Compile la bibilothèque partagée (.so).\n\
|
||||||
|
static : Compile la bibliothèque statique (.a).\n\
|
||||||
|
tx : Compile le programme d'exemple.\n\
|
||||||
|
\n\
|
||||||
|
install : Installe la bibliothèque partagée, statique, ainsi que le programme d'exemple.\n\
|
||||||
|
install-dynamic : N'installe que la bibliothèque partagée.\n\
|
||||||
|
install-static : N'installe que la bibliothèque statique.\n\
|
||||||
|
install-tx : N'installe que le programme d'exemple.\n\
|
||||||
|
\n\
|
||||||
|
uninstall : Désinstalle tout ce qu'il est possible de désinstaller.\n\
|
||||||
|
uninstall-dynamic : Désinstalle la bibliothèque partagée.\n\
|
||||||
|
uninstall-static : Désinstalle la bibliothèque statique.\n\
|
||||||
|
uninstall-tx : Désinstalle le programme d'exemple.\n\
|
||||||
|
\n\
|
||||||
|
clean : Supprime les fichiers temporaires.\n\
|
||||||
|
purge : Supprime le résultat de la compilation.\n\
|
||||||
|
\n\
|
||||||
|
Note : l'installation se fait dans l'arborescence $(PREFIX). Modifiez la variable PREFIX du Makefile pour changer ce comportement."
|
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the rtap localisation project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "rtaputil.h"
|
||||||
|
|
||||||
|
|
||||||
|
BOOL run = TRUE ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Convertit une adresse MAC en octets en une chaîne de caractères.
|
||||||
|
* ¡ Il est nécessaire de libérer manuellement le retour de cette fonction !
|
||||||
|
*/
|
||||||
|
char* mac_bytes_to_string(unsigned char *mac_binary)
|
||||||
|
{
|
||||||
|
char *ret = malloc(sizeof(char) * 18) ;
|
||||||
|
|
||||||
|
sprintf(ret, "%02x:%02x:%02x:%02x:%02x:%02x", mac_binary[0], mac_binary[1], mac_binary[2], mac_binary[3], mac_binary[4], mac_binary[5]) ;
|
||||||
|
ret[17] = '\0' ;
|
||||||
|
|
||||||
|
return ret ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Convertit un identifiant de canal en son numéro (0 si la fréquence est erronée) */
|
||||||
|
char frequency_to_channel(unsigned short channel)
|
||||||
|
{
|
||||||
|
char c = 0 ; // Résultat
|
||||||
|
|
||||||
|
switch (channel)
|
||||||
|
{
|
||||||
|
case 2412 :
|
||||||
|
c = 1 ;
|
||||||
|
break ;
|
||||||
|
case 2417 :
|
||||||
|
c = 2 ;
|
||||||
|
break ;
|
||||||
|
case 2422 :
|
||||||
|
c = 3 ;
|
||||||
|
break ;
|
||||||
|
case 2427 :
|
||||||
|
c = 4 ;
|
||||||
|
break ;
|
||||||
|
case 2432 :
|
||||||
|
c = 5 ;
|
||||||
|
break ;
|
||||||
|
case 2437 :
|
||||||
|
c = 6 ;
|
||||||
|
break ;
|
||||||
|
case 2442 :
|
||||||
|
c = 7 ;
|
||||||
|
break ;
|
||||||
|
case 2447 :
|
||||||
|
c = 8 ;
|
||||||
|
break ;
|
||||||
|
case 2452 :
|
||||||
|
c = 9 ;
|
||||||
|
break ;
|
||||||
|
case 2457 :
|
||||||
|
c = 10 ;
|
||||||
|
break ;
|
||||||
|
case 2462 :
|
||||||
|
c = 11 ;
|
||||||
|
break ;
|
||||||
|
case 2467 :
|
||||||
|
c = 12 ;
|
||||||
|
break ;
|
||||||
|
case 2472 :
|
||||||
|
c = 13 ;
|
||||||
|
break ;
|
||||||
|
case 2477 :
|
||||||
|
c = 14 ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Retourne une date au format struct timeval en mili-secondes */
|
||||||
|
unsigned long timeval_to_ms(struct timeval d)
|
||||||
|
{
|
||||||
|
return d.tv_sec * 1000 + d.tv_usec / 1000 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Retourne le temps (en mili-secondes) é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) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Compare deux adresses MAC : retourne TRUE si elles sont égales, FALSE sinon */
|
||||||
|
BOOL mac_cmp(unsigned char *mac1, unsigned char *mac2)
|
||||||
|
{
|
||||||
|
int i ;
|
||||||
|
for(i=0 ; i < 6 ; i++)
|
||||||
|
if(mac1[i] != mac2[i])
|
||||||
|
return FALSE ;
|
||||||
|
return TRUE ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Crée une socket d'envoi UDP et retourne son descripteur.
|
||||||
|
* Paramètres :
|
||||||
|
* - server_address : l'adresse IP du serveur.
|
||||||
|
* - server_port : le port d'écoute du serveur.
|
||||||
|
* - server_description (paramètre résultat) : la structure dans laquelle sera enregistrée la description du serveur.
|
||||||
|
* - client_description (paramètre résultat) : la structure dans laquelle sera enregistrée la description du client.
|
||||||
|
*/
|
||||||
|
int create_udp_sending_socket(char *server_address, int server_port, struct sockaddr_in *server_description, struct sockaddr_in * client_description)
|
||||||
|
{
|
||||||
|
int sockfd ; // Descripteur de la socket
|
||||||
|
int ret = 0 ; // Valeur de retour
|
||||||
|
|
||||||
|
/* Ceation de la socket UDP */
|
||||||
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
|
||||||
|
if (sockfd < 0)
|
||||||
|
{
|
||||||
|
perror("Échec de la création de la socket ") ;
|
||||||
|
return(sockfd) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remise à zéro et initialisation de la structure du client */
|
||||||
|
bzero((char *) client_description, sizeof(*client_description)) ;
|
||||||
|
client_description->sin_family = AF_INET ; // Socket INET
|
||||||
|
client_description->sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions
|
||||||
|
client_description->sin_port = htons(0) ; // N'importe quel port
|
||||||
|
|
||||||
|
/* Réservation d'un port quelconque pour le client */
|
||||||
|
ret = bind(sockfd, (struct sockaddr *) client_description, sizeof(*client_description)) ;
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
perror("Impossible de créer la socket (bind) ") ;
|
||||||
|
(void) close (sockfd) ;
|
||||||
|
return ret ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remise à zéro et initialisation de la structure du serveur */
|
||||||
|
bzero((char *) server_description, sizeof(*server_description)) ; // RÀZ
|
||||||
|
server_description->sin_family = AF_INET ; // Socket INET
|
||||||
|
server_description->sin_addr.s_addr = inet_addr(server_address) ; // Adresse du serveur
|
||||||
|
server_description->sin_port = htons(server_port) ; // Port d'écoute du serveur
|
||||||
|
|
||||||
|
return (sockfd) ; // On retourne le descripteur de la socket créée
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Crée une socket d'écoute UDP et retourne son descripteur.
|
||||||
|
* Paramètres :
|
||||||
|
* - port est le port sur lequel écouter.
|
||||||
|
*/
|
||||||
|
int create_udp_listening_socket(int port)
|
||||||
|
{
|
||||||
|
int sockfd ; // Descripteur de la socket
|
||||||
|
struct sockaddr_in server_description ; // Structure du serveur
|
||||||
|
int ret = 0 ; // Valeur de retour
|
||||||
|
|
||||||
|
/* Création d'une socket UDP */
|
||||||
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
|
||||||
|
if (sockfd < 0)
|
||||||
|
{
|
||||||
|
perror("Échec de la création de la socket ") ;
|
||||||
|
return(sockfd) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remise à zéro et initialisation de la structure du serveur */
|
||||||
|
bzero((char *) &server_description, sizeof(server_description)) ; // RÀZ
|
||||||
|
server_description.sin_family = AF_INET ; // Socket INET
|
||||||
|
server_description.sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions sont acceptées
|
||||||
|
server_description.sin_port = htons(port) ; // Port d'écoute
|
||||||
|
|
||||||
|
/* Réservation du port */
|
||||||
|
ret = bind(sockfd, (struct sockaddr*) &server_description, sizeof(server_description)) ;
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
perror("Impossible de créer la socket (bind) ") ;
|
||||||
|
(void) close(sockfd) ;
|
||||||
|
return ret ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sockfd ; // On retourne le descripteur de la socket créée
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void sigint_handler(int num)
|
||||||
|
{
|
||||||
|
if (num != SIGINT)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Erreur ! Gestionnaire de SIGINT appelé mais le signal n'est pas SIGINT.\n") ;
|
||||||
|
exit(1) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
run = FALSE ;
|
||||||
|
|
||||||
|
printf("\nSignal reçu : fin du programme.\n");
|
||||||
|
fflush(NULL) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void sigterm_handler(int num)
|
||||||
|
{
|
||||||
|
if (num != SIGTERM)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Erreur ! Gestionnaire de SIGTERM appelé mais le signal n'est pas SIGINT.\n") ;
|
||||||
|
exit(1) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigint_handler(SIGINT) ;
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the rtap localisation project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AGGREGATE_DEFAULT_PORT 9900 // Port d'échange des données
|
||||||
|
|
||||||
|
|
||||||
|
/* Type booléen */
|
||||||
|
typedef enum {FALSE, TRUE} BOOL ;
|
||||||
|
|
||||||
|
|
||||||
|
/* Type direction */
|
||||||
|
typedef enum {NORTH = 1, EAST, SOUTH, WEST} DIRECTION ;
|
||||||
|
|
||||||
|
|
||||||
|
/* Message envoyé par l'AP à l'agrégateur */
|
||||||
|
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
|
||||||
|
unsigned char antenna_signal_dbm ; // Puissance du signal reçu par l'AP du mobile
|
||||||
|
/* Données pour la calibration */
|
||||||
|
float x_position ;
|
||||||
|
float y_position ;
|
||||||
|
float z_position ;
|
||||||
|
DIRECTION direction ; // Orientation de la demande de localisation
|
||||||
|
} couple_message ;
|
||||||
|
|
||||||
|
|
||||||
|
/* Types de paquets */
|
||||||
|
#define PACKET_TYPE_NORMAL 0
|
||||||
|
#define PACKET_TYPE_CALIBRATION 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Position des champs fixes de l'en-tête rtap (octets) */
|
||||||
|
#define RTAP_P_HREVISION 0 // Header revision
|
||||||
|
#define RTAP_P_HPAD 1 // Header pad
|
||||||
|
#define RTAP_P_HLENGTH 2 // Header length
|
||||||
|
#define RTAP_P_PRESENTFLAGS 4 // Present flags
|
||||||
|
|
||||||
|
|
||||||
|
/* Longueur des champs de l'en-tête rtap (octets) */
|
||||||
|
#define RTAP_L_HREVISION 1 // Header revision
|
||||||
|
#define RTAP_L_HPAD 1 // Header pad
|
||||||
|
#define RTAP_L_HLENGTH 2 // Header length
|
||||||
|
#define RTAP_L_PRESENTFLAGS 4 // Present flags
|
||||||
|
#define RTAP_L_MACTS 8 // MAC timestamp
|
||||||
|
#define RTAP_L_FLAGS 1 // autre champ de flags
|
||||||
|
#define RTAP_L_RATE 1 // Data rate
|
||||||
|
#define RTAP_L_CHANNEL 2 // Channel
|
||||||
|
#define RTAP_L_CHANNELTYPE 2 // Channel type
|
||||||
|
#define RTAP_L_ANTENNASIGNALDBM 1 // SSI signal dBm
|
||||||
|
#define RTAP_L_ANTENNANOISEDBM 1 // SSI noise dBm
|
||||||
|
#define RTAP_L_ANTENNA 1 // Antenna
|
||||||
|
#define RTAP_L_FHSS 2
|
||||||
|
#define RTAP_L_LOCKQUALITY 2
|
||||||
|
#define RTAP_L_TXATTENUATION 2
|
||||||
|
#define RTAP_L_TXATTENUATIONDB 2
|
||||||
|
#define RTAP_L_TXATTENUATIONDBM 1
|
||||||
|
#define RTAP_L_ANTENNASIGNALDB 1 // en dB
|
||||||
|
#define RTAP_L_ANTENNANOISEDB 1 // en dB
|
||||||
|
#define RTAP_L_FCS 4
|
||||||
|
#define RTAP_L_EXT // Non implémenté
|
||||||
|
|
||||||
|
|
||||||
|
/* Positions pour affichage (tableau check de ss_list) */
|
||||||
|
#define RTAP_MACTS 0
|
||||||
|
#define RTAP_FLAGS 1
|
||||||
|
#define RTAP_RATE 2
|
||||||
|
#define RTAP_CHANNEL 3 // ainsi que RTAP_CHANNELTYPE
|
||||||
|
#define RTAP_FHSS 4
|
||||||
|
#define RTAP_ANTENNASIGNALDBM 5
|
||||||
|
#define RTAP_ANTENNANOISEDBM 6
|
||||||
|
#define RTAP_LOCKQUALITY 7
|
||||||
|
#define RTAP_TXATTENUATION 8
|
||||||
|
#define RTAP_TXATTENUATIONDB 9
|
||||||
|
#define RTAP_TXATTENUATIONDBM 10
|
||||||
|
#define RTAP_ANTENNA 11
|
||||||
|
#define RTAP_ANTENNASIGNALDB 12
|
||||||
|
#define RTAP_ANTENNANOISEDB 13
|
||||||
|
#define RTAP_FCS 14
|
||||||
|
|
||||||
|
|
||||||
|
/* Variables globales */
|
||||||
|
BOOL run ;
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 sub_date(struct timeval sup, struct timeval inf) ;
|
||||||
|
BOOL mac_cmp(unsigned char *mac1, unsigned char *mac2) ;
|
||||||
|
|
||||||
|
// Signaux
|
||||||
|
void sigint_handler(int num) ;
|
||||||
|
void sigterm_handler(int num) ;
|
||||||
|
|
||||||
|
// Réseau
|
||||||
|
int create_udp_listening_socket(int port) ;
|
||||||
|
int create_udp_sending_socket(char *server_address, int server_port, struct sockaddr_in *server_description, struct sockaddr_in * client_description) ;
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
rmmod ipw2200
|
||||||
|
modprobe ipw2200 rtap_iface=1
|
||||||
|
ifconfig rtap0 up
|
|
@ -0,0 +1,74 @@
|
||||||
|
# Répertoire d'installation
|
||||||
|
PREFIX=/usr/local
|
||||||
|
INSTALL_DIR= $(PREFIX)/bin
|
||||||
|
INSTALL_LIB= $(PREFIX)/lib
|
||||||
|
INSTALL_INC= $(PREFIX)/include
|
||||||
|
INSTALL_MAN= $(PREFIX)/share/man
|
||||||
|
|
||||||
|
# Compilateur
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
# Commandes d'installation et de désinstallation
|
||||||
|
RM=rm -fv
|
||||||
|
CP=cp -v
|
||||||
|
|
||||||
|
# Cible
|
||||||
|
TARGET=rtapaggregated
|
||||||
|
HEADER=rtapaggregate.h
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
|
||||||
|
DEPFLAGS=-MMD
|
||||||
|
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
|
||||||
|
PICFLAG=-fPIC
|
||||||
|
LIBS=-lpthread ../librtaputil/librtaputil.so.1.0
|
||||||
|
|
||||||
|
|
||||||
|
## Cibles de compilation standard ##
|
||||||
|
|
||||||
|
.PHONY : all install uninstall clean purge help
|
||||||
|
|
||||||
|
all : $(TARGET)
|
||||||
|
|
||||||
|
% : %.o
|
||||||
|
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
%.o : %.c $(HEADER)
|
||||||
|
$(CC) $(XCFLAGS) -c $<
|
||||||
|
|
||||||
|
# Compilation du programme
|
||||||
|
$(TARGET) : $(TARGET).o $(HEADER)
|
||||||
|
|
||||||
|
|
||||||
|
## Installation / désinstallation ##
|
||||||
|
|
||||||
|
install : $(TARGET)
|
||||||
|
@$(CP) $(TARGET) $(INSTALL_DIR)
|
||||||
|
@cd $(INSTALL_DIR) ; chown root:root $(TARGET) ; chmod 755 $(TARGET)
|
||||||
|
|
||||||
|
uninstall :
|
||||||
|
@$(RM) $(INSTALL_DIR)/$(TARGET)
|
||||||
|
|
||||||
|
|
||||||
|
## Nettoyage ##
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@$(RM) -fv *~ *.o *.d
|
||||||
|
|
||||||
|
purge : clean
|
||||||
|
@$(RM) -fv $(TARGET)
|
||||||
|
|
||||||
|
|
||||||
|
## Aide ##
|
||||||
|
|
||||||
|
help :
|
||||||
|
@echo "Bibliothèques nécessaires à la compilation :\n\
|
||||||
|
librtaputil1.0 (fournie)\n\
|
||||||
|
\n\
|
||||||
|
Cibles possibles :\n\
|
||||||
|
$(TARGET) (cible par défaut) : Compile le programme $(TARGET).\n\
|
||||||
|
install : Installe le programme $(TARGET).\n\
|
||||||
|
uninstall : Désinstalle le programme $(TARGET).\n\
|
||||||
|
clean : Supprime les fichiers temporaires.\n\
|
||||||
|
purge : Supprime le résultat de la compilation.\n\
|
||||||
|
\n\
|
||||||
|
Note : l'installation se fait dans l'arborescence $(PREFIX). Modifiez la variable PREFIX du Makefile pour changer ce comportement."
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the rtap localisation project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "../librtaputil/rtaputil.h"
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <pthread.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 CHECK_INTERVAL 500000 // Temps entre deux vérifications de la liste (en micro-secondes)
|
||||||
|
|
||||||
|
/* Codes d'erreur */
|
||||||
|
#define ERR_NO_MESSAGE_RECEIVED 1 // Erreur lors de la lecture sur la socket
|
||||||
|
#define ERR_CREATING_SOCKET 2 // Erreur lors de la création de la socket d'écoute
|
||||||
|
#define ERR_BAD_USAGE 3 // Mauvais appel au programme
|
||||||
|
|
||||||
|
|
||||||
|
/* Liste chaînée des informations concernant un couple MAC / séquence */
|
||||||
|
typedef struct _couple_info_list
|
||||||
|
{
|
||||||
|
unsigned char ap_mac_addr_bytes[6] ; // Adresse MAC de l'AP émetteur de l'info en octets
|
||||||
|
unsigned char antenna_signal_dbm ; // Puissance du signal reçu par l'AP du mobile
|
||||||
|
struct _couple_info_list *next ;
|
||||||
|
} couple_info_list ;
|
||||||
|
|
||||||
|
|
||||||
|
/* Liste chaînée des couples MAC / séquence */
|
||||||
|
typedef struct _couple_list
|
||||||
|
{
|
||||||
|
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 ;
|
||||||
|
/* Données pour la calibration */
|
||||||
|
float x_position ;
|
||||||
|
float y_position ;
|
||||||
|
float z_position ;
|
||||||
|
DIRECTION direction ; // Orientation de la demande de localisation
|
||||||
|
} couple_list ;
|
||||||
|
|
||||||
|
|
||||||
|
/* En-têtes de fonctions */
|
||||||
|
void got_couple_info(couple_list **couples, couple_message message) ;
|
||||||
|
void free_couple_list(couple_list **couples) ;
|
||||||
|
void print_couple_list(couple_list *couples) ;
|
||||||
|
void print_couple_info(couple_info_list *info) ;
|
||||||
|
void* monitor_couple_list(couple_list **couples) ;
|
||||||
|
void print_usage(char *prog) ;
|
|
@ -0,0 +1,359 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the rtap localisation project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "rtapaggregate.h"
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
print_usage(argv[0]) ;
|
||||||
|
return ERR_BAD_USAGE ;
|
||||||
|
}
|
||||||
|
|
||||||
|
run = TRUE ;
|
||||||
|
|
||||||
|
|
||||||
|
/* Fichier de sortie */
|
||||||
|
out_file = malloc((strlen(argv[1]) + 1) * sizeof(char)) ;
|
||||||
|
strcpy(out_file, argv[1]) ;
|
||||||
|
|
||||||
|
|
||||||
|
/* 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\
|
||||||
|
\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\
|
||||||
|
\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 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 ;
|
||||||
|
|
||||||
|
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(¤t_time, NULL) ;
|
||||||
|
|
||||||
|
while (couple_ptr != NULL) // Parcours de la liste
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
{
|
||||||
|
printf("* Timeout dépassé.\n") ;
|
||||||
|
fprintf(fd, "%f;%f;%f;%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 ;
|
||||||
|
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") ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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é
|
||||||
|
{
|
||||||
|
couple_list *couple_tmp = couple_ptr ;
|
||||||
|
|
||||||
|
printf("* Délai de garde dépassé.\n") ;
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fd) ;
|
||||||
|
|
||||||
|
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 ;
|
||||||
|
|
||||||
|
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 ;
|
||||||
|
|
||||||
|
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 ;
|
||||||
|
tmp_couple->start_time = message.start_time ;
|
||||||
|
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 ;
|
||||||
|
tmp_couple->start_time = message.start_time ;
|
||||||
|
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\
|
||||||
|
Numéro de séquence : %lu\n\
|
||||||
|
Heure de réception de la demande de localisation : %lu\n\
|
||||||
|
\n",
|
||||||
|
mobile_mac_string,
|
||||||
|
couple_ptr->request_time.tv_usec,
|
||||||
|
couple_ptr->start_time.tv_usec
|
||||||
|
) ;
|
||||||
|
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("\tMAC 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) ;
|
||||||
|
}
|
Loading…
Reference in New Issue