2017-04-09 17:33:27 +00:00
/**************************
* Handler Dependency *
* * * * * * * * * * * * * * * * * * * * * * * * * * *
* Designed & Developed by *
* Adrien Marquès *
* < xdrm - brackets > *
* * * * * * * * * * * * * * * * * * * * * * * * * * *
* doowap31 @ gmail . com *
* * * * * * * * * * * * * * * * * * * * * * * * * */
# include "handler.h"
/* Gestion d'une connexion PLANE
*
* @ THREADABLE_SOCKET < void * > SOCKET de la connexion client
*
* @ history
* [ 1 ] Initialisation des variables
* @ 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 )
* [ n ] Arrêt du THREAD
* 1. On met à jour " activeManagers "
* 2. On arrête le THREAD
*
*/
void * managePlane ( void * THREADABLE_ARGS ) {
/* [1] Initialisation des variables
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. Variables utiles */
int read , i , index , pindex ; // compteurs
char buffer [ MAX_BUF_LEN ] ; // buffer
struct plane data ; // données de l'avion
2017-04-20 09:49:11 +00:00
int SOCKET ; // Copie de la socket (évite les conflits de références)
2017-04-09 17:33:27 +00:00
/* 2. On récupère les arguments */
2017-04-11 17:12:34 +00:00
struct handler_arg * arg = THREADABLE_ARGS ;
2017-04-20 09:49:11 +00:00
memcpy ( & SOCKET , & arg - > socket , sizeof ( int ) ) ;
2017-04-18 08:21:10 +00:00
if ( DEBUGMOD & HDR ) printf ( " ===== managePlane(%p, %p, %d, %p) ===== \n " , ( void * ) arg - > managers , ( void * ) arg - > activeManagers , arg - > socket , ( void * ) arg - > sgca ) ;
2017-04-09 17:33:27 +00:00
2017-04-20 09:49:11 +00:00
2017-04-09 17:33:27 +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 ( arg - > managers [ i ] = = pthread_self ( ) ) { index = i ; break ; }
// Erreur de thread
if ( index = = - 1 ) {
if ( DEBUGMOD & THR ) printf ( " {tcp_com}(%d) Unknown thread index. Aborting \n " , index ) ;
pthread_exit ( NULL ) ;
}
while ( 1 ) {
/* (2) Récupération de la requête
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* 1. On lit sur la socket */
2017-04-20 09:49:11 +00:00
read = recv ( SOCKET , buffer , MAX_BUF_LEN , 0 ) ;
2017-04-09 17:33:27 +00:00
/* 2.1. Si erreur reception (-1:erreur, 0:fermeture client propre) */
if ( read < = 0 ) {
if ( DEBUGMOD & BUF ) printf ( " {tcp_com}(%d) read: %d -> must exit thread \n " , index , read ) ;
break ;
}
/* 2.2. Si message trop court */
if ( read < PLANE_LEN ) {
if ( DEBUGMOD & BUF ) printf ( " {tcp_com}(%d) read: %d (expected: %d) \n " , index , read , ( int ) PLANE_LEN ) ;
continue ;
}
/* 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 ) ) ;
/* (3) Gestion de la requête -> enregistrement
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
pindex = - 1 ;
/* 1. On regarde si l'avion existe */
for ( i = 0 ; i < arg - > sgca - > n ; i + + ) {
2017-04-12 08:32:48 +00:00
// Si l'avion existe -> on passe à la suite
if ( strcmp ( arg - > sgca - > data [ i ] . code , data . code ) = = 0 ) {
pindex = i ;
break ;
}
}
/* 2. Création si n'existe pas */
if ( pindex = = - 1 ) {
2017-04-09 17:33:27 +00:00
// On ajoute une entrée à data
2017-04-12 08:32:48 +00:00
pindex = arg - > sgca - > n ;
2017-04-09 17:33:27 +00:00
arg - > sgca - > n + + ;
2017-04-12 08:32:48 +00:00
arg - > sgca - > data = ( struct plane * ) realloc ( arg - > sgca - > data , sizeof ( struct plane ) * arg - > sgca - > n + 1 ) ;
printf ( " {tcp_com}(%d) plane '%s' (#%d) created \n " , index , data . code , pindex ) ;
2017-04-09 17:33:27 +00:00
}
2017-04-12 08:32:48 +00:00
/* 3. On copie les constantes */
2017-04-09 17:33:27 +00:00
memcpy ( & arg - > sgca - > data [ pindex ] , & data , sizeof ( struct plane ) ) ;
2017-04-12 08:32:48 +00:00
printf ( " {tcp_com}(%d) stored (%d)'%s': {x = %d; y = %d; z = %d; cap = %d; spd = %d} \n " , index , pindex , arg - > sgca - > data [ pindex ] . code , arg - > sgca - > data [ pindex ] . x , arg - > sgca - > data [ pindex ] . y , arg - > sgca - > data [ pindex ] . z , arg - > sgca - > data [ pindex ] . cap , arg - > sgca - > data [ pindex ] . spd ) ;
2017-04-09 17:33:27 +00:00
2017-04-12 08:32:48 +00:00
/* (4) On prépare la réponse
2017-04-09 17:33:27 +00:00
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2017-04-12 08:32:48 +00:00
/* 1. ACK data */
strcpy ( data . code , arg - > sgca - > data [ pindex ] . code ) ;
data . x = arg - > sgca - > data [ pindex ] . x ;
data . y = arg - > sgca - > data [ pindex ] . y ;
data . z = arg - > sgca - > data [ pindex ] . z ;
data . cap = arg - > sgca - > data [ pindex ] . cap ;
data . spd = arg - > sgca - > data [ pindex ] . spd ;
/* 2. Vérification du FLAG (modifications) si requêtes d'update */
//TODO: Gestion arg->sgca->update[pindex].flags|UPD_SPEED etc.. pour ajout du flag+elements dans reponse
/* 3. On sérialise la réponse */
bzero ( buffer , MAX_BUF_LEN * sizeof ( char ) ) ;
memcpy ( buffer + sizeof ( char ) * 0 + sizeof ( int ) * 0 , & data . code , sizeof ( char ) * 6 ) ;
memcpy ( buffer + sizeof ( char ) * 6 + sizeof ( int ) * 0 , & data . x , sizeof ( int ) ) ;
memcpy ( buffer + sizeof ( char ) * 6 + sizeof ( int ) * 1 , & data . y , sizeof ( int ) ) ;
memcpy ( buffer + sizeof ( char ) * 6 + sizeof ( int ) * 2 , & data . z , sizeof ( int ) ) ;
memcpy ( buffer + sizeof ( char ) * 6 + sizeof ( int ) * 4 , & data . spd , sizeof ( int ) ) ;
memcpy ( buffer + sizeof ( char ) * 6 + sizeof ( int ) * 3 , & data . cap , sizeof ( int ) ) ;
/* (5) Envoi de la réponse
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2017-04-20 09:49:11 +00:00
read = send ( SOCKET , buffer , PLANE_LEN / sizeof ( char ) + 1 , 0 ) ;
2017-04-09 17:33:27 +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 ) ;
2017-04-20 09:49:11 +00:00
close ( SOCKET ) ;
2017-04-09 17:33:27 +00:00
/* [n] Arrêt du THREAD
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. On met à jour "activeManagers" */
if ( index ! = - 1 )
arg - > activeManagers [ index ] = 0 ;
/* 2. On arrête le THREAD */
if ( DEBUGMOD & THR ) printf ( " {tcp_com}(%d) libéré \n " , index ) ;
pthread_exit ( NULL ) ;
}
/* Gestion d'une connexion TERMINAL
*
* @ THREADABLE_SOCKET < void * > SOCKET de la connexion client
*
* @ history
* [ 1 ] Initialisation des variables
2017-04-25 13:00:25 +00:00
*
* @ loop
* [ 2 ] Récupération des données
* [ 3 ] Construction de la requête
* [ 4 ] Envoi de la requête
* [ 5 ] Timeout
*
2017-04-09 17:33:27 +00:00
* [ 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 * manageViewTerm ( void * THREADABLE_ARGS ) {
/* [1] Initialisation des variables
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-25 13:00:25 +00:00
/* 1. Initialisation des variables */
2017-04-09 17:33:27 +00:00
struct sockaddr_in clientInfo ;
2017-04-25 13:00:25 +00:00
socklen_t len ;
char loop = 1 ;
int count , /*to_send, */ sent ; // compteurs d'envoi
int i , index = - 1 ; // Compteurs globaux
char buffer [ MAX_BUF_LEN ] ; // Buffer d'envoi
struct term_res request ; // Requête
2017-04-09 17:33:27 +00:00
/* 2. On récupère les arguments */
2017-04-11 17:12:34 +00:00
struct handler_arg * arg = THREADABLE_ARGS ;
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
/* 3. On récupère le rang dans les "managers" */
for ( i = 0 ; i < MAX_UDP_THR ; i + + )
if ( arg - > managers [ i ] = = pthread_self ( ) ) { index = i ; break ; }
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
printf ( " {udp_vterm}{com}(%d) starting terminal routine \n " , index ) ;
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
/* 4. Attente d'un client */
len = sizeof ( struct sockaddr_in ) ;
if ( recvfrom ( arg - > socket , buffer , MAX_BUF_LEN * sizeof ( char ) , 0 , ( struct sockaddr * ) & clientInfo , & len ) < 0 ) {
printf ( " {udp_vterm}{com}(%d) No terminal detected, exiting \n " , index ) ;
loop = 0 ;
}
while ( loop ) {
/* [2] Récupération des données
2017-04-09 17:33:27 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-25 13:00:25 +00:00
/* 1. On initialise les variables utiles */
request . flags = TERMREQ_FBK ;
request . n = arg - > sgca - > n ;
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
free ( request . data ) ;
request . data = malloc ( request . n * sizeof ( struct plane ) + 1 ) ;
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
/* 2. On récupère la liste des avions */
for ( i = 0 ; i < request . n ; i + + )
memcpy ( & request . data [ i ] , & arg - > sgca - > data [ i ] , sizeof ( struct plane ) ) ;
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
/* [3] Construction de la requête
2017-04-09 17:33:27 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-25 13:00:25 +00:00
/* 1. Initialisation du buffer */
bzero ( buffer , MAX_BUF_LEN * sizeof ( char ) ) ;
count = 0 ;
/* 2. Copie des données globales */
memcpy ( buffer + count , & request . flags , sizeof ( char ) ) ; count + = sizeof ( char ) ;
memcpy ( buffer + count , & request . n , sizeof ( char ) ) ; count + = sizeof ( char ) ;
/* 3. Copie des données des avions */
for ( i = 0 ; i < request . n ; i + + ) {
memcpy ( buffer + count , & request . data [ i ] . code , sizeof ( char ) * 6 ) ; count + = sizeof ( char ) * 6 ;
memcpy ( buffer + count , & request . data [ i ] . x , sizeof ( int ) ) ; count + = sizeof ( int ) ;
memcpy ( buffer + count , & request . data [ i ] . y , sizeof ( int ) ) ; count + = sizeof ( int ) ;
memcpy ( buffer + count , & request . data [ i ] . z , sizeof ( int ) ) ; count + = sizeof ( int ) ;
memcpy ( buffer + count , & request . data [ i ] . cap , sizeof ( int ) ) ; count + = sizeof ( int ) ;
memcpy ( buffer + count , & request . data [ i ] . spd , sizeof ( int ) ) ; count + = sizeof ( int ) ;
}
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
/* [4] Envoi de la requête
2017-04-09 17:33:27 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-04-25 13:00:25 +00:00
/* 1. Gestion de l'envoi en plusieurs requêtes */
/* 2. Envoi */
2017-04-09 17:33:27 +00:00
2017-04-25 13:00:25 +00:00
len = sizeof ( struct sockaddr_in ) ;
sent = sendto ( arg - > socket , buffer , count / sizeof ( char ) , 0 , ( struct sockaddr * ) & clientInfo , len ) ;
/* 3. Gestion erreur */
if ( sent < = 0 ) {
printf ( " {udp_vterm}{com}(%d) Unable to send data \n " , index ) ;
break ;
}
/* [5] Timeout
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
sleep ( PUBL_TIMEOUT ) ;
}
2017-04-09 17:33:27 +00:00
/* [n] Arrêt du THREAD
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 2. On met à jour "activeManagers" */
if ( index ! = - 1 )
arg - > activeManagers [ index ] = 0 ;
/* 3. On arrête le THREAD */
2017-04-25 13:00:25 +00:00
if ( DEBUGMOD & THR ) printf ( " {udp_vterm}{com}(%d) libéré \n " , index ) ;
2017-04-09 17:33:27 +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 * manageCtrlTerm ( void * THREADABLE_ARGS ) {
/* [1] Initialisation des variables
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
int read ; // compteur
struct sockaddr_in clientInfo ;
socklen_t len ;
char request [ MAX_BUF_LEN ] ; // Requête
// char response[MAX_BUF_LEN]; // Réponse
/* 2. On récupère les arguments */
2017-04-11 17:12:34 +00:00
struct handler_arg * arg = THREADABLE_ARGS ;
2017-04-09 17:33:27 +00:00
do {
printf ( " {udp_x-term}{udp_com} waiting for terminal request \n " ) ;
/* [2] Récupération de la requête
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. On lit sur la socket */
len = sizeof ( struct sockaddr_in ) ;
read = recvfrom ( arg - > socket , request , MAX_BUF_LEN , 0 , ( struct sockaddr * ) & clientInfo , & len ) ;
/* 2. Si erreur reception */
if ( DEBUGMOD & BUF ) printf ( " {udp_x-term}{udp_com} READ = %d \n " , read ) ;
if ( read < 0 )
continue ;
/* 3. On désérialise la requête*/
printf ( " {udp_x-term}{udp_com} TERMINAL Request(%d bytes) : '%s' \n " , read , request ) ;
/* [3] Gestion de la requête
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* [4] Envoi reponse
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
strcpy ( request + strlen ( request ) , " -bla \0 " ) ;
send ( arg - > socket , request , strlen ( request ) , 0 ) ;
} while ( 0 ) ;
/* [n] Arrêt du THREAD
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* 1. On récupère le rang dans les "managers" */
int i , index = - 1 ;
for ( i = 0 ; i < MAX_UDP_THR ; i + + )
if ( arg - > managers [ i ] = = pthread_self ( ) ) { index = i ; break ; }
/* 2. On met à jour "activeManagers" */
if ( index ! = - 1 )
arg - > activeManagers [ index ] = 0 ;
/* 3. On arrête le THREAD */
if ( DEBUGMOD & THR ) printf ( " {udp_x-term}{udp_com}(%d) libéré \n " , index ) ;
pthread_exit ( NULL ) ;
}