From cc78418a531f525ef3f309a76f1c350031292540 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Fri, 28 Apr 2017 16:32:20 +0200 Subject: [PATCH] Now viewTerm has an "infinite" buffer and delegates the data/buffer creation from context to local function (next step: use it also for ctrlTerm) --- central-manager/lib/local/handler.c | 267 ++++++++++++++++------------ central-manager/lib/local/handler.h | 1 + 2 files changed, 159 insertions(+), 109 deletions(-) diff --git a/central-manager/lib/local/handler.c b/central-manager/lib/local/handler.c index 64f3a95..98e206f 100644 --- a/central-manager/lib/local/handler.c +++ b/central-manager/lib/local/handler.c @@ -206,10 +206,10 @@ void* manageViewTerm(void* THREADABLE_ARGS){ struct sockaddr_in clientInfo; socklen_t len; char loop = 1; - 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 response; // Requête + size_t buflen; + int sent; // compteurs d'envoi + int i, index = -1; // Compteurs globaux + char* buffer = malloc(1); // Buffer d'envoi /* 2. On récupère les arguments */ struct handler_arg* arg = THREADABLE_ARGS; @@ -233,67 +233,17 @@ void* manageViewTerm(void* THREADABLE_ARGS){ while( loop ){ + /* [2] Récupération des données =========================================================*/ - /* 1. On initialise les variables utiles */ - response.flags = TERMREQ_FBK; - nb = arg->sgca->n; - response.n = 0; // nombre d'avions online - - 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(&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 - response.n += response.data[i].online; - - } + getPlaneData(&buffer, &buflen, arg->sgca); - /* [3] Construction de la requête + /* [3] Envoi de la requête =========================================================*/ - /* 1. Initialisation du buffer */ - bzero(buffer, MAX_BUF_LEN*sizeof(char)); - - /* 2. Copie des données globales */ - 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( !response.data[i].online ) - continue; - - 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; - - - /* [4] Envoi de la requête - =========================================================*/ - /* 1. Gestion de l'envoi en plusieurs requêtes */ - /* 2. Envoi */ len = sizeof(struct sockaddr_in); - sent = sendto(arg->socket, buffer, count/sizeof(char) + 1, 0, (struct sockaddr*) &clientInfo, len); + sent = sendto(arg->socket, buffer, buflen + 1, 0, (struct sockaddr*) &clientInfo, len); /* 3. Gestion erreur */ if( sent <= 0 ){ @@ -302,7 +252,7 @@ void* manageViewTerm(void* THREADABLE_ARGS){ } - /* [5] Timeout + /* [4] Timeout =========================================================*/ sleep(PUBL_TIMEOUT); @@ -315,8 +265,9 @@ void* manageViewTerm(void* THREADABLE_ARGS){ if( index != -1 ) arg->activeManagers[index] = 0; - /* 2. On ferme la socket */ + /* 2. On ferme la socket + libère la mémoire */ close(arg->socket); + free(buffer); /* 3. On arrête le THREAD */ @@ -356,7 +307,7 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){ /* 1. Initialisation des variables */ struct sockaddr_in clientInfo; socklen_t len; - char loop = 1; + char loop = 1, update = 0; int count, last, sent, nb; // compteurs d'envoi int i, index = -1; // Compteurs globaux int pindex; // index of the current plane @@ -395,6 +346,7 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){ /* 2. Si erreur reception */ if( count < TERMREQ_LEN ){ + send(arg->socket, "0", sizeof(char)*2, 0); if( DEBUGMOD&BUF ) printf("{udp_cterm}{com}(%d) Error receiving request\n", index); continue; } @@ -417,66 +369,84 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){ /* [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); + /* 1. On vérifie qu'il y a bien un update demandé (ou DATA) */ + update = ( request.flags&TERMREQ_ALT || request.flags&TERMREQ_CAP || request.flags&TERMREQ_SPD ); + if( !( update || request.flags&TERMREQ_FBK ) ){ + send(arg->socket, "0", sizeof(char)*2, 0); + printf("{udp_cterm}{com}(%d) Invalid flag, 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; + if( update ){ + + /* 2. On regarde si on trouve l'avion */ + for( i = 0 ; i < arg->sgca->n ; i++ ){ + + // Si l'avion existe et online -> on passe à la suite + if( strcmp(arg->sgca->data[i].code, request.update.code) == 0 && arg->sgca->data[i].online ){ + 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; - } + /* 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] Gestion de la réponse de l'avion + =========================================================*/ + /* 1. Réception */ + bzero(buffer, sizeof(char)*MAX_BUF_LEN); + if( recv(arg->sgca->socket[pindex], buffer, MAX_BUF_LEN, 0) <= 0 ){ + send(arg->socket, "0", sizeof(char)*2, 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; + + }else{ + + /* [5] Données des avions + =========================================================*/ + /* 1. Si TERMREQ_FBK, on récupère les données */ + - /* 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] Gestion de la réponse de l'avion - =========================================================*/ - /* 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 + /* [6] 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); @@ -501,3 +471,82 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){ + + + + + + + + + + + + + + + + + +void getPlaneData(char** pBuffer, size_t* pLen, struct context* pContext){ + /* [1] Initialisation des variables + =========================================================*/ + /* 1. Initialisation des variables */ + int count, last, i, nb; // compteurs + struct term_res response; // Requête + + + /* [1] Récupération des données + =========================================================*/ + /* 1. On initialise les variables utiles */ + response.flags = TERMREQ_FBK; + nb = pContext->n; + response.n = 0; // nombre d'avions online + + 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(&response.data[i].code, &pContext->data[i].code, sizeof(char)*6); + response.data[i].x = htonl( pContext->data[i].x ); + response.data[i].y = htonl( pContext->data[i].y ); + response.data[i].z = htonl( pContext->data[i].z ); + response.data[i].cap = htonl( pContext->data[i].cap ); + response.data[i].spd = htonl( pContext->data[i].spd ); + response.data[i].online = pContext->data[i].online; + + // Incrément du compte si online + response.n += response.data[i].online; + + } + + + /* [3] Construction de la requête + =========================================================*/ + /* 1. Initialisation du buffer */ + *pBuffer = realloc(*pBuffer, sizeof(char)*2 + PLANE_LEN * response.n + sizeof(char)); + + /* 2. Copie des données globales */ + count = 0; last = sizeof(char); memcpy(*pBuffer+count, &response.flags, last); + count += last; last = sizeof(char); memcpy(*pBuffer+count, &response.n, last); + + /* 3. Copie des données des avions */ + for( i = 0 ; i < nb ; i++ ){ + + // Ignore les avions offline + if( !response.data[i].online ) + continue; + + count += last; last = sizeof(char)*6; memcpy(*pBuffer+count, &response.data[i].code, last); + count += last; last = sizeof(int); memcpy(*pBuffer+count, &response.data[i].x, last); + count += last; last = sizeof(int); memcpy(*pBuffer+count, &response.data[i].y, last); + count += last; last = sizeof(int); memcpy(*pBuffer+count, &response.data[i].z, last); + count += last; last = sizeof(int); memcpy(*pBuffer+count, &response.data[i].cap, last); + count += last; last = sizeof(int); memcpy(*pBuffer+count, &response.data[i].spd, last); + } + + *pLen = (count+last) / sizeof(char); + free(response.data); + +} \ No newline at end of file diff --git a/central-manager/lib/local/handler.h b/central-manager/lib/local/handler.h index 77f807f..0a56619 100644 --- a/central-manager/lib/local/handler.h +++ b/central-manager/lib/local/handler.h @@ -19,5 +19,6 @@ void* manageViewTerm(void* THREADABLE_ARGS); void* manageCtrlTerm(void* THREADABLE_ARGS); + void getPlaneData(char** pBuffer, size_t* pLen, struct context* pContext); #endif \ No newline at end of file