owlps/infrastructure-centred/owlps-client/owlps-client.c

311 lines
10 KiB
C
Raw Normal View History

/*
* This file is part of the rtap localisation project.
*/
#include "../../libowlps/owlps.h"
#define DEBUG
/* Codes d'erreurs */
#define ERR_CREATING_SOCKET 1 // Erreur lors de la création de la socket d'envoi
#define ERR_BAD_USAGE 2 // Mauvais nombre d'arguments lors de l'appel au programme
#define ERR_SENDING_INFO 3 // Erreur lors de l'envoi de l'une des demandes de positionnement
/* Nombre de paquets envoyés */
#define DEFAULT_NBPKT_CALIB 20 // Rafale de 20 paquets lors de la calibration
#define DEFAULT_NBPKT_NORMAL 10 // Nombre de paquets envoyés dans le cas d'une demande de localisation
/* Délai entre chaque paquet envoyé */
#define DEFAULT_DELAY_CALIB 50000 // Délai entre chaque émission de paquet lors de la calibration (en microsecondes)
#define DEFAULT_DELAY_NORMAL 25000 // Délai entre chaque émission de paquet dans le cas d'une demande de localisation (en microsecondes)
/* Arguments du programme */
#define OPTIONS "d:i:l::n:p:t:"
/* Affiche le mode d'emploi du programme */
void print_usage(char *prog)
{
printf("Usage :\n\
\t- Demande de localisation : %s -d dest_ip [-p dest_port] [-i iface] [-t delay] [-n nb_packets] [-l [port]]\n\
\t- Requête de calibration : %s -d dest_ip [-i iface] [-t delay] [-n nb_packets] direction x y z\n\
- dest_ip est l'adresse IP vers laquelle sera envoyée la demande de localisation.\n\
- dest_port est le port sur lequel sera envoyée la demande de localisation (défaut : %d).\n\
- delay est le délai d'attente entre chaque paquet émis.\n\
- nb_packets est le nombre de paquets émis pour la demande.\n\
- iface est une chaîne désignant le nom de interface réseau à partir de laquelle envoyer la demande (par exemple \"eth2\"). Si elle n'est pas spécifiée, le choix de l'interface source est automatique. Vous devez être root pour utiliser cette option.\n\
- L'option -l indique au programme qu'il doit attendre et afficher la position calculée par l'infrastructure avant de quitter. L'argument optionnel \"port\" permet de spécifier le port d'écoute ; s'il n'est pas présent, la valeur par défaut (%d) est utilisée.\n\
", prog, prog, LOC_REQUEST_DEFAULT_PORT, MOBILE_DEFAULT_PORT) ;
}
int main(int argc, char *argv[])
{
struct timeval request_time ;
char *buf = NULL ; // Paquet à envoyer
int buf_offset ; // Indice dans le paquet à envoyer, utilisé lors de sa création
int buf_size ; // Taille du paquet envoyé
struct sockaddr_in server, client ;
int sockfd ; // Descripteur de la socket d'envoi
ssize_t nsent ; // Retour de sendto
int i ; // Compteur
BOOL is_calibration_request = FALSE ; // Sera positionné à TRUE si le paquet est une requête de calibration (FALSE pour une simple demande de localisation)
struct {
char dest_ip[16] ; // Adresse IP de destination des paquets de la demande
long dest_port ;
char iface[IFNAMSIZ + 1] ; // Interface réseau depuis laquelle on envoit les paquets
long delay ; // Temps d'attente entre chaque émission de paquet
short nb_pkt ; // Nombre de paquets envoyés pour la demande
long listening_port ;
// Données de calibration :
DIRECTION direction ;
float x ;
float y ;
float z ;
} options = {"",
LOC_REQUEST_DEFAULT_PORT,
"",
-1,
-1,
-1,
0, 0, 0, 0
} ;
int opt ; // Retour de getopt
float x, y, z ; // Position reçue en réponse du serveur
Reconstitution du dépôt, étape 5 (et dernière) Le commentaire de révision initial figure ci-dessous. Les différences par rapport à ce commit sont : - Dans code/infrastructure-centred/owlps-client/ : importation des modifs de Julien dans la dernière version du client (Julien avait utilisé comme base une ancienne version). - Dans code/infrastructure-centred/owlps-listener/ : idem. - Dans code/owlps-positioning/ : ° Suppression de client (déplacé dans les archives). ° Makefile : ajout d'une pseudo-cible .PHONY. - code/writeInDb/ : ° Le binaire n'est pas versionné. ° Application de astyle --style=gnu. | r93 | jgraeffly | 2009-05-27 14:51:40 +0200 (mer 27 mai 2009) | 23 lines | Chemins modifiés : | R /code/infrastructure-centred/owlps-aggregator/owlps-aggregator.h | R /code/infrastructure-centred/owlps-aggregator/owlps-aggregatord.c | R /code/infrastructure-centred/owlps-client/owlps-client.c | R /code/infrastructure-centred/owlps-listener/owlps-listener.h | R /code/infrastructure-centred/owlps-listener/owlps-listenerd.c | R /code/libowlps/owlps.h | R /code/owlps-positioning/Makefile | D /code/owlps-positioning/client | A /code/owlps-positioning/libowlps-positioning.cc | A /code/owlps-positioning/libowlps-positioning.hh | R /code/owlps-positioning/owlps-positioning.cc | A /code/owlps-positioning/owlps-positioning.cfg | R /code/owlps-positioning/owlps-positioning.hh | R /code/owlps-positioning/positioning.cc | R /code/owlps-positioning/positioning.hh | R /code/owlps-positioning/server.cc | R /code/owlps-positioning/server.hh | R /code/owlps-positioning/treatment.cc | R /code/owlps-positioning/treatment.hh | A /code/writeInDb | A /code/writeInDb/writeindb | A /code/writeInDb/writeindb.cc | A /code/writeInDb/writeindb.hh | | - Mise à jour du positioner : | Prise en charge de la BdD pour utilisation ainsi que pour la | sauvegarde des résultats | Envoi du résultat au client | Prise en compte du fichier de configuration ainsi que des | lignes de commande avec la library boost | | - Mise à jour de l'aggregator : | Pris en compte de la BdD pour la sauvegarde des requetes de | calibration ou de localisation | Envoi des demandes de localisation uniquement vers le | positioner | Ajout des options utilisables en ligne de commande et dans le | fichier de conf | | - Mise à jour du listener : | Ajout de l'envoi de l'adresse IP du mobile | | - Mise à jour du mobile : | Ajout de la socket de récupération de la réponse du serveur la | réponse est sous forme de 3 float (x, y, z) et non d'un Point. | | - Mise à jour de owlps.h : | Ajout des ports par défaut du positioner ainsi que du mobile. | | - Ajout de writeInDb : | Programme permettant de mettre les données contenu dans un | fichier dans la BdD git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@94 785a6c6c-259e-4ff1-8b91-dc31627914f0
2009-05-29 17:02:20 +02:00
/* Parcours des arguments de la ligne de commandes */
while ((opt = getopt(argc, argv, OPTIONS)) != -1)
{
switch (opt)
{
case 'd' :
strncpy(options.dest_ip, optarg, 16) ;
break ;
case 'i' :
strncpy(options.iface, optarg, IFNAMSIZ + 1) ;
break ;
case 'l' :
if (optarg == 0) // Les options facultatives de getopt ne gèrent pas
{ // les valeurs séparées (du type : -l <port>)
if (argv[optind] == NULL // Si on est en bout de chaîne ou que l'optind
|| argv[optind][0] == '-') // suivant est une option, c'est qu'on a -l sans numéro de port
options.listening_port = MOBILE_DEFAULT_PORT ; // on prend donc la valeur par défaut.
else
{ // Sinon on prend la valeur de l'optind :
options.listening_port = strtol(argv[optind], NULL, 0) ;
optind++ ;
}
}
else // On a une option de la forme -l<port>, tout va bien
options.listening_port = strtol(optarg, NULL, 0) ;
break ;
case 'n' :
options.nb_pkt = strtol(optarg, NULL, 0) ;
break ;
case 'p' :
options.dest_port = strtol(optarg, NULL, 0) ;
break ;
case 't' :
options.delay = strtol(optarg, NULL, 0) ;
break ;
default :
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
}
if (options.dest_ip[0] == '\0') // On vérifie si on a bien une adresse de destination
{
fprintf(stderr, "Erreur ! Vous devez spécifier une adresse de destination (-d).\n") ;
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
/* Parcours des arguments restants (éventuelles données de calibration) */
if (argc - optind != 0)
{
if (argc - optind == 4)
{
is_calibration_request = TRUE ;
options.direction = strtol(argv[optind++], NULL, 0) ;
options.x = strtod(argv[optind++], NULL) ;
options.y = strtod(argv[optind++], NULL) ;
options.z = strtod(argv[optind], NULL) ;
}
else
{ // Si le nombre d'arguments est mauvais, on quitte
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
}
/* Vérifications des arguments et initialisation des données non initialisées */
if (options.delay < 0) // Délai non spécifié ou mauvais, application des valeurs par défaut
{
#ifdef DEBUG
fprintf(stderr, "Attention ! delay : application de la valeur par défaut.\n") ;
#endif // DEBUG
if (is_calibration_request)
options.delay = DEFAULT_DELAY_CALIB ;
else
options.delay = DEFAULT_DELAY_NORMAL ;
}
if (options.nb_pkt < 1) // Nombre de paquets non spécifié ou mauvais, application des valeurs par défaut
{
#ifdef DEBUG
fprintf(stderr, "Attention ! nb_pkt : application de la valeur par défaut.\n") ;
#endif // DEBUG
if (is_calibration_request)
options.nb_pkt = DEFAULT_NBPKT_CALIB ;
else
options.nb_pkt = DEFAULT_NBPKT_NORMAL ;
}
if (is_calibration_request && options.listening_port != -1)
{
#ifdef DEBUG
fprintf(stderr, "Attention ! Vous ne pouvez pas attendre de réponse du serveur lorsque vous effectuez une requête de calibration. Option -l ignorée...\n") ;
#endif // DEBUG
options.listening_port = -1 ;
}
#ifdef DEBUG
fprintf(stderr, "Options :\n\
\tDestination IP : %s\n\
\tDestination port : %ld\n\
\tInterface : %s\n\
\tDelay : %ld\n\
\tNumber of packets : %d\n\
\tListening port : %ld\n\
\tDirection : %d\n\
\tX : %f\n\
\tY : %f\n\
\tZ : %f\n",
options.dest_ip,
options.dest_port,
options.iface,
options.delay,
options.nb_pkt,
options.listening_port,
options.direction,
options.x,
options.y,
options.z
) ;
#endif // DEBUG
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
sockfd = create_udp_sending_socket(options.dest_ip, options.dest_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 ;
}
if (options.iface[0] != '\0') // Si on a spécifié un nom d'interface
{
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, options.iface, strlen(options.iface) + 1) == -1)
{
fprintf(stderr, "Erreur ! Impossible de sélectionner l'interface %s pour l'envoi du paquet : ", options.iface) ;
perror("") ;
fprintf(stderr, "Envoi sur l'interface par défaut.\n") ;
}
}
/* Création du paquet à envoyer */
gettimeofday(&request_time, NULL) ;
if (is_calibration_request) // Paquet calibration
{
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 ;
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++] = options.direction ; // Direction
/*
float posX = options.x ;
float posY = options.y ;
float posZ = options.z ;
*/
#ifdef DEBUG
printf("Direction = %d, X = %f, Y = %f, Z = %f\n", buf[buf_offset - 1], options.x, options.y, options.z) ;
#endif // DEBUG
memcpy(&buf[buf_offset], &options.x, sizeof(float)) ;
buf_offset += sizeof(float) ;
memcpy(&buf[buf_offset], &options.y, sizeof(float)) ;
buf_offset += sizeof(float) ;
memcpy(&buf[buf_offset], &options.z, sizeof(float)) ;
}
else // Paquet normal
{
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
memcpy(&buf[1], &request_time, sizeof(request_time)) ;
}
/* Envoi des infos au serveur d'aggrégation */
nsent = sendto(sockfd, (void *) buf, buf_size, 0, (struct sockaddr *) &server, (socklen_t) sizeof(server)) ; // Envoi d'un paquet.
if (nsent != (ssize_t) buf_size)
{
perror("Erreur lors de l'envoi des informations au serveur ") ;
return ERR_SENDING_INFO ;
}
#ifdef DEBUG
printf("Paquets envoyés : .") ;
fflush(stdout) ;
#endif // DEBUG
for (i = 0 ; i < options.nb_pkt - 1 ; i++) // Si tels sont les paramètres, on envoit éventuellement la suite de la rafale de paquets :
{
usleep(options.delay) ; // On attend le temps voulu entre chaque paquet.
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 ;
}
#ifdef DEBUG
putchar('.') ;
fflush(stdout) ;
#endif // DEBUG
}
#ifdef DEBUG
putchar('\n') ;
#endif // DEBUG
(void) close(sockfd) ;
Reconstitution du dépôt, étape 5 (et dernière) Le commentaire de révision initial figure ci-dessous. Les différences par rapport à ce commit sont : - Dans code/infrastructure-centred/owlps-client/ : importation des modifs de Julien dans la dernière version du client (Julien avait utilisé comme base une ancienne version). - Dans code/infrastructure-centred/owlps-listener/ : idem. - Dans code/owlps-positioning/ : ° Suppression de client (déplacé dans les archives). ° Makefile : ajout d'une pseudo-cible .PHONY. - code/writeInDb/ : ° Le binaire n'est pas versionné. ° Application de astyle --style=gnu. | r93 | jgraeffly | 2009-05-27 14:51:40 +0200 (mer 27 mai 2009) | 23 lines | Chemins modifiés : | R /code/infrastructure-centred/owlps-aggregator/owlps-aggregator.h | R /code/infrastructure-centred/owlps-aggregator/owlps-aggregatord.c | R /code/infrastructure-centred/owlps-client/owlps-client.c | R /code/infrastructure-centred/owlps-listener/owlps-listener.h | R /code/infrastructure-centred/owlps-listener/owlps-listenerd.c | R /code/libowlps/owlps.h | R /code/owlps-positioning/Makefile | D /code/owlps-positioning/client | A /code/owlps-positioning/libowlps-positioning.cc | A /code/owlps-positioning/libowlps-positioning.hh | R /code/owlps-positioning/owlps-positioning.cc | A /code/owlps-positioning/owlps-positioning.cfg | R /code/owlps-positioning/owlps-positioning.hh | R /code/owlps-positioning/positioning.cc | R /code/owlps-positioning/positioning.hh | R /code/owlps-positioning/server.cc | R /code/owlps-positioning/server.hh | R /code/owlps-positioning/treatment.cc | R /code/owlps-positioning/treatment.hh | A /code/writeInDb | A /code/writeInDb/writeindb | A /code/writeInDb/writeindb.cc | A /code/writeInDb/writeindb.hh | | - Mise à jour du positioner : | Prise en charge de la BdD pour utilisation ainsi que pour la | sauvegarde des résultats | Envoi du résultat au client | Prise en compte du fichier de configuration ainsi que des | lignes de commande avec la library boost | | - Mise à jour de l'aggregator : | Pris en compte de la BdD pour la sauvegarde des requetes de | calibration ou de localisation | Envoi des demandes de localisation uniquement vers le | positioner | Ajout des options utilisables en ligne de commande et dans le | fichier de conf | | - Mise à jour du listener : | Ajout de l'envoi de l'adresse IP du mobile | | - Mise à jour du mobile : | Ajout de la socket de récupération de la réponse du serveur la | réponse est sous forme de 3 float (x, y, z) et non d'un Point. | | - Mise à jour de owlps.h : | Ajout des ports par défaut du positioner ainsi que du mobile. | | - Ajout de writeInDb : | Programme permettant de mettre les données contenu dans un | fichier dans la BdD git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@94 785a6c6c-259e-4ff1-8b91-dc31627914f0
2009-05-29 17:02:20 +02:00
/* Attente de la position du serveur */
if (options.listening_port != -1)
{
sockfd = create_udp_listening_socket(options.listening_port);
recvfrom(sockfd, &x, sizeof(float), 0, NULL, NULL);
recvfrom(sockfd, &y, sizeof(float), 0, NULL, NULL);
recvfrom(sockfd, &z, sizeof(float), 0, NULL, NULL);
(void) close(sockfd) ;
printf("Position reçue : (%.4f;%.4f;%.4f)\n", x, y, z);
}
Reconstitution du dépôt, étape 5 (et dernière) Le commentaire de révision initial figure ci-dessous. Les différences par rapport à ce commit sont : - Dans code/infrastructure-centred/owlps-client/ : importation des modifs de Julien dans la dernière version du client (Julien avait utilisé comme base une ancienne version). - Dans code/infrastructure-centred/owlps-listener/ : idem. - Dans code/owlps-positioning/ : ° Suppression de client (déplacé dans les archives). ° Makefile : ajout d'une pseudo-cible .PHONY. - code/writeInDb/ : ° Le binaire n'est pas versionné. ° Application de astyle --style=gnu. | r93 | jgraeffly | 2009-05-27 14:51:40 +0200 (mer 27 mai 2009) | 23 lines | Chemins modifiés : | R /code/infrastructure-centred/owlps-aggregator/owlps-aggregator.h | R /code/infrastructure-centred/owlps-aggregator/owlps-aggregatord.c | R /code/infrastructure-centred/owlps-client/owlps-client.c | R /code/infrastructure-centred/owlps-listener/owlps-listener.h | R /code/infrastructure-centred/owlps-listener/owlps-listenerd.c | R /code/libowlps/owlps.h | R /code/owlps-positioning/Makefile | D /code/owlps-positioning/client | A /code/owlps-positioning/libowlps-positioning.cc | A /code/owlps-positioning/libowlps-positioning.hh | R /code/owlps-positioning/owlps-positioning.cc | A /code/owlps-positioning/owlps-positioning.cfg | R /code/owlps-positioning/owlps-positioning.hh | R /code/owlps-positioning/positioning.cc | R /code/owlps-positioning/positioning.hh | R /code/owlps-positioning/server.cc | R /code/owlps-positioning/server.hh | R /code/owlps-positioning/treatment.cc | R /code/owlps-positioning/treatment.hh | A /code/writeInDb | A /code/writeInDb/writeindb | A /code/writeInDb/writeindb.cc | A /code/writeInDb/writeindb.hh | | - Mise à jour du positioner : | Prise en charge de la BdD pour utilisation ainsi que pour la | sauvegarde des résultats | Envoi du résultat au client | Prise en compte du fichier de configuration ainsi que des | lignes de commande avec la library boost | | - Mise à jour de l'aggregator : | Pris en compte de la BdD pour la sauvegarde des requetes de | calibration ou de localisation | Envoi des demandes de localisation uniquement vers le | positioner | Ajout des options utilisables en ligne de commande et dans le | fichier de conf | | - Mise à jour du listener : | Ajout de l'envoi de l'adresse IP du mobile | | - Mise à jour du mobile : | Ajout de la socket de récupération de la réponse du serveur la | réponse est sous forme de 3 float (x, y, z) et non d'un Point. | | - Mise à jour de owlps.h : | Ajout des ports par défaut du positioner ainsi que du mobile. | | - Ajout de writeInDb : | Programme permettant de mettre les données contenu dans un | fichier dans la BdD git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@94 785a6c6c-259e-4ff1-8b91-dc31627914f0
2009-05-29 17:02:20 +02:00
return 0 ;
}