2017-03-28 16:45:18 +00:00
# include "central-manager.h"
2017-04-01 15:01:36 +00:00
/*
*
* @ argv : { 0 : program name }
*
* @ history
2017-04-07 18:25:53 +00:00
* [ 0 ] Initialisation des variables globales
2017-04-03 16:04:57 +00:00
* [ 1 ] Lancement des THREADS d ' é coute
* 1. On démarre le SERVEUR TCP d ' é coute globale
* 2. On démarre le SERVEUR UDP d ' é coute globale
* [ 2 ] On attends la fin de tous les THREADS
2017-04-07 18:25:53 +00:00
* [ 3 ] On libère les variables globale
2017-04-01 15:01:36 +00:00
*
*/
int main ( int argc , char * argv [ ] ) {
2017-03-28 16:45:18 +00:00
2017-04-07 18:25:53 +00:00
printf ( " **** Execution tree structure \n " ) ;
printf ( " ** [procedureName] \n " ) ;
printf ( " ** {threadName} \n " ) ;
printf ( " ** [parent]{child}[subchild] Description \n \n \n " ) ;
printf ( " **** Execution tree \n " ) ;
2017-04-07 16:14:21 +00:00
2017-04-07 18:25:53 +00:00
/* [0] Initialisation des variables globales
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-08 16:20:17 +00:00
sgca_data = ( struct plane * ) malloc ( sizeof ( struct plane ) ) ;
sgca_update = ( struct plane * ) malloc ( sizeof ( struct plane ) ) ;
sgca_index . data = 0 ;
sgca_index . update = 0 ;
2017-03-28 16:45:18 +00:00
2017-04-09 14:06:31 +00:00
/* Variables locales */
struct listn_thrd_arg tcp_listn_arg = { SERV_HOST , TCP_LIST } ;
struct listn_thrd_arg udp_vterm_arg = { MCST_VTER , UDP_VTER } ;
struct listn_thrd_arg udp_cterm_arg = { MCST_CTER , UDP_CTER } ;
2017-04-01 15:01:36 +00:00
/* [1] Lancement des THREADS d'écoute
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* (1) Ecoute TCP */
2017-04-09 14:06:31 +00:00
pthread_create ( & listenManagers [ 0 ] , NULL , LISTEN_TCP , ( void * ) & tcp_listn_arg ) ;
2017-04-07 18:25:53 +00:00
if ( DEBUGMOD & THR ) printf ( " {tcp_listn} démarré \n " ) ;
2017-04-07 16:14:21 +00:00
/* (2) Ecoute UDP multicast */
2017-04-09 14:06:31 +00:00
// pthread_create(&listenManagers[1], NULL, LISTEN_UDP, (void*)(intptr_t) UDP_MCST);
// if( DEBUGMOD&THR ) printf("{udp_mcast} émarré\n\n");
2017-04-07 16:14:21 +00:00
/* (3) Ecoute UDP viewTerm */
2017-04-09 14:06:31 +00:00
pthread_create ( & listenManagers [ 2 ] , NULL , LISTEN_UDP , ( void * ) & udp_vterm_arg ) ;
2017-04-07 16:14:21 +00:00
if ( DEBUGMOD & THR ) printf ( " {udp_vterm} démarré \n " ) ;
2017-03-28 16:45:18 +00:00
2017-04-07 16:14:21 +00:00
/* (4) Ecoute UDP ctrlTerm */
2017-04-09 14:06:31 +00:00
pthread_create ( & listenManagers [ 3 ] , NULL , LISTEN_UDP , ( void * ) & udp_cterm_arg ) ;
2017-04-07 16:14:21 +00:00
if ( DEBUGMOD & THR ) printf ( " {udp_cterm} démarré \n " ) ;
2017-04-01 15:01:36 +00:00
/* [2] On attends la fin de tous les THREADS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-07 16:14:21 +00:00
for ( char i = 0 ; i < 4 ; i + + )
pthread_join ( listenManagers [ ( int ) i ] , NULL ) ;
2017-04-01 15:01:36 +00:00
2017-04-07 18:25:53 +00:00
/* [3] On libère les variables globales
2017-04-01 15:01:36 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-08 16:20:17 +00:00
free ( sgca_data ) ;
free ( sgca_update ) ;
2017-04-01 15:01:36 +00:00
}
2017-04-03 16:04:57 +00:00
2017-04-01 15:01:36 +00:00
/* Attente de connection TCP
2017-03-28 16:45:18 +00:00
*
* @ history
* [ 0 ] Initialisation des variables
2017-04-01 15:01:36 +00:00
* [ 1 ] On démarre le SERVEUR TCP d ' é coute globale
* [ 2 ] Attente d ' une demande de connection TCP - > création d ' un THREAD
2017-03-28 16:45:18 +00:00
* [ 3 ] On attends la fin de tous les THREADS
2017-04-01 15:01:36 +00:00
* [ 4 ] On ferme la SOCKET d ' é coute TCP globale
*
2017-03-28 16:45:18 +00:00
*/
2017-04-09 14:06:31 +00:00
void * LISTEN_TCP ( void * THREADABLE_ARG ) {
2017-03-28 16:45:18 +00:00
/* [0] Initialisation des variables
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-09 14:06:31 +00:00
int CLIENT_SOCKET ; // contiendra la socket TCP à envoyer sur un THREAD
struct sockaddr_in clientInfo ; // contiendra les infos client
socklen_t len ; // taille de la socket
int index , i ; // compteurs
struct listn_thrd_arg * arg = THREADABLE_ARG ; // Addr + Port serveur
2017-04-07 18:25:53 +00:00
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
// retour de @DROP_TCP_SERVER
int LISTENSOCK ; // contiendra la socket d'écoute TCP
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* [1] On démarre le SERVEUR TCP d'écoute globale
2017-03-28 16:45:18 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-09 14:06:31 +00:00
if ( DROP_TCP_SERVER ( arg - > port , & LISTENSOCK ) < 0 ) {
2017-04-01 15:01:36 +00:00
2017-04-07 18:25:53 +00:00
if ( DEBUGMOD & SCK ) printf ( " {tcp_listn} Erreur création socket d'écoute \n " ) ;
2017-04-01 15:01:36 +00:00
// On ferme la SOCKET d'écoute globale
2017-04-07 18:25:53 +00:00
printf ( " {tcp_listn} FERMETURE SOCKET D'ECOUTE TCP! \n " ) ;
2017-04-01 15:01:36 +00:00
close ( LISTENSOCK ) ;
return NULL ;
}
2017-03-28 16:45:18 +00:00
2017-04-09 14:06:31 +00:00
printf ( " {tcp_listn} listen on %s:%d \n " , arg - > addr , arg - > port ) ;
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* [2] Attente d'une demande de connection, pour création d'un THREAD
2017-03-28 16:45:18 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
while ( 1 ) {
2017-04-01 15:01:36 +00:00
/* 1. On initialise les SOCKET en attendant la connexion et le rang du "manager" inactif */
CLIENT_SOCKET = - 1 ;
index = - 1 ;
/* 2. On attends une connection TCP */
CLIENT_SOCKET = accept ( LISTENSOCK , ( struct sockaddr * ) & clientInfo , & len ) ;
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* 3. Si erreur, on attend une nouvelle connection */
if ( CLIENT_SOCKET < 0 ) {
2017-04-07 18:25:53 +00:00
if ( DEBUGMOD & SCK ) printf ( " {tcp_listn} accept: Erreur connection \n " ) ;
2017-04-01 15:01:36 +00:00
break ;
}
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* 4. On cherche un "manager" libre (inactif) */
for ( i = 0 ; i < MAX_TCP_THR ; i + + )
if ( activeTCPManagers [ i ] = = 0 ) { index = i ; break ; }
2017-03-28 16:45:18 +00:00
// si on a trouvé un "manager" libre
if ( index ! = - 1 ) {
2017-04-01 15:01:36 +00:00
/* 5. On lance un thread pour le traitement de ce client */
pthread_create ( & TCPManagers [ index ] , NULL , managePlane , ( void * ) ( intptr_t ) CLIENT_SOCKET ) ;
2017-04-07 18:25:53 +00:00
if ( DEBUGMOD & THR ) printf ( " {tcp_listn}{com}(%d) démarré \n " , index ) ;
2017-04-01 15:01:36 +00:00
/* 6. On signale que ce "manager" est maintenant actif */
activeTCPManagers [ index ] = 1 ;
2017-03-28 16:45:18 +00:00
} else
2017-04-07 18:25:53 +00:00
if ( DEBUGMOD & THR ) printf ( " {tcp_listn} Aucun thread libre \n " ) ;
2017-04-01 15:01:36 +00:00
2017-03-28 16:45:18 +00:00
}
/* [3] On attends la fin de tous les THREADS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-01 15:01:36 +00:00
for ( i = 0 ; i < MAX_TCP_THR ; i + + )
pthread_join ( TCPManagers [ i ] , NULL ) ;
2017-04-07 16:14:21 +00:00
2017-03-28 16:45:18 +00:00
/* [4] On ferme la SOCKET d'écoute globale
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-07 18:25:53 +00:00
printf ( " {tcp_listn} FERMETURE SOCKET D'ECOUTE TCP! \n " ) ;
2017-03-28 16:45:18 +00:00
close ( LISTENSOCK ) ;
2017-04-01 15:01:36 +00:00
return NULL ;
2017-03-28 16:45:18 +00:00
}
2017-04-03 16:04:57 +00:00
2017-04-01 15:01:36 +00:00
/* Attente de connection UDP
*
* @ history
* [ 0 ] Initialisation des variables
* [ 1 ] On démarre le SERVEUR UDP d ' é coute globale
* [ 2 ] On attends un client
* [ 3 ] On gère la requête
2017-04-07 18:25:53 +00:00
* 1. On parse la requête
* 2. Si demande de socket de communication
* 1. Création socket port random
* 2. On récupère le port en question
* 3. On envoie la réponse
* [ 4 ] On envoie la réponse
* [ 5 ] On démarre un thread de gestion
* [ N ] On ferme la SOCKET d ' é coute globale
2017-04-01 15:01:36 +00:00
*
*/
2017-04-09 14:06:31 +00:00
void * LISTEN_UDP ( void * THREADABLE_ARG ) {
2017-04-01 15:01:36 +00:00
/* [0] Initialisation des variables
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-09 14:06:31 +00:00
int CLIENT_SOCKET ; // contiendra la socket UDP à envoyer sur un THREAD
struct sockaddr_in listenInfo ; // contiendra les infos de la socket LISTEN
struct sockaddr_in comInfo ; // contiendra les infos de la socket COM
struct sockaddr_in clientInfo ; // contiendra les infos client
socklen_t len ; // taille de la socket
int read ; // compteurs
char buffer [ MAX_BUF_LEN ] ; // buffer requête
struct bind_header request ; // requête parsée
int i , index ; // compteurs
struct listn_thrd_arg * arg = THREADABLE_ARG ; // Addr + Port serveur
char entity [ 9 + 1 ] ;
if ( strcmp ( arg - > addr , MCST_VTER ) = = 0 & & arg - > port = = UDP_VTER ) strcpy ( entity , " udp_vterm " ) ;
else strcpy ( entity , " udp_cterm " ) ;
2017-04-01 15:01:36 +00:00
// retour de @DROP_UDP_SERVER
int SOCKET ;
2017-04-07 18:25:53 +00:00
2017-04-01 15:01:36 +00:00
/* [1] On démarre le SERVEUR UDP d'écoute globale
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-09 14:06:31 +00:00
if ( DROP_UDP_SERVER ( arg - > addr , arg - > port , & SOCKET , & listenInfo , strcmp ( arg - > addr , SERV_HOST ) ! = 0 ) < 0 ) {
2017-04-01 15:01:36 +00:00
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & SCK ) printf ( " {%s} Erreur de création socket d'écoute \n " , entity ) ;
2017-04-01 15:01:36 +00:00
// On ferme la SOCKET d'écoute globale
2017-04-09 14:06:31 +00:00
printf ( " {%s} FERMETURE SOCKET D'ECOUTE UDP! \n " , entity ) ;
2017-04-01 15:01:36 +00:00
close ( SOCKET ) ;
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
return NULL ;
}
2017-03-28 16:45:18 +00:00
2017-04-09 14:06:31 +00:00
printf ( " {%s} listen on %s:%d \n " , entity , arg - > addr , arg - > port ) ;
2017-04-01 15:01:36 +00:00
/* [2] Attente de connection
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
while ( 1 ) {
2017-03-28 16:45:18 +00:00
2017-04-06 18:08:45 +00:00
/* 0. On initialise les SOCKET en attendant la connexion d'un client */
2017-04-06 11:36:51 +00:00
CLIENT_SOCKET = - 1 ;
index = - 1 ;
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* 1. On attends une connection UDP */
2017-04-07 16:14:21 +00:00
len = sizeof ( struct sockaddr_in ) ;
2017-04-06 11:36:51 +00:00
read = recvfrom ( SOCKET , buffer , MAX_BUF_LEN , 0 , ( struct sockaddr * ) & clientInfo , & len ) ;
2017-03-28 16:45:18 +00:00
2017-04-06 18:08:45 +00:00
/* 2. Si erreur reception ou taille incorrecte -> retour à l'écoute */
2017-04-07 16:14:21 +00:00
if ( read < BINDHDR_LEN ) {
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & BUF ) printf ( " {%s} read('%s') = %d bytes (expected: %d) \n " , entity , buffer , read , ( int ) ( BINDHDR_LEN ) ) ;
2017-04-06 15:41:34 +00:00
continue ;
2017-04-01 15:01:36 +00:00
}
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* 3. On récupère l'adresse IP du client */
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & SCK ) printf ( " {%s} '%s' connecté \n " , entity , inet_ntoa ( clientInfo . sin_addr ) ) ;
2017-04-01 15:01:36 +00:00
2017-04-07 18:25:53 +00:00
/* [3] Gestion de la requête
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. On parse la requête */
2017-04-09 14:06:31 +00:00
memcpy ( & request . flags , buffer , sizeof ( char ) ) ;
memcpy ( & request . addr , buffer + sizeof ( char ) , sizeof ( char ) * 15 ) ;
memcpy ( & request . port , buffer + sizeof ( char ) * 16 , sizeof ( unsigned short ) ) ;
printf ( " {%s} received: bind_header{flag = %d; addr = '%s'; port = %d} \n " , entity , ( int ) request . flags , request . addr , request . port ) ;
2017-04-06 15:41:34 +00:00
2017-04-07 18:25:53 +00:00
/* 2. Si on veut un port de communicatin */
2017-04-09 14:06:31 +00:00
if ( request . flags & BINDHEAD_SCK ) {
2017-04-06 15:41:34 +00:00
2017-04-07 18:25:53 +00:00
/* 2.1 On bind une socket sur un port random */
2017-04-09 14:06:31 +00:00
if ( DROP_UDP_SERVER ( SERV_HOST , 0 , & CLIENT_SOCKET , & comInfo , 0 ) < 0 ) {
2017-04-06 15:41:34 +00:00
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & SCK ) printf ( " {%s} Erreur de création de la socket COM \n " , entity ) ;
2017-04-06 15:41:34 +00:00
// On ferme la SOCKET CLIENT
close ( CLIENT_SOCKET ) ;
// On retire le flags PORT pour dire qu'on a pas pu ouvrir une socket de comm.
2017-04-09 14:06:31 +00:00
request . flags - = BINDHEAD_SCK ;
2017-04-06 15:41:34 +00:00
}
}
2017-04-07 18:25:53 +00:00
/* 2.2 Si on veut on port de communication */
2017-04-09 14:06:31 +00:00
if ( request . flags & BINDHEAD_SCK ) {
2017-04-06 15:41:34 +00:00
/* On récupère le port de la socket de communication */
len = sizeof ( struct sockaddr_in ) ;
2017-04-07 16:14:21 +00:00
if ( getsockname ( CLIENT_SOCKET , ( struct sockaddr * ) & comInfo , & len ) < 0 ) {
2017-04-06 15:41:34 +00:00
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & SCK ) printf ( " {%s} Erreur de recherche du port COM ouvert \n " , entity ) ;
2017-04-06 15:41:34 +00:00
close ( CLIENT_SOCKET ) ;
// On retire le flags PORT pour dire qu'on a pas pu ouvrir une socket de comm.
2017-04-09 14:06:31 +00:00
request . flags - = BINDHEAD_SCK ;
2017-04-06 15:41:34 +00:00
// Si on a le port -> on le met dans la reponse
2017-04-06 18:08:45 +00:00
} else {
2017-04-09 14:06:31 +00:00
strcpy ( request . addr , SERV_HOST ) ;
2017-04-07 16:14:21 +00:00
request . port = htons ( comInfo . sin_port ) ;
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & SCK ) printf ( " {%s}{udp_com} socket opened on %s:%d \n " , entity , request . addr , request . port ) ;
2017-04-06 18:08:45 +00:00
}
2017-04-06 15:41:34 +00:00
}
2017-04-07 18:25:53 +00:00
/* [4] Envoi de la réponse
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-06 18:08:45 +00:00
bzero ( buffer , MAX_BUF_LEN ) ;
2017-04-09 14:06:31 +00:00
memcpy ( buffer , & request . flags , sizeof ( char ) ) ;
memcpy ( buffer + sizeof ( char ) , & request . addr , sizeof ( char ) * 15 ) ;
memcpy ( buffer + sizeof ( char ) * 16 , & request . port , sizeof ( unsigned short ) ) ;
2017-04-06 18:08:45 +00:00
2017-04-07 16:14:21 +00:00
len = sizeof ( struct sockaddr_in ) ;
if ( sendto ( SOCKET , buffer , BINDHDR_LEN / sizeof ( char ) + 1 , 0 , ( struct sockaddr * ) & clientInfo , len ) < 0 ) {
2017-04-09 14:06:31 +00:00
printf ( " {%s} Impossible de répondre au client! \n " , entity ) ;
2017-04-06 15:41:34 +00:00
continue ;
}
2017-04-09 14:06:31 +00:00
printf ( " {%s} sent: bind_header{flag = %d; addr = '%s'; port = %d} \n " , entity , ( int ) request . flags , request . addr , request . port ) ;
2017-04-06 11:36:51 +00:00
2017-04-01 15:01:36 +00:00
2017-04-06 11:36:51 +00:00
2017-04-07 18:25:53 +00:00
/* [5] On démarre la tache sur un thread dédié
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. On cherche un "manager" libre (inactif) */
2017-04-06 11:36:51 +00:00
for ( i = 0 ; i < MAX_UDP_THR ; i + + )
if ( activeUDPManagers [ i ] = = 0 ) { index = i ; break ; }
2017-04-07 18:25:53 +00:00
/* 2. si on a trouvé un "manager" libre */
2017-04-06 11:36:51 +00:00
if ( index ! = - 1 ) {
2017-04-07 18:25:53 +00:00
/* 2.1. On lance un thread pour le traitement de ce client */
2017-04-06 11:36:51 +00:00
pthread_create ( & UDPManagers [ index ] , NULL , manageTerminal , ( void * ) ( intptr_t ) CLIENT_SOCKET ) ;
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & THR ) printf ( " {%s}{udp_com}(%d) démarré \n " , entity , index ) ;
2017-04-06 11:36:51 +00:00
2017-04-07 18:25:53 +00:00
/* 2.2. On signale que ce "manager" est maintenant actif */
2017-04-06 11:36:51 +00:00
activeUDPManagers [ index ] = 1 ;
} else
2017-04-09 14:06:31 +00:00
if ( DEBUGMOD & THR ) printf ( " {%s} Aucun thread UDP libre! \n " , entity ) ;
2017-04-01 15:01:36 +00:00
}
/* [n] On ferme la SOCKET d'écoute globale
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-09 14:06:31 +00:00
printf ( " {%s} FERMETURE SOCKET D'ECOUTE UDP! \n " , entity ) ;
2017-04-01 15:01:36 +00:00
close ( SOCKET ) ;
return NULL ;
}
/* Gestion d'une connexion PLANE
2017-03-28 16:45:18 +00:00
*
* @ THREADABLE_SOCKET < void * > SOCKET de la connexion client
*
* @ history
* [ 1 ] Initialisation des variables
2017-04-07 18:25:53 +00:00
* @ loop
* ( 2 ) Attente de requête
* ( 3 ) Gestion de la requête
* ( 4 ) Envoi de la réponse
* [ 5 ] On libère la mémoire
* [ 6 ] Fermeture de la connection ( SOCKET )
2017-04-01 15:01:36 +00:00
* [ n ] Arrêt du THREAD
2017-04-07 18:25:53 +00:00
* 1. On met à jour " activeManagers "
* 2. On arrête le THREAD
2017-04-01 15:01:36 +00:00
*
2017-03-28 16:45:18 +00:00
*/
2017-04-01 15:01:36 +00:00
void * managePlane ( void * THREADABLE_SOCKET ) {
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* [1] Initialisation des variables
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-07 18:25:53 +00:00
/* 1. Variables utiles */
int read , i , index , pindex ; // compteurs
char buffer [ MAX_BUF_LEN ] ; // buffer
2017-04-08 16:20:17 +00:00
struct plane data ; // données de l'avion
2017-04-07 18:25:53 +00:00
/* 2. On récupère la socket */
2017-04-01 15:01:36 +00:00
int TCP_SOCKET = ( intptr_t ) THREADABLE_SOCKET ; // Socket client
2017-03-28 16:45:18 +00:00
2017-04-07 18:25:53 +00:00
/* 3. On récupère le rang du thread parmi les "managers" */
index = - 1 ;
for ( i = 0 ; i < MAX_TCP_THR ; i + + )
if ( TCPManagers [ i ] = = pthread_self ( ) ) { index = i ; break ; }
2017-03-28 16:45:18 +00:00
2017-04-08 16:20:17 +00:00
// Erreur de thread
if ( index = = - 1 ) {
if ( DEBUGMOD & THR ) printf ( " {tcp_com}(%d) Unknown thread index. Aborting \n " , index ) ;
pthread_exit ( NULL ) ;
}
2017-04-07 18:25:53 +00:00
while ( 1 ) {
/* (2) Récupération de la requête
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2017-04-01 15:01:36 +00:00
/* 1. On lit sur la socket */
2017-04-07 18:25:53 +00:00
read = recv ( TCP_SOCKET , buffer , MAX_BUF_LEN , 0 ) ;
2017-03-28 16:45:18 +00:00
2017-04-08 16:20:17 +00:00
/* 2.1. Si erreur reception (-1:erreur, 0:fermeture client propre) */
2017-04-08 16:30:41 +00:00
if ( read < = 0 ) {
2017-04-08 16:20:17 +00:00
if ( DEBUGMOD & BUF ) printf ( " {tcp_com}(%d) read: %d -> must exit thread \n " , index , read ) ;
break ;
}
/* 2.2. Si message trop court */
2017-04-07 18:25:53 +00:00
if ( read < PLANE_LEN ) {
if ( DEBUGMOD & BUF ) printf ( " {tcp_com}(%d) read: %d (expected: %d) \n " , index , read , ( int ) PLANE_LEN ) ;
continue ;
2017-04-01 15:01:36 +00:00
}
2017-03-28 16:45:18 +00:00
2017-04-08 16:20:17 +00:00
2017-04-07 18:25:53 +00:00
/* 3. On parse la requête*/
memcpy ( & data . code , buffer + sizeof ( char ) * 0 + sizeof ( int ) * 0 , sizeof ( char ) * 6 ) ;
memcpy ( & data . x , buffer + sizeof ( char ) * 6 + sizeof ( int ) * 0 , sizeof ( int ) ) ;
memcpy ( & data . y , buffer + sizeof ( char ) * 6 + sizeof ( int ) * 1 , sizeof ( int ) ) ;
memcpy ( & data . z , buffer + sizeof ( char ) * 6 + sizeof ( int ) * 2 , sizeof ( int ) ) ;
memcpy ( & data . spd , buffer + sizeof ( char ) * 6 + sizeof ( int ) * 4 , sizeof ( int ) ) ;
memcpy ( & data . cap , buffer + sizeof ( char ) * 6 + sizeof ( int ) * 3 , sizeof ( int ) ) ;
2017-04-08 16:20:17 +00:00
printf ( " {tcp_com}(%d) received: plane_req{code = '%s'; x = %d; y = %d; z = %d; cap = %d; spd = %d} \n " , index , data . code , data . x , data . y , data . z , data . cap , data . spd ) ;
2017-04-06 11:36:51 +00:00
2017-04-07 18:25:53 +00:00
/* (3) Gestion de la requête -> enregistrement
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
pindex = - 1 ;
2017-04-06 11:36:51 +00:00
2017-04-07 18:25:53 +00:00
/* 1. On regarde si l'avion existe */
2017-04-08 16:20:17 +00:00
for ( i = 0 ; i < sgca_index . data ; i + + ) {
2017-04-07 18:25:53 +00:00
2017-04-08 16:20:17 +00:00
pindex = sgca_index . data ;
2017-04-07 18:25:53 +00:00
// On ajoute une entrée à data
2017-04-08 16:20:17 +00:00
sgca_data = ( struct plane * ) realloc ( sgca_data , sizeof ( struct plane ) * sgca_index . data + 1 ) ;
sgca_index . data + + ;
2017-04-07 18:25:53 +00:00
}
/* 3. On met à jour les données*/
2017-04-08 16:20:17 +00:00
memcpy ( & sgca_data [ pindex ] , & data , sizeof ( struct plane ) ) ;
2017-04-07 18:25:53 +00:00
/* (4) Envoi de la réponse
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2017-04-08 16:20:17 +00:00
printf ( " send: %d \n " , ( int ) send ( TCP_SOCKET , " coucou \n " , 8 , 0 ) ) ;
2017-04-07 18:25:53 +00:00
}
/* [5] On libère la mémoire
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* [6] Fermeture de la connection (SOCKET)
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
printf ( " {tcp_com}(%d) Fermeture de la socket de communication! \n " , index ) ;
close ( TCP_SOCKET ) ;
2017-04-06 11:36:51 +00:00
/* [n] Arrêt du THREAD
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-07 18:25:53 +00:00
/* 1. On met à jour "activeManagers" */
2017-04-06 11:36:51 +00:00
if ( index ! = - 1 )
activeTCPManagers [ index ] = 0 ;
2017-04-07 18:25:53 +00:00
/* 2. On arrête le THREAD */
2017-04-08 16:20:17 +00:00
if ( DEBUGMOD & THR ) printf ( " {tcp_com}(%d) libéré \n " , index ) ;
2017-04-06 11:36:51 +00:00
pthread_exit ( NULL ) ;
}
/* Gestion d'une connexion TERMINAL
*
* @ THREADABLE_SOCKET < void * > SOCKET de la connexion client
*
* @ history
* [ 1 ] Initialisation des variables
* [ 2 ] Récupération de la requête
* [ 3 ] Traitement de la requête
* [ 4 ] Création de la réponse
* [ 5 ] Envoi de la réponse
* [ 6 ] On vide les buffers
* [ 7 ] Fermeture de la connection ( SOCKET )
* [ n ] Arrêt du THREAD
* 1. On récupère le rang dans les " managers "
* 2. On met à jour " activeManagers "
* 3. On arrête le THREAD
*
*/
void * manageTerminal ( void * THREADABLE_SOCKET ) {
/* [1] Initialisation des variables
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
int read ; // compteur
struct sockaddr_in clientInfo ;
socklen_t len ;
2017-04-06 15:41:34 +00:00
int UDP_SOCKET = ( intptr_t ) THREADABLE_SOCKET ; // Socket client
2017-04-06 11:36:51 +00:00
char request [ MAX_BUF_LEN ] ; // Requête
// char response[MAX_BUF_LEN]; // Réponse
do {
2017-04-07 16:14:21 +00:00
printf ( " {udp_x-term}{udp_com} waiting for terminal request \n " ) ;
2017-04-06 11:36:51 +00:00
/* [2] Récupération de la requête
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. On lit sur la socket */
2017-04-06 15:41:34 +00:00
len = sizeof ( struct sockaddr_in ) ;
read = recvfrom ( UDP_SOCKET , request , MAX_BUF_LEN , 0 , ( struct sockaddr * ) & clientInfo , & len ) ;
2017-04-06 11:36:51 +00:00
/* 2. Si erreur reception */
2017-04-07 16:14:21 +00:00
if ( DEBUGMOD & BUF ) printf ( " {udp_x-term}{udp_com} READ = %d \n " , read ) ;
2017-04-06 11:36:51 +00:00
2017-04-06 15:41:34 +00:00
if ( read < 0 )
continue ;
2017-04-03 16:04:57 +00:00
2017-04-06 15:41:34 +00:00
/* 3. On désérialise la requête*/
2017-04-07 16:14:21 +00:00
printf ( " {udp_x-term}{udp_com} TERMINAL Request(%d bytes) : '%s' \n " , read , request ) ;
2017-04-03 16:04:57 +00:00
2017-04-06 11:36:51 +00:00
/* [3] Gestion de la requête
2017-04-03 16:04:57 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-06 11:36:51 +00:00
2017-04-03 16:04:57 +00:00
2017-04-06 15:41:34 +00:00
/* [4] Envoi reponse
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
strcpy ( request + strlen ( request ) , " -bla \0 " ) ;
send ( UDP_SOCKET , request , strlen ( request ) , 0 ) ;
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
} while ( 0 ) ;
2017-03-28 16:45:18 +00:00
2017-04-01 15:01:36 +00:00
/* [n] Arrêt du THREAD
2017-03-28 16:45:18 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. On récupère le rang dans les "managers" */
int i , index = - 1 ;
2017-04-07 16:14:21 +00:00
for ( i = 0 ; i < MAX_UDP_THR ; i + + )
if ( UDPManagers [ i ] = = pthread_self ( ) ) { index = i ; break ; }
2017-03-28 16:45:18 +00:00
/* 2. On met à jour "activeManagers" */
if ( index ! = - 1 )
2017-04-07 16:14:21 +00:00
activeUDPManagers [ index ] = 0 ;
2017-03-28 16:45:18 +00:00
/* 3. On arrête le THREAD */
2017-04-07 16:14:21 +00:00
if ( DEBUGMOD & THR ) printf ( " {udp_x-term}{udp_com}(%d) libéré \n " , index ) ;
2017-03-28 16:45:18 +00:00
pthread_exit ( NULL ) ;
}
2017-04-07 16:14:21 +00:00