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

269 lines
8.7 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:t:n:"
/* Affiche le mode d'emploi du programme */
void print_usage(char *prog)
{
printf("Usage :\n\
\t- Demande de localisation : %s -d destination_ip [-i iface] [-t delay] [-n nb_packets]\n\
\t- Requête de calibration : %s -d destination_ip [-i iface] [-t delay] [-n nb_packets] direction x y z\n\
destination_ip est l'adresse IP vers laquelle sera envoyée la demande de localisation.\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\
", prog, prog) ;
}
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
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
// Données de calibration :
DIRECTION direction ;
float x ;
float y ;
float z ;
} options = {"", "", -1, -1, 0, 0, 0, 0} ;
int opt ; // Retour de getopt
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
float x,y,z; // Position reçue en réponse du serveur
// int delay = (argc == ARGC_NORMAL ? DELAY_NORMAL : DELAY_CALIB) ;
/* 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 't' :
options.delay = strtol(optarg, NULL, 0) ;
break ;
case 'n' :
options.nb_pkt = 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 ;
}
#ifdef DEBUG
fprintf(stderr, "Options :\n\
\tDestination : %s\n\
\tInterface : %s\n\
\tDelay : %ld\n\
\tNumber of packets : %d\n\
\tDirection : %d\n\
\tX : %f\n\
\tY : %f\n\
\tZ : %f\n",
options.dest_ip,
options.iface,
options.delay,
options.nb_pkt,
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, LOC_REQUEST_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 ;
}
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 */
sockfd = create_udp_listening_socket(MOBILE_DEFAULT_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);
return 0 ;
}