[Aggregator] Code refactoring (conf parsing, loop)
This commit is contained in:
parent
a955467c83
commit
1863bd9e9f
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue