From 0d7946e3dbc3fd1b7e5fc8fb4c61e222a13940f3 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Tue, 14 Apr 2009 12:29:21 +0000 Subject: [PATCH] =?UTF-8?q?[Client]=20getopt,=20nombre=20et=20d=C3=A9lai?= =?UTF-8?q?=20d'envoi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit owlps-client : - Utilisation de getopt pour la gestion des arguments. - On peut maintenant spécifier le nombre de paquets envoyés et le délai entre deux paquets. git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@87 785a6c6c-259e-4ff1-8b91-dc31627914f0 --- .../owlps-client/owlps-client.c | 185 +++++++++++++----- 1 file changed, 135 insertions(+), 50 deletions(-) diff --git a/infrastructure-centred/owlps-client/owlps-client.c b/infrastructure-centred/owlps-client/owlps-client.c index 2bb985e..6a980a7 100644 --- a/infrastructure-centred/owlps-client/owlps-client.c +++ b/infrastructure-centred/owlps-client/owlps-client.c @@ -2,36 +2,36 @@ * This file is part of the rtap localisation project. */ - +#include #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_NUMBER_OF_ARGS 2 // Mauvais nombre d'arguments lors de l'appel au programme +#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 d'arguments du programme */ -#define ARGC_NORMAL 2 -#define ARGC_CALIB 6 - /* Nombre de paquets envoyés */ -#define NBPKT_CALIB 20 // Rafale de 20 paquets lors de la calibration -#define NBPKT_NORMAL 10 // Nombre de paquets envoyés dans le cas d'une demande de localisation +#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 DELAY_CALIB 50000 // Délai entre chaque émission de paquet lors de la calibration (en microsecondes) -#define DELAY_NORMAL 25000 // Délai entre chaque émission de paquet dans le cas d'une demande de localisation (en microsecondes) +#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) +#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 [iface] ip_serveur\n\ -\t- Requête de calibration : %s [iface] ip_serveur direction x y z\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) ; } @@ -48,41 +48,124 @@ int main(int argc, char *argv[]) struct sockaddr_in server, client ; int sockfd ; // Descripteur de la socket d'envoi ssize_t nsent ; // Retour de sendto - char iface[IFNAMSIZ + 1] = "" ; // Interface réseau depuis laquelle on envoit le paquet int i ; // Compteur - int delay = (argc == ARGC_NORMAL ? DELAY_NORMAL : DELAY_CALIB) ; // Temps d'attente entre chaque émission de paquet + 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 - /* Test du nombre d'arguments */ - if (argc == ARGC_NORMAL + 1 || argc == ARGC_CALIB + 1) // Si on a spécifié un nom d'interface + // int delay = (argc == ARGC_NORMAL ? DELAY_NORMAL : DELAY_CALIB) ; + + /* Parcours des arguments de la ligne de commandes */ + while ((opt = getopt(argc, argv, OPTIONS)) != -1) { - strncpy(iface, argv[1], IFNAMSIZ + 1) ; - argv++ ; - argc-- ; + 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) ; + options.nb_pkt = atoi(optarg) ; + break ; + default : + print_usage(argv[0]) ; + return ERR_BAD_USAGE ; + } } - /* Test du nombre d'arguments (suite) */ - if (argc != ARGC_NORMAL && argc != ARGC_CALIB) + 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_NUMBER_OF_ARGS ; + 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 == -1) // Délai non spécifié, application des valeurs par défaut + { + 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é, application des valeurs par défaut + { + 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(argv[1], LOC_REQUEST_DEFAULT_PORT, &server, &client) ; + 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 (iface[0] != '\0') // Si on a spécifié un nom d'interface + if (options.iface[0] != '\0') // Si on a spécifié un nom d'interface { - if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) + 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 : ", iface) ; + 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") ; } @@ -92,16 +175,7 @@ int main(int argc, char *argv[]) /* Création du paquet à envoyer */ gettimeofday(&request_time, NULL) ; - if (argc == ARGC_NORMAL) // 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)) ; - } - - else // Paquet calibration + if (is_calibration_request) // Paquet calibration { printf("Envoi Calibration effectué à : %llu\n", timeval_to_ms(request_time)) ; @@ -112,18 +186,29 @@ int main(int argc, char *argv[]) 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]) ; + buf[buf_offset++] = options.direction ; // Direction + /* + float posX = options.x ; + float posY = options.y ; + float posZ = options.z ; + */ #ifdef DEBUG - printf("direction = %d, posX = %f, posY = %f, posZ = %f\n", buf[buf_offset - 1], posX, posY, posZ) ; -#endif - memcpy(&buf[buf_offset], &posX, sizeof(float)) ; + 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], &posY, sizeof(float)) ; + memcpy(&buf[buf_offset], &options.y, sizeof(float)) ; buf_offset += sizeof(float) ; - memcpy(&buf[buf_offset], &posZ, 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)) ; } @@ -137,11 +222,11 @@ int main(int argc, char *argv[]) #ifdef DEBUG printf("Paquets envoyés : .") ; fflush(stdout) ; -#endif +#endif // DEBUG - for (i = 0 ; i < (argc == ARGC_NORMAL ? NBPKT_NORMAL : NBPKT_CALIB) - 1 ; i++) // Si tels sont les paramètres, on envoit éventuellement la suite de la rafale de paquets : + 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(delay) ; // On attend le temps voulu entre chaque paquet. + 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) @@ -153,12 +238,12 @@ int main(int argc, char *argv[]) #ifdef DEBUG putchar('.') ; fflush(stdout) ; -#endif +#endif // DEBUG } #ifdef DEBUG putchar('\n') ; -#endif +#endif // DEBUG (void) close(sockfd) ;