2008-02-14 08:54:51 +01:00
/*
* This file is part of the rtap localisation project .
*/
2008-10-06 17:27:33 +02:00
# include "../../libowlps/owlps.h"
2008-02-14 08:54:51 +01:00
2008-03-14 11:31:04 +01:00
# define DEBUG
2008-02-14 08:54:51 +01:00
/* Codes d'erreurs */
2008-10-10 15:00:34 +02:00
# 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_SENDING_INFO 3 // Erreur lors de l'envoi de l'une des demandes de positionnement
2008-02-14 08:54:51 +01:00
2008-02-16 10:58:12 +01:00
/* 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
2008-06-17 15:23:03 +02:00
# define NBPKT_NORMAL 10 // Nombre de paquets envoyés dans le cas d'une demande de localisation
/* Délai entre chaque paquet envoyé */
2008-10-06 17:27:33 +02:00
# 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)
2008-02-16 10:58:12 +01:00
2008-02-14 08:54:51 +01:00
/* Affiche le mode d'emploi du programme */
void print_usage ( char * prog )
{
printf ( " Usage : \n \
2008-02-16 10:58:12 +01:00
\ t - Demande de localisation : % s [ iface ] ip_serveur \ n \
\ t - Requête de calibration : % s [ iface ] ip_serveur direction x y z \ n \
2008-02-19 11:59:22 +01:00
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 \
2008-02-14 08:54:51 +01:00
" , prog, prog) ;
}
int main ( int argc , char * argv [ ] )
{
struct timeval request_time ;
2008-02-16 10:58:12 +01:00
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é
2008-02-14 08:54:51 +01:00
struct sockaddr_in server , client ;
2008-02-16 10:58:12 +01:00
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
2008-06-17 15:23:03 +02:00
int i ; // Compteur
int delay = ( argc = = ARGC_NORMAL ? DELAY_NORMAL : DELAY_CALIB ) ; // Temps d'attente entre chaque émission de paquet
2008-02-16 10:58:12 +01:00
/* Test du nombre d'arguments */
if ( argc = = ARGC_NORMAL + 1 | | argc = = ARGC_CALIB + 1 ) // Si on a spécifié un nom d'interface
{
strncpy ( iface , argv [ 1 ] , IFNAMSIZ + 1 ) ;
argv + + ;
argc - - ;
}
/* Test du nombre d'arguments (suite) */
if ( argc ! = ARGC_NORMAL & & argc ! = ARGC_CALIB )
{
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_NUMBER_OF_ARGS ;
}
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
2008-02-20 16:36:44 +01:00
sockfd = create_udp_sending_socket ( argv [ 1 ] , LOC_REQUEST_DEFAULT_PORT , & server , & client ) ;
2008-02-16 10:58:12 +01:00
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 ( setsockopt ( sockfd , SOL_SOCKET , SO_BINDTODEVICE , iface , strlen ( iface ) + 1 ) = = - 1 )
{
fprintf ( stderr , " Erreur ! Impossible de sélectionner l'interface %s pour l'envoi du paquet : " , iface ) ;
perror ( " " ) ;
fprintf ( stderr , " Envoi sur l'interface par défaut. \n " ) ;
}
}
2008-02-14 08:54:51 +01:00
2008-02-16 10:58:12 +01:00
/* Création du paquet à envoyer */
2008-02-14 08:54:51 +01:00
gettimeofday ( & request_time , NULL ) ;
2008-06-17 15:23:03 +02:00
if ( argc = = ARGC_NORMAL ) // Paquet normal
2008-02-14 08:54:51 +01:00
{
2008-03-14 11:31:04 +01:00
printf ( " Envoi normal effectué à : %llu \n " , timeval_to_ms ( request_time ) ) ;
2008-02-14 08:54:51 +01:00
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 ) ) ;
}
2008-06-17 15:23:03 +02:00
else // Paquet calibration
2008-02-14 08:54:51 +01:00
{
2008-03-14 11:31:04 +01:00
printf ( " Envoi Calibration effectué à : %llu \n " , timeval_to_ms ( request_time ) ) ;
2008-02-14 08:54:51 +01:00
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 ] ) ;
2008-02-16 10:58:12 +01:00
# ifdef DEBUG
printf ( " direction = %d, posX = %f, posY = %f, posZ = %f \n " , buf [ buf_offset - 1 ] , posX , posY , posZ ) ;
# endif
2008-02-14 08:54:51 +01:00
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 ) ) ;
}
/* Envoi des infos au serveur d'aggrégation */
2008-06-17 15:23:03 +02:00
nsent = sendto ( sockfd , ( void * ) buf , buf_size , 0 , ( struct sockaddr * ) & server , ( socklen_t ) sizeof ( server ) ) ; // Envoi d'un paquet.
2008-02-14 08:54:51 +01:00
if ( nsent ! = ( ssize_t ) buf_size )
{
2008-06-17 15:23:03 +02:00
perror ( " Erreur lors de l'envoi des informations au serveur " ) ;
2008-02-14 08:54:51 +01:00
return ERR_SENDING_INFO ;
}
2008-06-17 15:23:03 +02:00
# ifdef DEBUG
printf ( " Paquets envoyés : . " ) ;
fflush ( stdout ) ;
# endif
2008-02-14 08:54:51 +01:00
2008-06-17 15:23:03 +02:00
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 :
2008-02-16 10:58:12 +01:00
{
2008-06-17 15:23:03 +02:00
usleep ( 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 )
2008-02-16 10:58:12 +01:00
{
2008-06-17 15:23:03 +02:00
perror ( " Erreur lors de l'envoi des infos au serveur " ) ;
return ERR_SENDING_INFO ;
}
2008-03-14 11:31:04 +01:00
# ifdef DEBUG
2008-06-17 15:23:03 +02:00
putchar ( ' . ' ) ;
fflush ( stdout ) ;
2008-03-14 11:31:04 +01:00
# endif
2008-02-16 10:58:12 +01:00
}
2008-06-17 15:23:03 +02:00
2008-03-14 11:31:04 +01:00
# ifdef DEBUG
putchar ( ' \n ' ) ;
# endif
2008-02-14 08:54:51 +01:00
( void ) close ( sockfd ) ;
return 0 ;
}