[done] ctrlTerm plane update procedure (v0.1) to be tested by SdS
This commit is contained in:
parent
e8e65f81fb
commit
1a98172fca
|
@ -34,8 +34,9 @@ int main(int argc, char* argv[]){
|
|||
/* [0] Initialisation des variables
|
||||
=========================================================*/
|
||||
/* 1. Variables globales */
|
||||
sgca.n = 0;
|
||||
sgca.data = (struct plane*) malloc( sizeof(struct plane) );
|
||||
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);
|
||||
|
||||
|
||||
|
@ -273,8 +280,8 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){
|
|||
if( arg->middleware != NULL ){
|
||||
|
||||
/* 1. Construction des arguments */
|
||||
marg.listenSock = SOCKET;
|
||||
marg.comSock = &CLIENT_SOCKET;
|
||||
marg.listenSock = SOCKET;
|
||||
marg.comSock = &CLIENT_SOCKET;
|
||||
strcpy(marg.entity, entity);
|
||||
|
||||
/* 2. Exécution middleware */
|
||||
|
@ -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;
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
struct plane* data; // buffer tes données avion
|
||||
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{
|
||||
|
|
|
@ -37,10 +37,10 @@ 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
|
||||
int SOCKET; // Copie de la socket (évite les conflits de références)
|
||||
int read, i, index, pindex; // compteurs
|
||||
char buffer[MAX_BUF_LEN]; // buffer
|
||||
struct plane data; // données de l'avion
|
||||
int SOCKET; // Copie de la socket (évite les conflits de références)
|
||||
|
||||
|
||||
/* 2. On récupère les arguments */
|
||||
|
@ -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,67 +104,40 @@ 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 */
|
||||
for( i = 0 ; i < arg->sgca->n ; i++ ){
|
||||
/* 2. On regarde si l'avion existe */
|
||||
for( i = 0 ; i < arg->sgca->n ; i++ ){
|
||||
|
||||
// Si l'avion existe -> on passe à la suite
|
||||
if( strcmp(arg->sgca->data[i].code, data.code) == 0 ){
|
||||
pindex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// 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 ){
|
||||
/* 3. Création si n'existe pas */
|
||||
if( pindex <= -1 ){
|
||||
|
||||
// On ajoute une entrée à data
|
||||
pindex = arg->sgca->n;
|
||||
// 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->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;
|
||||
nb = arg->sgca->n;
|
||||
request.n = 0; // nombre d'avions online
|
||||
response.flags = TERMREQ_FBK;
|
||||
nb = arg->sgca->n;
|
||||
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
|
||||
socklen_t len;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
=========================================================*/
|
||||
|
|
|
@ -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
|
||||
=========================================================*/
|
||||
|
|
|
@ -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
|
||||
=========================================================*/
|
||||
|
|
|
@ -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
|
||||
=========================================================*/
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
*
|
||||
* ==IN==
|
||||
* @pAddr<const in_addr_t> Adresse du serveur TCP
|
||||
* @pPort<const int> Port 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
|
|
@ -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;
|
||||
}
|
||||
|
|
140
plane/plane.c
140
plane/plane.c
|
@ -18,8 +18,8 @@ char numero_vol[6];
|
|||
struct coord crd;
|
||||
struct control ctrl;
|
||||
|
||||
int mcast_socket = -1;
|
||||
int commu_socket = -1;
|
||||
int mcast_socket = -1;
|
||||
int commu_socket = -1;
|
||||
char buffer[MAX_BUF_LEN] = {0};
|
||||
struct sockaddr_in sgca;
|
||||
|
||||
|
@ -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))
|
||||
ctrl.cap = cap;
|
||||
|
||||
|
||||
|
||||
|
||||
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){
|
||||
if (alt < 0)
|
||||
crd.z = 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue