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
2009-04-14 14:29:21 +02:00
# define ERR_BAD_USAGE 2 // Mauvais nombre d'arguments lors de l'appel au programme
2008-10-10 15:00:34 +02:00
# 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 de paquets envoyés */
2009-04-14 14:29:21 +02:00
# 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
2008-06-17 15:23:03 +02:00
/* Délai entre chaque paquet envoyé */
2009-04-14 14:29:21 +02:00
# 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)
2008-02-16 10:58:12 +01:00
2009-04-15 14:15:49 +02:00
/* Arguments du programme */
2009-04-14 14:29:21 +02:00
# define OPTIONS "d:i:t:n:"
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 \
2009-04-14 14:29:21 +02:00
\ 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 \
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
2008-06-17 15:23:03 +02:00
int i ; // Compteur
2009-04-14 14:29:21 +02:00
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
2009-05-29 17:02:20 +02:00
float x , y , z ; // Position reçue en réponse du serveur
2009-04-14 14:29:21 +02:00
// 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 ' :
2009-04-15 14:15:49 +02:00
options . nb_pkt = strtol ( optarg , NULL , 0 ) ;
2009-04-14 14:29:21 +02:00
break ;
default :
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
}
2008-06-17 15:23:03 +02:00
2009-04-14 14:29:21 +02:00
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 ;
}
2008-02-16 10:58:12 +01:00
2009-04-14 14:29:21 +02:00
/* Parcours des arguments restants (éventuelles données de calibration) */
if ( argc - optind ! = 0 )
2008-02-16 10:58:12 +01:00
{
2009-04-14 14:29:21 +02:00
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 ;
}
2008-02-16 10:58:12 +01:00
}
2009-04-14 14:29:21 +02:00
/* Vérifications des arguments et initialisation des données non initialisées */
2009-04-15 14:15:49 +02:00
if ( options . delay < 0 ) // Délai non spécifié ou mauvais, application des valeurs par défaut
2008-02-16 10:58:12 +01:00
{
2009-04-15 14:15:49 +02:00
# ifdef DEBUG
fprintf ( stderr , " Attention ! delay : application de la valeur par défaut. \n " ) ;
# endif // DEBUG
2009-04-14 14:29:21 +02:00
if ( is_calibration_request )
options . delay = DEFAULT_DELAY_CALIB ;
else
options . delay = DEFAULT_DELAY_NORMAL ;
}
2009-04-15 14:15:49 +02:00
if ( options . nb_pkt < 1 ) // Nombre de paquets non spécifié ou mauvais, application des valeurs par défaut
2009-04-14 14:29:21 +02:00
{
2009-04-15 14:15:49 +02:00
# ifdef DEBUG
fprintf ( stderr , " Attention ! nb_pkt : application de la valeur par défaut. \n " ) ;
# endif // DEBUG
2009-04-14 14:29:21 +02:00
if ( is_calibration_request )
options . nb_pkt = DEFAULT_NBPKT_CALIB ;
else
options . nb_pkt = DEFAULT_NBPKT_NORMAL ;
2008-02-16 10:58:12 +01:00
}
2009-04-14 14:29:21 +02:00
# 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
2008-02-16 10:58:12 +01:00
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
2009-04-14 14:29:21 +02:00
sockfd = create_udp_sending_socket ( options . dest_ip , 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 ;
}
2009-04-14 14:29:21 +02:00
if ( options . iface [ 0 ] ! = ' \0 ' ) // Si on a spécifié un nom d'interface
2008-02-16 10:58:12 +01:00
{
2009-04-14 14:29:21 +02:00
if ( setsockopt ( sockfd , SOL_SOCKET , SO_BINDTODEVICE , options . iface , strlen ( options . iface ) + 1 ) = = - 1 )
2008-02-16 10:58:12 +01:00
{
2009-04-14 14:29:21 +02:00
fprintf ( stderr , " Erreur ! Impossible de sélectionner l'interface %s pour l'envoi du paquet : " , options . iface ) ;
2008-02-16 10:58:12 +01:00
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 ) ;
2009-04-14 14:29:21 +02:00
if ( is_calibration_request ) // 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 ) ;
2009-04-14 14:29:21 +02:00
buf [ buf_offset + + ] = options . direction ; // Direction
/*
float posX = options . x ;
float posY = options . y ;
float posZ = options . z ;
*/
2008-02-16 10:58:12 +01:00
# ifdef DEBUG
2009-04-14 14:29:21 +02:00
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 ) ) ;
2008-02-14 08:54:51 +01:00
buf_offset + = sizeof ( float ) ;
2009-04-14 14:29:21 +02:00
memcpy ( & buf [ buf_offset ] , & options . y , sizeof ( float ) ) ;
2008-02-14 08:54:51 +01:00
buf_offset + = sizeof ( float ) ;
2009-04-14 14:29:21 +02:00
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 ) ) ;
2008-02-14 08:54:51 +01:00
}
/* 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 ) ;
2009-04-14 14:29:21 +02:00
# endif // DEBUG
2008-02-14 08:54:51 +01:00
2009-04-14 14:29:21 +02:00
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 :
2008-02-16 10:58:12 +01:00
{
2009-04-14 14:29:21 +02:00
usleep ( options . delay ) ; // On attend le temps voulu entre chaque paquet.
2008-06-17 15:23:03 +02:00
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 ) ;
2009-04-14 14:29:21 +02:00
# endif // DEBUG
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 ' ) ;
2009-04-14 14:29:21 +02:00
# endif // DEBUG
2008-03-14 11:31:04 +01:00
2008-02-14 08:54:51 +01:00
( void ) close ( sockfd ) ;
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 ) ;
2008-02-14 08:54:51 +01:00
return 0 ;
}