From 1863bd9e9f743d5b920b2963c167005c0b5c817d Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 12 Jul 2010 12:50:02 +0200 Subject: [PATCH] [Aggregator] Code refactoring (conf parsing, loop) --- .../owlps-aggregator/owlps-aggregator.h | 10 +- .../owlps-aggregator/owlps-aggregatord.c | 375 ++++++++++-------- 2 files changed, 225 insertions(+), 160 deletions(-) diff --git a/infrastructure-centred/owlps-aggregator/owlps-aggregator.h b/infrastructure-centred/owlps-aggregator/owlps-aggregator.h index 27f45b8..1c26103 100644 --- a/infrastructure-centred/owlps-aggregator/owlps-aggregator.h +++ b/infrastructure-centred/owlps-aggregator/owlps-aggregator.h @@ -58,13 +58,21 @@ typedef struct _couple_list /* En-têtes de fonctions */ +void initialise_configuration(int argc, char **argv) ; +void parse_config_file(int argc, char **argv) ; +void parse_command_line(int argc, char **argv) ; +void check_configuration(void) ; + +int read_loop(int sockfd) ; void got_couple_info(couple_list **couples, couple_message message) ; void free_couple_list(couple_list **couples) ; #ifdef DEBUG void print_couple_list(couple_list *couples) ; void print_couple_info(couple_info_list *info) ; #endif // DEBUG + void* monitor_couple_list(couple_list **couples) ; -void print_usage(char *prog) ; +char* ip_bytes_to_string(unsigned char *ip_binary) ; +void print_usage(void) ; #endif diff --git a/infrastructure-centred/owlps-aggregator/owlps-aggregatord.c b/infrastructure-centred/owlps-aggregator/owlps-aggregatord.c index 32a0390..2748d13 100644 --- a/infrastructure-centred/owlps-aggregator/owlps-aggregatord.c +++ b/infrastructure-centred/owlps-aggregator/owlps-aggregatord.c @@ -7,163 +7,21 @@ -cfg_t *cfg ; // Structure contenant la configuration - -char* ip_bytes_to_string(unsigned char *ip_binary) -{ - int taille = 16, i = 0; - for(i = 0; i < 4; i++) - { - if(ip_binary[i] < 0x64) - taille--; - if(ip_binary[i] < 0x10) - taille--; - } - - char *ret = malloc(sizeof(char) * taille) ; +char *program_name = NULL ; +cfg_t *cfg = NULL ; // Configuration structure +couple_list *couples = NULL ; // Computed data list - sprintf(ret, "%d.%d.%d.%d", ip_binary[0], ip_binary[1], ip_binary[2], ip_binary[3]) ; - ret[taille-1] = '\0' ; - - return ret ; -} int main(int argc, char **argv) { int ret = 0 ; // Valeur de retour du programme - couple_list *couples = NULL ; // Liste des données traitées struct sigaction action ; // Structure de mise en place des gestionnaires de signaux - int sockfd ; // Socket d'écoute UDP - int nread ; // Retour de recvfrom - struct sockaddr_in client; // Structure pour le client UDP - socklen_t client_len = sizeof(client) ; // Taille du client pour la socket - couple_message message ; // Message lu sur la socket pthread_t thread ; // Thread pour la fonction de surveillance de la liste d'informations agrégées - char *ap_mac_string, *mobile_mac_string ; // Pointeurs pour retour de mac_bytes_to_string() - char *mobile_ip_string ; + int sockfd ; // Socket d'écoute UDP - cfg_opt_t opts[] = { // Options reconnues par confuse dans le fichier de config - CFG_INT("listening_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE), // Port d'écoute - CFG_INT("positioner_port", POSITIONER_DEFAULT_PORT, CFGF_NONE), // Port d'envoi sur le serveur de calcul - CFG_STR("positioner_ip", POSITIONER_DEFAULT_IP, CFGF_NONE), // Adresse IP du serveur de géolocalisation - CFG_STR("output_file", "", CFGF_NONE), // Fichier de sortie - CFG_INT("aggregate_timeout", DEFAULT_AGGREGATE_TIMEOUT, CFGF_NONE), // Timeout d'agrégation (en millisecondes) - CFG_INT("keep_timeout", DEFAULT_KEEP_TIMEOUT, CFGF_NONE), // Temps que l'on conserve les données dans la liste (en millisecondes) - CFG_INT("check_interval", DEFAULT_CHECK_INTERVAL, CFGF_NONE), // Temps entre deux vérifications de la liste (en micro-secondes) - CFG_END() } ; - char *config_file ; // Nom du fichier de configuration - int opt ; // Retour de getopt - - - /* L'option -f sert à spécifier un fichier de configuration alternatif, - * on regarde en premier si elle est présente */ - do - opt = getopt(argc, argv, OPTIONS) ; - while (opt != 'f' && opt != -1) ; - if (opt == 'f') - { - config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ; - strcpy(config_file, optarg) ; - } - else // Si -f n'est pas présente, on utilise le fichier de config par défaut - { - config_file = malloc((strlen(DEFAULT_CONFIG_FILE) + 1) * sizeof(char)) ; - strcpy(config_file, DEFAULT_CONFIG_FILE) ; - } - - /* Lecture du fichier de configuration */ - cfg = cfg_init(opts, CFGF_NONE) ; // Initialisation des options - if (cfg_parse(cfg, config_file) == CFG_PARSE_ERROR) - { - free(config_file) ; - return ERR_PARSING_CONFIG_FILE ; - } - free(config_file) ; - - /* Lecture des arguments de la ligne de commandes */ - optind = 1 ; // On reprend l'analyse des arguments au début - while ((opt = getopt(argc, argv, OPTIONS)) != -1) - { - switch (opt) - { - case 'a' : - cfg_setint(cfg, "aggregate_timeout", strtol(optarg, NULL, 0)) ; - break ; - case 'c' : - cfg_setint(cfg, "check_interval", strtol(optarg, NULL, 0)) ; - break ; - case 'f' : // Fichier de configuration - // Déjà traité. - break ; - case 'i' : - cfg_setstr(cfg, "positioner_ip", optarg) ; - break ; - case 'k' : - cfg_setint(cfg, "keep_timeout", strtol(optarg, NULL, 0)) ; - break ; - case 'l' : - cfg_setint(cfg, "listening_port", strtol(optarg, NULL, 0)) ; - break ; - case 'o' : - cfg_setstr(cfg, "output_file", optarg) ; - break ; - case 'p' : - cfg_setint(cfg, "positioner_port", strtol(optarg, NULL, 0)) ; - break ; - default : - print_usage(argv[0]) ; - return ERR_BAD_USAGE ; - } - } - - /* Vérification des arguments */ - // output_file // - if (cfg_getstr(cfg, "output_file")[0] == '\0') - { - fprintf(stderr, "Erreur ! Vous devez spécifier un fichier de sortie.\n") ; - print_usage(argv[0]) ; - return ERR_BAD_USAGE ; - } - // positioner_ip // - if (cfg_getstr(cfg, "positioner_ip")[0] == '\0') - { - fprintf(stderr, "Erreur ! Vous devez spécifier l'adresse IP du serveur de géolocalisation.\n") ; - print_usage(argv[0]) ; - return ERR_BAD_USAGE ; - } - // aggregate_timeout // - if (cfg_getint(cfg, "aggregate_timeout") < 0) - { -#ifdef DEBUG - fprintf(stderr, "Attention ! aggregate_timeout n'admet pas de valeur négative : application de la valeur par défaut.\n") ; -#endif // DEBUG - cfg_setint(cfg, "aggregate_timeout", DEFAULT_AGGREGATE_TIMEOUT) ; - } - // keep_timeout // - if (cfg_getint(cfg, "keep_timeout") < 0) - { -#ifdef DEBUG - fprintf(stderr, "Attention ! keep_timeout n'admet pas de valeur négative : application de la valeur par défaut.\n") ; -#endif // DEBUG - cfg_setint(cfg, "keep_timeout", DEFAULT_KEEP_TIMEOUT) ; - } - // check_interval // - if (cfg_getint(cfg, "check_interval") < 0) - { -#ifdef DEBUG - fprintf(stderr, "Attention ! check_interval n'admet pas de valeur négative : application de la valeur par défaut.\n") ; -#endif // DEBUG - cfg_setint(cfg, "check_interval", DEFAULT_CHECK_INTERVAL) ; - } - -#ifdef DEBUG - /* Affichage de la configuration */ - fprintf(stderr, "Configuration :\n") ; - cfg_print(cfg, stderr) ; -#endif // DEBUG - - run = TRUE ; + program_name = argv[0] ; + initialise_configuration(argc, argv) ; /* Mise en place des gestionnaires de signaux */ sigemptyset(&action.sa_mask) ; @@ -182,7 +40,188 @@ int main(int argc, char **argv) /* Création du thread */ pthread_create(&thread, NULL, (void *) &monitor_couple_list, &couples) ; - /* Lecture sur la socket */ + run = TRUE ; + ret = read_loop(sockfd) ; + + (void) close(sockfd) ; // Fermeture de la socket + free_couple_list(&couples) ; // Nettoyage de la liste + cfg_free(cfg) ; // Nettoyage de la configuration + + printf("%s : fin.\n", argv[0]) ; + return ret ; +} + + + +void initialise_configuration(int argc, char **argv) +{ + parse_config_file(argc, argv) ; + parse_command_line(argc, argv) ; + check_configuration() ; + +#ifdef DEBUG + /* Configuration printing */ + fprintf(stderr, "Configuration :\n") ; + cfg_print(cfg, stderr) ; +#endif // DEBUG +} + + +void parse_config_file(int argc, char **argv) +{ + // Config file options for confuse + cfg_opt_t opts[] = + { + CFG_INT("listening_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE), + + // Port and IP address of the localisation server: + CFG_INT("positioner_port", POSITIONER_DEFAULT_PORT, CFGF_NONE), + CFG_STR("positioner_ip", POSITIONER_DEFAULT_IP, CFGF_NONE), + + CFG_STR("output_file", "", CFGF_NONE), + + // Timeouts (in milliseconds): + CFG_INT("aggregate_timeout", DEFAULT_AGGREGATE_TIMEOUT, CFGF_NONE), + CFG_INT("keep_timeout", DEFAULT_KEEP_TIMEOUT, CFGF_NONE), + + // Time between two list checks (in microseconds): + CFG_INT("check_interval", DEFAULT_CHECK_INTERVAL, CFGF_NONE), + + CFG_END() + } ; + + char *config_file ; + + // Option -f specifies a config file, so we search for it first + int opt ; + do + opt = getopt(argc, argv, OPTIONS) ; + while (opt != 'f' && opt != -1) ; + if (opt == 'f') + { + config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ; + strcpy(config_file, optarg) ; + } + else // If -f isn't found, we use the default config file + { + config_file = malloc((strlen(DEFAULT_CONFIG_FILE) + 1) * sizeof(char)) ; + strcpy(config_file, DEFAULT_CONFIG_FILE) ; + } + + /* Parse config file */ + cfg = cfg_init(opts, CFGF_NONE) ; // Initialise options + if (cfg_parse(cfg, config_file) == CFG_PARSE_ERROR) + { + free(config_file) ; + exit(ERR_PARSING_CONFIG_FILE) ; + } + free(config_file) ; +} + + +void parse_command_line(int argc, char **argv) +{ + int opt ; + + optind = 1 ; // Rewind argument parsing + + while ((opt = getopt(argc, argv, OPTIONS)) != -1) + { + switch (opt) + { + case 'a' : + cfg_setint(cfg, "aggregate_timeout", strtol(optarg, NULL, 0)) ; + break ; + case 'c' : + cfg_setint(cfg, "check_interval", strtol(optarg, NULL, 0)) ; + break ; + case 'f' : // Config file + break ; // (already parsed) + case 'i' : + cfg_setstr(cfg, "positioner_ip", optarg) ; + break ; + case 'k' : + cfg_setint(cfg, "keep_timeout", strtol(optarg, NULL, 0)) ; + break ; + case 'l' : + cfg_setint(cfg, "listening_port", strtol(optarg, NULL, 0)) ; + break ; + case 'o' : + cfg_setstr(cfg, "output_file", optarg) ; + break ; + case 'p' : + cfg_setint(cfg, "positioner_port", strtol(optarg, NULL, 0)) ; + break ; + default : + print_usage() ; + exit(ERR_BAD_USAGE) ; + } + } +} + + +void check_configuration() +{ + // output_file // + if (cfg_getstr(cfg, "output_file")[0] == '\0') + { + fprintf(stderr, "Error! You must specify an output file.\n") ; + print_usage() ; + exit(ERR_BAD_USAGE) ; + } + + // positioner_ip // + if (cfg_getstr(cfg, "positioner_ip")[0] == '\0') + { + fprintf(stderr, "Error! You must specify the IP address of the" + " localisation server.\n") ; + print_usage() ; + exit(ERR_BAD_USAGE) ; + } + + // aggregate_timeout // + if (cfg_getint(cfg, "aggregate_timeout") < 0) + { +#ifdef DEBUG + fprintf(stderr, "Warning! aggregate_timeout cannot be negative:" + " failing back to default value.\n") ; +#endif // DEBUG + cfg_setint(cfg, "aggregate_timeout", DEFAULT_AGGREGATE_TIMEOUT) ; + } + + // keep_timeout // + if (cfg_getint(cfg, "keep_timeout") < 0) + { +#ifdef DEBUG + fprintf(stderr, "Warning! keep_timeout cannot be negative:" + " failing back to default value.\n") ; +#endif // DEBUG + cfg_setint(cfg, "keep_timeout", DEFAULT_KEEP_TIMEOUT) ; + } + + // check_interval // + if (cfg_getint(cfg, "check_interval") < 0) + { +#ifdef DEBUG + fprintf(stderr, "Warning! check_interval cannot be negative:" + " failing back to default value.\n") ; +#endif // DEBUG + cfg_setint(cfg, "check_interval", DEFAULT_CHECK_INTERVAL) ; + } +} + + + +int read_loop(int sockfd) +{ + int ret = 0 ; // Return value + int nread ; // Retour de recvfrom + struct sockaddr_in client; // Structure pour le client UDP + socklen_t client_len = sizeof(client) ; // Taille du client pour la socket + couple_message message ; // Message lu sur la socket + char *ap_mac_string, *mobile_mac_string ; // Pointeurs pour retour de mac_bytes_to_string() + char *mobile_ip_string ; + while (run) { nread = recvfrom(sockfd, &message, sizeof(message), 0, (struct sockaddr *) &client, &client_len) ; @@ -230,17 +269,11 @@ int main(int argc, char **argv) got_couple_info(&couples, message) ; } - (void) close(sockfd) ; // Fermeture de la socket - free_couple_list(&couples) ; // Nettoyage de la liste - cfg_free(cfg) ; // Nettoyage de la configuration - - printf("%s : fin.\n", argv[0]) ; return ret ; } - /* Fonction du thread, qui surveille la liste et envoie les infos au serveur de localisation au bout du timeout */ void* monitor_couple_list(couple_list **couples) { @@ -556,8 +589,32 @@ void print_couple_info(couple_info_list *info) +char* ip_bytes_to_string(unsigned char *ip_binary) +{ + int + taille = 16, + i = 0 ; + + for (i = 0 ; i < 4 ; ++i) + { + if (ip_binary[i] < 0x64) + taille-- ; + if (ip_binary[i] < 0x10) + taille-- ; + } + + char *ret = malloc(sizeof(char) * taille) ; + + sprintf(ret, "%d.%d.%d.%d", ip_binary[0], ip_binary[1], ip_binary[2], ip_binary[3]) ; + ret[taille-1] = '\0' ; + + return ret ; +} + + + /* Affiche le mode d'emploi du programme */ -void print_usage(char *prog) +void print_usage() { printf("Usage :\n\ \t%s [-f config_file] [-l listening_port] [-i positionner_ip] [-p positioner_port] [-a aggregate_timeout] [-k keep_timeout] [-c check_interval] [-o output_file]\n\ @@ -569,10 +626,10 @@ Options serveur :\n\ \t-p positioner_port : les demandes agrégées seront transmises sur ce port du serveur de calcul (défaut : %d).\n\ Options d'agrégation :\n\ \t-a aggregate_timeout : temps d'agrégation (défaut : %d millisecondes)\n\ -\t-a keep_timeout : temps de garde des demandes (défaut : %d millisecondes)\n\ -\t-a check_interval : délai entre deux vérifications des demandes en mémoire, et agrégation (défaut : %d micro-secondes)\n\ +\t-k keep_timeout : temps de garde des demandes (défaut : %d millisecondes)\n\ +\t-c check_interval : délai entre deux vérifications des demandes en mémoire, et agrégation (défaut : %d micro-secondes)\n\ ", - prog, + program_name, AGGREGATE_DEFAULT_PORT, POSITIONER_DEFAULT_IP, POSITIONER_DEFAULT_PORT,