[Client] getopt, nombre et délai d'envoi

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
This commit is contained in:
Matteo Cypriani 2009-04-14 12:29:21 +00:00
parent f02fd800db
commit 0d7946e3db
1 changed files with 135 additions and 50 deletions

View File

@ -2,36 +2,36 @@
* This file is part of the rtap localisation project.
*/
#include <stdlib.h>
#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) ;