[done] ctrlTerm plane update procedure (v0.1) to be tested by SdS

This commit is contained in:
xdrm-brackets 2017-04-28 14:54:02 +02:00
parent e8e65f81fb
commit 1a98172fca
15 changed files with 446 additions and 204 deletions

View File

@ -36,6 +36,7 @@ int main(int argc, char* argv[]){
/* 1. Variables globales */
sgca.n = 0;
sgca.data = (struct plane*) malloc( sizeof(struct plane) );
sgca.socket = (int*) malloc( sizeof(int) );
struct in_addr* SERV_HOST;
/* 2. On récupère l'IP locale' */
@ -58,19 +59,19 @@ int main(int argc, char* argv[]){
=========================================================*/
/* (1) Ecoute TCP */
pthread_create(&listenManagers[0], NULL, LISTEN_TCP, (void*) &tcp_listn_arg);
if( DEBUGMOD&THR ) printf("{tcp_listn} démarré\n");
if( DEBUGMOD&THR ) printf("{tcp_listn} started\n");
/* (2) Ecoute UDP multicast */
pthread_create(&listenManagers[1], NULL, MCAST_PUBLISH, (void*) &udp_mcast_arg);
if( DEBUGMOD&THR ) printf("{udp_mcast} démarré\n");
if( DEBUGMOD&THR ) printf("{udp_mcast} started\n");
/* (3) Ecoute UDP viewTerm */
pthread_create(&listenManagers[2], NULL, LISTEN_UDP, (void*) &udp_vterm_arg);
if( DEBUGMOD&THR ) printf("{udp_vterm} démarré\n");
if( DEBUGMOD&THR ) printf("{udp_vterm} started\n");
/* (4) Ecoute UDP ctrlTerm */
pthread_create(&listenManagers[3], NULL, LISTEN_UDP, (void*) &udp_cterm_arg);
if( DEBUGMOD&THR ) printf("{udp_cterm} démarré\n");
if( DEBUGMOD&THR ) printf("{udp_cterm} started\n");
/* [2] On attends la fin de tous les THREADS
@ -82,6 +83,7 @@ int main(int argc, char* argv[]){
/* [3] On libère les variables globales
==========================================================*/
free(sgca.data);
free(sgca.socket);
return EXIT_SUCCESS;
}
@ -121,10 +123,10 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
==========================================================*/
if( DROP_TCP_SERVER(arg->port, &LISTENSOCK) < 0 ){
if( DEBUGMOD&SCK ) printf("{tcp_listn} Erreur création socket d'écoute\n");
if( DEBUGMOD&SCK ) printf("{tcp_listn} Error creating listener socket\n");
// On ferme la SOCKET d'écoute globale
printf("{tcp_listn} FERMETURE SOCKET D'ECOUTE TCP!\n");
printf("{tcp_listn} Closing listener socket!\n");
close(LISTENSOCK);
return NULL;
@ -154,7 +156,7 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
break;
}
if( DEBUGMOD&SCK ) printf("{tcp_listn} %s:%d connecté\n", inet_ntoa(clientInfo.sin_addr), ntohs(clientInfo.sin_port));
if( DEBUGMOD&SCK ) printf("{tcp_listn} %s:%d connected\n", inet_ntoa(clientInfo.sin_addr), ntohs(clientInfo.sin_port));
/* 4. On cherche un "manager" libre (inactif) */
for( i = 0 ; i < MAX_TCP_THR ; i++ )
@ -169,13 +171,13 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
/* 5. On lance un thread pour le traitement de ce client */
pthread_create(&TCPManagers[index], NULL, arg->handler, (void*) &thread_args);
if( DEBUGMOD&THR ) printf("{tcp_listn}{com}(%d) démarré\n", index);
if( DEBUGMOD&THR ) printf("{tcp_listn}{com}(%d) started\n", index);
/* 6. On signale que ce "manager" est maintenant actif */
activeTCPManagers[index] = 1;
}else
if( DEBUGMOD&THR ) printf("{tcp_listn} Aucun thread libre\n");
if( DEBUGMOD&THR ) printf("{tcp_listn} No available thread\n");
}
@ -188,7 +190,7 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
/* [4] On ferme la SOCKET d'écoute globale
==========================================================*/
printf("{tcp_listn} FERMETURE SOCKET D'ECOUTE TCP!\n");
printf("{tcp_listn} Closing listener socket\n");
close(LISTENSOCK);
return NULL;
@ -244,17 +246,22 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){
/* [1] On démarre le SERVEUR UDP d'écoute globale
==========================================================*/
/* 1. On crée la socket */
if( DROP_UDP_SERVER(arg->addr, arg->port, &SOCKET, &listenInfo, 1) < 0 ){
if( DEBUGMOD&SCK ) printf("{%s} Erreur de création socket d'écoute\n", entity);
if( DEBUGMOD&SCK ) printf("{%s} Error creating listener socket\n", entity);
// On ferme la SOCKET d'écoute globale
printf("{%s} FERMETURE SOCKET D'ECOUTE UDP!\n", entity);
printf("{%s} Closing listener socket!\n", entity);
close(SOCKET);
return NULL;
}
/* 2. On définit un timeout d'envoi */
setTimeout(SOCKET, SOCK_TIMEOUT, TIMEOUT_SEND);
if( DEBUGMOD&SCK ) printf("{%s} SEND timeout set to %d\n", entity, SOCK_TIMEOUT);
printf("{%s} listen on %s:%d\n", entity, inet_ntoa(ip), arg->port);
@ -315,13 +322,13 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){
/* 2.1. On lance un thread pour le traitement de ce client */
pthread_create(&UDPManagers[index], NULL, arg->handler, (void*) &thread_args);
if( DEBUGMOD&THR ) printf("{%s}{com}(%d) démarré\n", entity, index);
if( DEBUGMOD&THR ) printf("{%s}{com}(%d) started\n", entity, index);
/* 2.2. On signale que ce "manager" est maintenant actif */
activeUDPManagers[index] = 1;
}else
if( DEBUGMOD&THR ) printf("{%s} Aucun thread UDP libre!\n", entity);
if( DEBUGMOD&THR ) printf("{%s} No available thread\n", entity);
}
@ -329,7 +336,7 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){
/* [n] On ferme la SOCKET d'écoute globale
==========================================================*/
printf("{%s} FERMETURE SOCKET D'ECOUTE UDP!\n", entity);
printf("{%s} Closing listener socket\n", entity);
close(SOCKET);
return NULL;
@ -395,7 +402,7 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
struct in_addr* servip = GET_LOCAL_IP();
if( servip == NULL ){
printf("{udp_mcast} /!\\ Cannot fetch local ip address. Aborting!\n");// On ferme la SOCKET d'écoute globale
printf("{udp_mcast} FERMETURE SOCKET CLIENT UDP!\n");
printf("{udp_mcast} Closing publisher socket!\n");
close(SOCKET);
return NULL;
}
@ -421,7 +428,7 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
/* [4] On envoie les information de la socket TCP
=========================================================*/
if( sendto(SOCKET, buffer, BINDHDR_LEN / sizeof(char) + 1, 0, (struct sockaddr*) &targetInfo, sizeof(struct sockaddr_in)) < 0 ){
printf("{udp_mcast} Erreur d'envoi\n");
printf("{udp_mcast} Cannot publish credentials\n");
break;
}
@ -432,7 +439,7 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
/* [n] On ferme la SOCKET CLIENT UDP
==========================================================*/
printf("{udp_mcast} FERMETURE SOCKET CLIENT UDP!\n");
printf("{udp_mcast} Closing publisher socket\n");
close(SOCKET);
return NULL;

View File

@ -29,9 +29,18 @@
char online;
};
struct plane_update{
char flags;
int z;
int cap;
int spd;
char done;
};
#define TERMREQ_LEN ( sizeof(char)+PLANE_LEN )
struct term_req{
char flags;
struct plane udpate;
struct plane update;
};
struct term_res{

View File

@ -51,13 +51,15 @@
#define maxHostLen 64
#define maxPortLen 6
#define SOCK_TIMEOUT 3 // 3sec timeout (1+ temps refresh plane)
#define SOCK_TIMEOUT 4 // 4sec timeout (1+ temps refresh plane)
#define PUBL_TIMEOUT 2 // 2sec entre chaque publication sur multicast UDP (pour avions)
struct context{
unsigned int n; // nombre d'avions
int* socket; // sockets associées aux avions
struct plane* data; // buffer tes données avion
struct plane_update* request; // Stack des requêtes de modifications
};
struct middleware_arg{

View File

@ -61,6 +61,8 @@ void* managePlane(void* THREADABLE_ARGS){
}
pindex = -1; // on ne connait pas encore l'avion
while( 1 ){
/* (2) Récupération de la requête
@ -102,9 +104,10 @@ void* managePlane(void* THREADABLE_ARGS){
/* (3) Gestion de la requête -> enregistrement
---------------------------------------------------------*/
pindex = -1;
/* 1. On cherche le rang de l'avion si on l'a pas déja */
if( pindex <= -1 ){
/* 1. On regarde si l'avion existe */
/* 2. On regarde si l'avion existe */
for( i = 0 ; i < arg->sgca->n ; i++ ){
// Si l'avion existe -> on passe à la suite
@ -115,54 +118,26 @@ void* managePlane(void* THREADABLE_ARGS){
}
/* 2. Création si n'existe pas */
if( pindex == -1 ){
}
// On ajoute une entrée à data
/* 3. Création si n'existe pas */
if( pindex <= -1 ){
// On ajoute une entrée à data + socket
pindex = arg->sgca->n;
arg->sgca->n++;
arg->sgca->data = (struct plane*) realloc(arg->sgca->data, sizeof(struct plane)*arg->sgca->n + 1);
arg->sgca->socket = (int*) realloc(arg->sgca->socket, sizeof(struct plane)*arg->sgca->n + 1);
arg->sgca->socket[pindex] = SOCKET;
printf("{tcp_com}(%d) plane '%s' (#%d) created\n", index, data.code, pindex);
}
/* 3. On copie les constantes */
/* 4. On copie/met à jour les valeurs */
memcpy(&arg->sgca->data[pindex], &data, sizeof(struct plane));
if( DEBUGMOD&COM ) 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);
/* (4) On prépare la réponse
---------------------------------------------------------*/
/* 1. ACK data */
strcpy(data.code, arg->sgca->data[pindex].code);
data.x = htonl(arg->sgca->data[pindex].x);
data.y = htonl(arg->sgca->data[pindex].y);
data.z = htonl(arg->sgca->data[pindex].z);
data.cap = htonl(arg->sgca->data[pindex].cap);
data.spd = htonl(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
---------------------------------------------------------*/
read = send(SOCKET, buffer, PLANE_LEN/sizeof(char) + 1, 0);
}
@ -170,6 +145,7 @@ void* managePlane(void* THREADABLE_ARGS){
=========================================================*/
/* 1. On notifie le crash */
arg->sgca->data[pindex].online = 0;
arg->sgca->socket[pindex] = -1;
@ -182,7 +158,7 @@ void* managePlane(void* THREADABLE_ARGS){
/* [7] Fermeture de la connection (SOCKET)
=========================================================*/
printf("{tcp_com}(%d) Fermeture de la socket de communication!\n", index);
printf("{tcp_com}(%d) Closing communication socket\n", index);
close(SOCKET);
@ -194,7 +170,7 @@ void* managePlane(void* THREADABLE_ARGS){
arg->activeManagers[index] = 0;
/* 2. On arrête le THREAD */
if( DEBUGMOD&THR ) printf("{tcp_com}(%d) libéré\n", index);
if( DEBUGMOD&THR ) printf("{tcp_com}(%d) freed\n", index);
pthread_exit(NULL);
}
@ -233,7 +209,7 @@ void* manageViewTerm(void* THREADABLE_ARGS){
int count, last, sent, nb; // compteurs d'envoi
int i, index = -1; // Compteurs globaux
char buffer[MAX_BUF_LEN]; // Buffer d'envoi
struct term_res request; // Requête
struct term_res response; // Requête
/* 2. On récupère les arguments */
struct handler_arg* arg = THREADABLE_ARGS;
@ -242,7 +218,7 @@ void* manageViewTerm(void* THREADABLE_ARGS){
for( i = 0 ; i < MAX_UDP_THR ; i++ )
if( arg->managers[i] == pthread_self() ){ index = i; break; }
printf("{udp_vterm}{com}(%d) starting terminal routine\n", index);
printf("{udp_vterm}{com}(%d) starting terminal routine (rate: %d sec)\n", index, PUBL_TIMEOUT);
/* 4. Attente d'un client */
@ -252,32 +228,34 @@ void* manageViewTerm(void* THREADABLE_ARGS){
loop = 0;
}
if( loop ) printf("{udp_cterm}{com}(%d) Terminal connected\n", index);
while( loop ){
/* [2] Récupération des données
=========================================================*/
/* 1. On initialise les variables utiles */
request.flags = TERMREQ_FBK;
response.flags = TERMREQ_FBK;
nb = arg->sgca->n;
request.n = 0; // nombre d'avions online
response.n = 0; // nombre d'avions online
free(request.data);
request.data = malloc( nb * sizeof(struct plane) + 1 );
free(response.data);
response.data = malloc( nb * sizeof(struct plane) + 1 );
/* 2. On récupère la liste des avions (network byte order) */
for( i = 0 ; i < nb ; i++ ){
memcpy(&request.data[i].code, &arg->sgca->data[i].code, sizeof(char)*6);
request.data[i].x = htonl( arg->sgca->data[i].x );
request.data[i].y = htonl( arg->sgca->data[i].y );
request.data[i].z = htonl( arg->sgca->data[i].z );
request.data[i].cap = htonl( arg->sgca->data[i].cap );
request.data[i].spd = htonl( arg->sgca->data[i].spd );
request.data[i].online = arg->sgca->data[i].online;
memcpy(&response.data[i].code, &arg->sgca->data[i].code, sizeof(char)*6);
response.data[i].x = htonl( arg->sgca->data[i].x );
response.data[i].y = htonl( arg->sgca->data[i].y );
response.data[i].z = htonl( arg->sgca->data[i].z );
response.data[i].cap = htonl( arg->sgca->data[i].cap );
response.data[i].spd = htonl( arg->sgca->data[i].spd );
response.data[i].online = arg->sgca->data[i].online;
// Incrément du compte si online
request.n += request.data[i].online;
response.n += response.data[i].online;
}
@ -288,22 +266,22 @@ void* manageViewTerm(void* THREADABLE_ARGS){
bzero(buffer, MAX_BUF_LEN*sizeof(char));
/* 2. Copie des données globales */
count = 0; last = sizeof(char); memcpy(buffer+count, &request.flags, last);
count += last; last = sizeof(char); memcpy(buffer+count, &request.n, last);
count = 0; last = sizeof(char); memcpy(buffer+count, &response.flags, last);
count += last; last = sizeof(char); memcpy(buffer+count, &response.n, last);
/* 3. Copie des données des avions */
for( i = 0 ; i < nb ; i++ ){
// Ignore les avions offline
if( !request.data[i].online )
if( !response.data[i].online )
continue;
count += last; last = sizeof(char)*6; memcpy(buffer+count, &request.data[i].code, last);
count += last; last = sizeof(int); memcpy(buffer+count, &request.data[i].x, last);
count += last; last = sizeof(int); memcpy(buffer+count, &request.data[i].y, last);
count += last; last = sizeof(int); memcpy(buffer+count, &request.data[i].z, last);
count += last; last = sizeof(int); memcpy(buffer+count, &request.data[i].cap, last);
count += last; last = sizeof(int); memcpy(buffer+count, &request.data[i].spd, last);
count += last; last = sizeof(char)*6; memcpy(buffer+count, &response.data[i].code, last);
count += last; last = sizeof(int); memcpy(buffer+count, &response.data[i].x, last);
count += last; last = sizeof(int); memcpy(buffer+count, &response.data[i].y, last);
count += last; last = sizeof(int); memcpy(buffer+count, &response.data[i].z, last);
count += last; last = sizeof(int); memcpy(buffer+count, &response.data[i].cap, last);
count += last; last = sizeof(int); memcpy(buffer+count, &response.data[i].spd, last);
}
count += last;
@ -333,13 +311,16 @@ void* manageViewTerm(void* THREADABLE_ARGS){
/* [n] Arrêt du THREAD
============================================================================*/
/* 2. On met à jour "activeManagers" */
/* 1. On met à jour "activeManagers" */
if( index != -1 )
arg->activeManagers[index] = 0;
/* 2. On ferme la socket */
close(arg->socket);
/* 3. On arrête le THREAD */
if( DEBUGMOD&THR ) printf("{udp_vterm}{com}(%d) libéré\n", index);
if( DEBUGMOD&THR ) printf("{udp_vterm}{com}(%d) freed\n", index);
pthread_exit(NULL);
}
@ -372,60 +353,149 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){
/* [1] Initialisation des variables
=========================================================*/
int read; // compteur
/* 1. Initialisation des variables */
struct sockaddr_in clientInfo;
socklen_t len;
char request[MAX_BUF_LEN]; // Requête
// char response[MAX_BUF_LEN]; // Réponse
char loop = 1;
int count, last, sent, nb; // compteurs d'envoi
int i, index = -1; // Compteurs globaux
int pindex; // index of the current plane
char buffer[MAX_BUF_LEN]; // Buffer d'envoi
struct term_req request; // Requête
/* 2. On récupère les arguments */
struct handler_arg* arg = THREADABLE_ARGS;
/* 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; }
printf("{udp_cterm}{com}(%d) starting terminal routine (rate: %d sec)\n", index, PUBL_TIMEOUT);
/* 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_cterm}{com}(%d) No terminal detected, exiting\n", index);
loop = 0;
}
if( loop ) printf("{udp_cterm}{com}(%d) Terminal connected\n", index);
do{
while( loop ){
pindex = -1;
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);
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
count = recvfrom(arg->socket, buffer, 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 )
if( count < TERMREQ_LEN ){
if( DEBUGMOD&BUF ) printf("{udp_cterm}{com}(%d) Error receiving request\n", index);
continue;
}
/* 3. On désérialise la requête*/
printf("{udp_x-term}{udp_com} TERMINAL Request(%d bytes) : '%s'\n", read, request);
bzero(&request, sizeof(struct term_req));
count = 0; last = sizeof(char); memcpy(&request.flags, buffer+count, last );
count += last; last = sizeof(char)*6; memcpy(&request.update.code, buffer+count, last );
count += last; last = sizeof(int); memcpy(&request.update.x, buffer+count, last );
count += last; last = sizeof(int); memcpy(&request.update.y, buffer+count, last );
count += last; last = sizeof(int); memcpy(&request.update.z, buffer+count, last );
count += last; last = sizeof(int); memcpy(&request.update.cap, buffer+count, last );
count += last; last = sizeof(int); memcpy(&request.update.spd, buffer+count, last );
// indian-switch
request.update.cap = ntohl(request.update.cap);
request.update.spd = ntohl(request.update.spd);
printf("{udp_cterm}{com}(%d) { flags: %d; plane: #%s { z=%d; cap=%d; speed=%d} }\n", index, request.flags, request.update.code, request.update.z, request.update.cap, request.update.spd);
/* [3] Gestion de la requête
=========================================================*/
/* 1. On vérifie qu'il y a bien un update demandé */
if( !( request.flags&TERMREQ_ALT || request.flags&TERMREQ_CAP || request.flags&TERMREQ_SPD ) ){
printf("{udp_cterm}{com}(%d) No update requested, passing\n", index);
continue;
}
/* 2. On regarde si on trouve l'avion */
for( i = 0 ; i < arg->sgca->n ; i++ ){
// Si l'avion existe -> on passe à la suite
if( strcmp(arg->sgca->data[i].code, request.update.code) == 0 ){
pindex = i;
break;
}
}
/* 3. Si on a pas trouvé l'avion ou qu'il est déconnecté, on passe */
if( pindex <= -1 || arg->sgca->socket[pindex] <= -1 ){
printf("{udp_cterm}{com}(%d) Plane unknown or unreachable, passing\n", index);
continue;
}
/* 4. On transfère la requête à l'avion */
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
// indian-switch
request.update.z = htonl(request.update.z);
request.update.cap = htonl(request.update.cap);
request.update.spd = htonl(request.update.spd);
count = 0; last = sizeof(char); memcpy(buffer+count, &request.flags, last );
count += last; last = sizeof(int); memcpy(buffer+count, &request.update.z, last );
count += last; last = sizeof(int); memcpy(buffer+count, &request.update.cap, last );
count += last; last = sizeof(int); memcpy(buffer+count, &request.update.spd, last );
if( send(arg->sgca->socket[pindex], buffer, count/sizeof(char)+1, 0) <= 0 ){
printf("{udp_cterm}{com}(%d) Cannot send request to plane\n", index);
continue;
}
/* [4] Envoi reponse
/* [4] Gestion de la réponse de l'avion
=========================================================*/
strcpy(request+strlen(request), "-bla\0");
send(arg->socket, request, strlen(request), 0);
/* 1. Réception */
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
if( recv(arg->sgca->socket[pindex], buffer, MAX_BUF_LEN, 0) <= 0 ){
printf("{udp_cterm}{com}(%d) Cannot get response from plane\n", index);
continue;
}
/* 2. Gestion de la validation de l'update */
if( !(buffer[0]&TERMREQ_ALT) && request.flags&TERMREQ_ALT )
request.flags -= TERMREQ_ALT;
if( !(buffer[0]&TERMREQ_CAP) && request.flags&TERMREQ_CAP )
request.flags -= TERMREQ_CAP;
if( !(buffer[0]&TERMREQ_SPD) && request.flags&TERMREQ_SPD )
request.flags -= TERMREQ_SPD;
/* [5] Réponse au terminal
=========================================================*/
if( send(arg->socket, buffer, sizeof(char)*2, 0) < 0 )
printf("{udp_cterm}{com}(%d) Cannot answer to terminal\n", index);
}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" */
/* 1. On met à jour "activeManagers" */
if( index != -1 )
arg->activeManagers[index] = 0;
/* 2. On ferme la socket */
close(arg->socket);
/* 3. On arrête le THREAD */
if( DEBUGMOD&THR ) printf("{udp_x-term}{udp_com}(%d) libéré\n", index);
if( DEBUGMOD&THR ) printf("{udp_cterm}{com}(%d) freed\n", index);
pthread_exit(NULL);
}

View File

@ -55,7 +55,7 @@ int multicastTerminal(struct middleware_arg* arg){
memcpy(&request.port, buffer+sizeof(char)+sizeof(in_addr_t), sizeof(unsigned short));
request.addr = ntohl(request.addr);
ip.s_addr = request.addr;
printf("{%s} received: bind_header{flag = %d; addr = %x/'%s'; port = %d}\n", arg->entity, (int) request.flags, ntohl(request.addr), inet_ntoa(ip), request. port);
if( DEBUGMOD&COM ) printf("{%s} received: bind_header{flag = %d; addr = %x/'%s'; port = %d}\n", arg->entity, (int) request.flags, ntohl(request.addr), inet_ntoa(ip), request. port);
/* 2. Si mauvais flag (avion) */
if( request.flags&BINDHEAD_TCP || !(request.flags&BINDHEAD_UDP) ){
@ -86,13 +86,15 @@ int multicastTerminal(struct middleware_arg* arg){
/* 1. On bind une socket sur un port random */
if( DROP_UDP_SERVER(SERV_IP->s_addr, 0, arg->comSock, &comInfo, 0) < 0 ){
if( DEBUGMOD&SCK ) printf("{%s} Erreur de création de la socket COM\n", arg->entity);
if( DEBUGMOD&SCK ) printf("{%s} Cannot create COMmunication socket\n", arg->entity);
/* 2. On ferme la socket et enleve le FLAG pour dire qu'on a pas pu ouvrir le port */
close(*arg->comSock);
request.flags -= BINDHEAD_UDP;
}
/* 3. On définit un timeout (si aucune connection) */
setTimeout(*arg->comSock, SOCK_TIMEOUT, TIMEOUT_RECV|TIMEOUT_SEND);
/* (2) Récupération port random
@ -101,7 +103,7 @@ int multicastTerminal(struct middleware_arg* arg){
len = sizeof(struct sockaddr_in);
if( getsockname(*arg->comSock, (struct sockaddr*) &comInfo, &len) < 0 ){
if( DEBUGMOD&SCK ) printf("{%s} Erreur de recherche du port COM ouvert\n", arg->entity);
if( DEBUGMOD&SCK ) printf("{%s} Cannot find opened port from socket\n", arg->entity);
/* 2. On ferme la socket et enleve le FLAG pour dire qu'on a pas pu ouvrir le port */
close(*arg->comSock);
@ -127,11 +129,11 @@ int multicastTerminal(struct middleware_arg* arg){
/* 2. On envoie la réponse*/
len = sizeof(struct sockaddr_in);
if( sendto(arg->listenSock, buffer, BINDHDR_LEN/sizeof(char) + 1, 0, (struct sockaddr*) &clientInfo, len) < 0 ){
printf("{%s} Impossible de répondre au client!\n", arg->entity);
printf("{%s} Cannot answer to client\n", arg->entity);
return -2;
}
printf("{%s} sent: bind_header{flag = %d; addr = %x/'%s'; port = %d}\n", arg->entity, (int) request.flags, ntohl(request.addr), inet_ntoa(*SERV_IP), ntohs(request.port));
if( DEBUGMOD&COM ) printf("{%s} sent: bind_header{flag = %d; addr = %x/'%s'; port = %d}\n", arg->entity, (int) request.flags, ntohl(request.addr), inet_ntoa(*SERV_IP), ntohs(request.port));
return 0;

View File

@ -12,19 +12,6 @@
/* Retourne l'adresse IP du serveur (première interface excepté "lo")
*
* @history
* [0] Initialisation des variables
* [1] On récupère la liste des interfaces
* [2] Parcourt des interfaces
* 1. Si "lo" -> suivant
* 2. Si pas IPV4 -> suivant
* 3. Si ok, on retourne l'ip
* [3] Cas échéant -> aucun résultat (NULL)
*
*/
struct in_addr* GET_LOCAL_IP(){
/* [0] Initialisation des variables
=========================================================*/
@ -66,3 +53,46 @@ struct in_addr* GET_LOCAL_IP(){
freeifaddrs(list);
return NULL;
}
int setTimeout(int pSocket, const time_t pSec, char pFlags){
/* [1] Initialisation des variables
=========================================================*/
/* 1. Création de la variable */
struct timeval timeout;
/* 2. On définit le temps du timeout */
timeout.tv_sec = pSec;
timeout.tv_usec = 0;
/* [2] On applique à la socket
=========================================================*/
/* 1. Timeout de reception */
if( pFlags&TIMEOUT_RECV ){
if( setsockopt(pSocket, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(pSocket);
return -1;
}
}
/* 2. Timeout d'envoi */
if( pFlags&TIMEOUT_SEND ){
if( setsockopt(pSocket, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(pSocket);
return -1;
}
}
/* 3. Résultat de succès */
return 0;
}

View File

@ -15,7 +15,42 @@
#include <ifaddrs.h>
/* Retourne l'adresse IP du serveur (première interface excepté "lo")
*
* @history
* [0] Initialisation des variables
* [1] On récupère la liste des interfaces
* [2] Parcourt des interfaces
* 1. Si "lo" -> suivant
* 2. Si pas IPV4 -> suivant
* 3. Si ok, on retourne l'ip
* [3] Cas échéant -> aucun résultat (NULL)
*
*/
struct in_addr* GET_LOCAL_IP();
#define TIMEOUT_RECV 0x01
#define TIMEOUT_SEND 0x02
/* Définit un timeout pour une socket données
*
* @in
* pSocket<int> Socket à modifier
* pSec<const time_t> Valeur en seconde du timeout
* pFlags<char> Si RECV et/ou SEND
*
* @out
* -1 en cas d'échec
* 0 sinon
*
* @history
* [1] Initialisation des variables
* [2] On applique le timeout à la socket
*
*/
int setTimeout(int pSocket, const time_t pSec, char pFlags);
#endif

View File

@ -22,7 +22,6 @@ int DROP_TCP_SERVER(const int pPort, int* pListenSock){
=========================================================*/
static struct sockaddr_in addr; // contiendra les infos du serveur
int STATUS; // status
struct timeval timeout;
*pListenSock = -1;
@ -37,15 +36,6 @@ int DROP_TCP_SERVER(const int pPort, int* pListenSock){
/* 2. Gestion erreur */
if( *pListenSock < 0 ) return -1;
/* 3. Timeout */
timeout.tv_sec = SOCK_TIMEOUT;
timeout.tv_usec = 0;
if( setsockopt(*pListenSock, SOL_SOCKET, SO_RCVTIMEO|SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(*pListenSock);
return -1;
}
/* [2] On définit les infos de la socket
=========================================================*/

View File

@ -7,7 +7,6 @@ int UDP_SOCKET(int* pSocket, in_addr_t pAddr, const int pPort, struct sockaddr_i
/* [0] Initialisation des variables
=========================================================*/
*pSocket = -1;
struct timeval timeout;
/* [1] Création de la socket
@ -19,15 +18,6 @@ int UDP_SOCKET(int* pSocket, in_addr_t pAddr, const int pPort, struct sockaddr_i
if( *pSocket < 0 )
return -1;
/* 3. Timeout */
timeout.tv_sec = SOCK_TIMEOUT;
timeout.tv_usec = 0;
if( setsockopt(*pSocket, SOL_SOCKET, SO_RCVTIMEO|SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(*pSocket);
return -1;
}
/* [2] On définit les infos de la socket
=========================================================*/

View File

@ -20,7 +20,6 @@ int DROP_UDP_SERVER(in_addr_t pAddr, const int pPort, int* pListenSock, struct s
int STATUS; // status
struct ip_mreq mcastReq;
*pListenSock = -1;
struct timeval timeout;
struct in_addr tmp;
@ -34,15 +33,6 @@ int DROP_UDP_SERVER(in_addr_t pAddr, const int pPort, int* pListenSock, struct s
/* 2. Gestion erreur */
if( *pListenSock < 0 ) return -1;
/* 3. Timeout */
timeout.tv_sec = SOCK_TIMEOUT;
timeout.tv_usec = 0;
if( setsockopt(*pListenSock, SOL_SOCKET, SO_RCVTIMEO|SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(*pListenSock);
return -1;
}
/* [2] On définit les infos de la socket
=========================================================*/

View File

@ -10,10 +10,11 @@
#include "client.h"
int TCP_CONNECT(int* pSocket, const in_addr_t pAddr, const int pPort, struct sockaddr_in* pInfo){
int TCP_CONNECT(int* pSocket, const in_addr_t pAddr, const int pPort, const time_t pTimeout, struct sockaddr_in* pInfo){
/* [0] Initialisation des variables
=========================================================*/
struct timeval timeout;
*pSocket = -1;
@ -26,6 +27,16 @@ int TCP_CONNECT(int* pSocket, const in_addr_t pAddr, const int pPort, struct soc
if( *pSocket < 0 )
return -1;
/* 3. Gestion timeout */
timeout.tv_sec = pTimeout;
timeout.tv_usec = 0;
if( setsockopt(*pSocket, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(*pSocket);
return -1;
}
/* [2] On définit les infos de la socket
=========================================================*/

View File

@ -20,6 +20,7 @@
* ==IN==
* @pAddr<const in_addr_t> Adresse du serveur TCP
* @pPort<const int> Port du serveur TCP
* @pTimeout<const time_t> Timeout de réception
*
* ==OUT==
* @pSocket<int*> Pointeur sur le <int> à remplir => contiendra un pointeur sur la socket créée
@ -34,6 +35,6 @@
* [3] On se connecte au serveur
*
*/
int TCP_CONNECT(int* pSocket, const in_addr_t pAddr, const int pPort, struct sockaddr_in* pInfo);
int TCP_CONNECT(int* pSocket, const in_addr_t pAddr, const int pPort, const time_t pTimeout, struct sockaddr_in* pInfo);
#endif

View File

@ -35,7 +35,13 @@ int DROP_MULTICAST_SERVER(const char* pAddr, const int pPort, int* pListenSock,
timeout.tv_sec = SOCK_TIMEOUT;
timeout.tv_usec = 0;
if( setsockopt(*pListenSock, SOL_SOCKET, SO_RCVTIMEO|SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
if( setsockopt(*pListenSock, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(*pListenSock);
return -1;
}
if( setsockopt(*pListenSock, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
close(*pListenSock);
return -1;
}

View File

@ -70,7 +70,6 @@ int open_communication(){
memcpy(&request.port, buffer+sizeof(char)+sizeof(in_addr_t), sizeof(unsigned short) );
// on indian-switch
printf("received : %x\n", request.addr);
request.addr = ntohl(request.addr);
request.port = ntohs(request.port);
ip.s_addr = request.addr;
@ -83,7 +82,7 @@ int open_communication(){
// printf("* hex("); for( int i = 0 ; i < BINDHDR_LEN/sizeof(char) ; i++ ) printf("\\x%02X", buffer[i]); printf(")\n");
printf("* received bind_header{flags = %d; addr = %x/%s; port = %d;}\n\n", request.flags, request.addr, inet_ntoa(ip), request.port);
printf("* received bind_header{flags = %d; addr = %x/'%s'; port = %d;}\n\n", request.flags, request.addr, inet_ntoa(ip), request.port);
@ -96,7 +95,7 @@ int open_communication(){
/* (1) Création socket TCP + connection
---------------------------------------------------------*/
/* 1. Création socket TCP + connection serveur */
if( TCP_CONNECT(&commu_socket, request.addr, request.port, &sgca) < 0 )
if( TCP_CONNECT(&commu_socket, request.addr, request.port, PAUSE, &sgca) < 0 )
return 0;
return 1;
@ -105,11 +104,19 @@ int open_communication(){
void close_communication(){
// fonction à implémenter qui permet de fermer la communication
// avec le gestionnaire de vols
}
void send_data(){
/* [0] Initialisation des variables
@ -145,21 +152,11 @@ void send_data(){
read = send(commu_socket, buffer, PLANE_DATA_LEN/sizeof(char) + 1, 0);
if( read <= 0 ){
printf("Erreur d'envoi\n");
printf("Cannot send\n");
return;
}
// printf("* hex("); for( int i = 0 ; i < PLANE_DATA_LEN/sizeof(char) ; i++ ) printf("\\x%02X", buffer[i]); printf(")\n");
/* 4. Récupération réponse */
read = recv(commu_socket, buffer, MAX_BUF_LEN, 0);
if( read < 0 ){
printf("Erreur de réception\n");
return;
}
/* 5. Gestion mise à jour */
//TODO: update_cap etc avec flags
}
@ -168,6 +165,10 @@ void send_data(){
********************************/
// initialise aléatoirement les paramètres initiaux de l'plane
void init_plane(){
// initialisation aléatoire du compteur aléatoire
time_t seed;
@ -193,28 +194,61 @@ void init_plane(){
}
// modifie la valeur de l'plane avec la valeur passée en paramètre
void update_speed(int speed){
if (speed < 0) ctrl.speed = speed;
int update_speed(int speed){
if( speed < 0 )
return -1;
if( speed > VITMAX )
return -1;
ctrl.speed = speed;
return 0;
}
// modifie le cap de l'plane avec la valeur passée en paramètre
void update_cap(int cap){
if ((cap >= 0) && (cap < 360))
int update_cap(int cap){
if( cap < 0 || cap >= 360 )
return -1;
ctrl.cap = cap;
return 0;
}
// modifie l'z de l'plane avec la valeur passée en paramètre
void update_z(int alt){
int update_z(int alt){
if( alt < 0 )
return 01;
crd.z = alt;
return 0;
}
// affiche les caractéristiques courantes de l'plane
void display_data(){
printf("Avion %6s -> localisation : (%d,%d), altitude : %d, vitesse : %d, cap : %d\n", numero_vol, crd.x, crd.y, crd.z, ctrl.speed, ctrl.cap);
printf("| Plane %s |\n * position(%d,%d, %d)\n * speed: %d\n * cap: %d\n\n", numero_vol, crd.x, crd.y, crd.z, ctrl.speed, ctrl.cap);
}
// recalcule la localisation de l'plane en fonction de sa speed et de son cap
void calc_ctrl(){
float ctrl_x, ctrl_y;
@ -246,13 +280,66 @@ void calc_ctrl(){
}
// fonction principale : gère l'exécution de l'plane au fil du temps
void update(){
int received;
struct sgca_req request;
char buffer[MAX_BUF_LEN] = {0};
while( 1 ){
calc_ctrl();
send_data();
sleep(PAUSE);
/* [1] Gestion réception avec timeout
=========================================================*/
/* 1. Attente de message */
received = recv(commu_socket, buffer, MAX_BUF_LEN, 0);
/* 2. Si rien -> on reboucle */
if( received <= 0 || received < (sizeof(char)+3*sizeof(int)) )
continue;
/* [2] Gestion de requête de mise à jour
=========================================================*/
/* 1. On parse la requête */
memcpy(&request.flags, buffer, sizeof(char) );
memcpy(&request.z, buffer+sizeof(char), sizeof(int) );
memcpy(&request.cap, buffer+sizeof(char)+sizeof(int), sizeof(int) );
memcpy(&request.spd, buffer+sizeof(char)+sizeof(int)*2, sizeof(int) );
/* 2. On indian-switch */
request.z = ntohl(request.z);
request.cap = ntohl(request.cap);
request.spd = ntohl(request.spd);
printf("Request received { flags = %d; z = %d; cap = %d; speed = %d }\n", request.flags, request.z, request.cap, request.spd);
/* 3. On essaie de mettre à jour en fonction des flags */
if( request.flags&REQ_ALT )
if( update_z(request.z) == -1 )
request.flags -= REQ_ALT;
if( request.flags&REQ_SPD )
if( update_z(request.spd) == -1 )
request.flags -= REQ_SPD;
if( request.flags&REQ_CAP )
if( update_z(request.cap) == -1 )
request.flags -= REQ_CAP;
/* [3] Gestion de la réponse
=========================================================*/
/* 1. On prépare la réponse */
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
memcpy(buffer, &request.flags, sizeof(char));
/* 2. Envoi de la réponse */
send(commu_socket, buffer, sizeof(char)*2, 0);
}
@ -266,6 +353,7 @@ int main(){
// on quitte si on arrive à pas contacter le gestionnaire de vols
if( !open_communication() ){
printf("Cannot connect to SGCA.\n");
exit(1);
}

View File

@ -49,6 +49,17 @@
int spd;
};
#define REQ_CAP 0x02
#define REQ_SPD 0x04
#define REQ_ALT 0x08
struct sgca_req{
char flags;
int z;
int cap;
int spd;
};
#define BINDHDR_LEN ( sizeof(char)+sizeof(in_addr_t)+sizeof(unsigned short) )
#define BINDHEAD_UDP 0x01 // is terminal (ask for UDP socket)
#define BINDHEAD_TCP 0x02 // is plane (ask for TCP socket)