/* * This file is part of the rtap localisation project. */ #include "../librtaputil/rtaputil.h" //#define DEBUG /* Codes d'erreurs */ #define ERR_CREATING_SOCKET 1 #define ERR_BAD_NUMBER_OF_ARGS 2 #define ERR_SENDING_INFO 3 /* 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 /* 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\ 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.\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 char iface[IFNAMSIZ + 1] = "" ; // Interface réseau depuis laquelle on envoit le paquet /* 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 */ sockfd = create_udp_sending_socket(argv[1], AGGREGATE_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 (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") ; } } /* Création du paquet à envoyer */ gettimeofday(&request_time, NULL) ; if(argc == ARGC_NORMAL) // Paquet normal { printf("Envoi normal effectué à : %lu\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 if(argc == ARGC_CALIB) // Paquet calibration { printf("Envoi Calibration effectué à : %lu\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++] = atoi(argv[2]) ; // Direction float posX = atof(argv[3]) ; float posY = atof(argv[4]) ; float posZ = atof(argv[5]) ; #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)) ; 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 */ 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 ; } if (argc == ARGC_CALIB) // Dans le cas d'un paquet de calibration, on envoit une rafale de NBPKT_CALIB paquets? { int i ; for (i = 0 ; i < NBPKT_CALIB - 1 ; i++) { 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 ; } } } (void) close(sockfd) ; return 0 ; }