From d5f883add161ec7b60bca61233ba0a8bbb8565e6 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 18 Apr 2017 20:06:14 +0200 Subject: [PATCH] [updated] central-manager : 1. removed middleware for planes 2. instead thread that publishes over multicast UDP to planes every N seconds. 3. Added udp/client to central-manager [todo] 1. Update `bind_header` flags to know if plane/vterm/cterm with combination + must ask for TCP/UDP (implicit) no need to say it --- central-manager/Makefile | 7 +- central-manager/central-manager.c | 101 +++++++++++++++++++++-- central-manager/central-manager.h | 6 +- central-manager/lib/data.h | 4 +- central-manager/lib/header.h | 1 + central-manager/lib/local/middleware.c | 74 +---------------- central-manager/lib/local/middleware.h | 2 +- central-manager/lib/network/udp/client.c | 46 +++++++++++ central-manager/lib/network/udp/client.h | 50 +++++++++++ 9 files changed, 206 insertions(+), 85 deletions(-) create mode 100644 central-manager/lib/network/udp/client.c create mode 100644 central-manager/lib/network/udp/client.h diff --git a/central-manager/Makefile b/central-manager/Makefile index bc52ea7..9381bcf 100644 --- a/central-manager/Makefile +++ b/central-manager/Makefile @@ -12,6 +12,9 @@ lib/network/tcp/server.o: lib/header.h lib/network/tcp/server.h lib/network/tcp/ lib/network/udp/server.o: lib/header.h lib/network/udp/server.h lib/network/udp/server.c gcc $(CFLAGS) -c -o lib/network/udp/server.o lib/network/udp/server.c +lib/network/udp/client.o: lib/header.h lib/network/udp/client.h lib/network/udp/client.c + gcc $(CFLAGS) -c -o lib/network/udp/client.o lib/network/udp/client.c + lib/local/middleware.o: lib/header.h lib/local/middleware.h lib/local/middleware.c gcc $(CFLAGS) -c -o lib/local/middleware.o lib/local/middleware.c @@ -20,8 +23,8 @@ lib/local/handler.o: lib/header.h lib/local/handler.h lib/local/handler.c # Compiles the SGCA -boot: lib/network/tcp/server.o lib/network/udp/server.o lib/local/middleware.o lib/local/handler.o central-manager.h central-manager.c - gcc $(CFLAGS) -o boot lib/network/udp/server.o lib/network/tcp/server.o lib/local/middleware.o lib/local/handler.o central-manager.c +boot: lib/network/tcp/server.o lib/network/udp/server.o lib/network/udp/client.o lib/local/middleware.o lib/local/handler.o central-manager.h central-manager.c + gcc $(CFLAGS) -o boot lib/network/udp/server.o lib/network/udp/client.o lib/network/tcp/server.o lib/local/middleware.o lib/local/handler.o central-manager.c # Run full compilation diff --git a/central-manager/central-manager.c b/central-manager/central-manager.c index 4223ff3..5a330f5 100644 --- a/central-manager/central-manager.c +++ b/central-manager/central-manager.c @@ -38,7 +38,7 @@ int main(int argc, char* argv[]){ /* 2. Variables locales */ struct listen_arg tcp_listn_arg = { SERV_HOST, TCP_LIST, NULL, &managePlane }; - struct listen_arg udp_mcast_arg = { MCST_HOST, UDP_MCST, &multicastPlanes, NULL }; + struct listen_arg udp_mcast_arg = { MCST_HOST, UDP_MCST, NULL, NULL }; struct listen_arg udp_vterm_arg = { MCST_VTER, UDP_VTER, &multicastTerminal, &manageViewTerm }; struct listen_arg udp_cterm_arg = { MCST_CTER, UDP_CTER, &multicastTerminal, &manageCtrlTerm }; @@ -46,19 +46,19 @@ int main(int argc, char* argv[]){ /* [1] Lancement des THREADS d'écoute =========================================================*/ /* (1) Ecoute TCP */ - pthread_create(&listenManagers[0], NULL, LISTEN_TCP, (void*) &tcp_listn_arg); + pthread_create(&listenManagers[0], NULL, LISTEN_TCP, (void*) &tcp_listn_arg); if( DEBUGMOD&THR ) printf("{tcp_listn} démarré\n"); /* (2) Ecoute UDP multicast */ - pthread_create(&listenManagers[1], NULL, LISTEN_UDP, (void*) &udp_mcast_arg); + pthread_create(&listenManagers[1], NULL, MCAST_PUBLISH, (void*) &udp_mcast_arg); if( DEBUGMOD&THR ) printf("{udp_mcast} démarré\n"); /* (3) Ecoute UDP viewTerm */ - pthread_create(&listenManagers[2], NULL, LISTEN_UDP, (void*) &udp_vterm_arg); + pthread_create(&listenManagers[2], NULL, LISTEN_UDP, (void*) &udp_vterm_arg); if( DEBUGMOD&THR ) printf("{udp_vterm} démarré\n"); /* (4) Ecoute UDP ctrlTerm */ - pthread_create(&listenManagers[3], NULL, LISTEN_UDP, (void*) &udp_cterm_arg); + pthread_create(&listenManagers[3], NULL, LISTEN_UDP, (void*) &udp_cterm_arg); if( DEBUGMOD&THR ) printf("{udp_cterm} démarré\n"); @@ -315,5 +315,96 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){ printf("{%s} FERMETURE SOCKET D'ECOUTE UDP!\n", entity); close(SOCKET); + return NULL; +} + + + + + + +/* Publication de la socket TCP sur un groupe multicast +* +* @history +* [0] Initialisation des variables +* [1] On initialise la socket CLIENT UDP +* [2] On construit la requête à envoyer +* @loop +* [3] On attends un délai fixé (2s par défaut) +* [4] On envoie les information de la socket TCP +* [N] On ferme la SOCKET +* +*/ +void* MCAST_PUBLISH(void* THREADABLE_ARGS){ + /* [0] Initialisation des variables + ==========================================================*/ + /* 1. On initialise les variables */ + struct sockaddr_in targetInfo; // contiendra les infos de la cible de la socket client + char buffer[MAX_BUF_LEN]; // buffer de requêtes (envois) + struct bind_header request; // requête brute + + /* 2. On parse les arguments */ + struct listen_arg* arg = THREADABLE_ARGS; // Addr + Port serveur + + // retour de @UDP_SOCKET + int SOCKET; + + + /* [1] On initialise la socket CLIENT UDP + ==========================================================*/ + if( UDP_SOCKET(&SOCKET, arg->addr, arg->port, &targetInfo) < 0 ){ + + if( DEBUGMOD&SCK ) printf("{udp_mcast} Erreur de création socket UDP client\n"); + + // On ferme la SOCKET d'écoute globale + printf("{udp_mcast} FERMETURE SOCKET CLIENT UDP!\n"); + close(SOCKET); + + return NULL; + } + + printf("{udp_mcast} bound to %s:%d\n", arg->addr, arg->port); + + + /* [2] On construit la requête à envoyer + =========================================================*/ + /* 1. Initialisation du buffer */ + bzero(buffer, MAX_BUF_LEN*sizeof(char)); + + /* 2. Remplissage de la requête brute */ + request.flags = BINDHEAD_TCP; + strcpy(request.addr, SERV_HOST); + request.port = htons(TCP_LIST); + + /* 3. Copie dans le buffer */ + memcpy(buffer, &request.flags, sizeof(char)); + memcpy(buffer+sizeof(char), &request.addr, sizeof(char)*INET_ADDRSTRLEN); + memcpy(buffer+sizeof(char)*(INET_ADDRSTRLEN+1), &request.port, sizeof(unsigned short)); + + + while( 1 ){ + + /* [3] On attends un délai fixé (2s par défaut) + =========================================================*/ + sleep(PUBL_TIMEOUT); + + + /* [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"); + break; + } + + + } + + + + /* [n] On ferme la SOCKET CLIENT UDP + ==========================================================*/ + printf("{udp_mcast} FERMETURE SOCKET CLIENT UDP!\n"); + close(SOCKET); + return NULL; } \ No newline at end of file diff --git a/central-manager/central-manager.h b/central-manager/central-manager.h index 902b5dd..c5a2f74 100644 --- a/central-manager/central-manager.h +++ b/central-manager/central-manager.h @@ -14,13 +14,15 @@ /* local dependencies */ #include "lib/network/tcp/server.h" #include "lib/network/udp/server.h" +#include "lib/network/udp/client.h" #include "lib/local/middleware.h" #include "lib/local/handler.h" /* headers */ -void* LISTEN_TCP(void* THREADABLE_ARG); -void* LISTEN_UDP(void* THREADABLE_ARG); +void* LISTEN_TCP(void* THREADABLE_ARGS); +void* LISTEN_UDP(void* THREADABLE_ARGS); +void* MCAST_PUBLISH(void* THREADABLE_ARGS); diff --git a/central-manager/lib/data.h b/central-manager/lib/data.h index 31e8a20..9997619 100644 --- a/central-manager/lib/data.h +++ b/central-manager/lib/data.h @@ -42,8 +42,8 @@ #define BINDHDR_LEN ( sizeof(char)*(1+INET_ADDRSTRLEN)+sizeof(unsigned short) ) #define BINDHEAD_CTL 0x01 // is command terminal (else: view terminal) - #define BINDHEAD_SCK 0x02 // ask for com socket - #define BINDHEAD_TCP 0x04 // ask TCP instead of UDP + #define BINDHEAD_SCK 0x02 // ask for com socket (terminal) + #define BINDHEAD_TCP 0x04 // ask TCP com socket (plane) struct bind_header{ char flags; diff --git a/central-manager/lib/header.h b/central-manager/lib/header.h index c77dca5..a58b292 100644 --- a/central-manager/lib/header.h +++ b/central-manager/lib/header.h @@ -53,6 +53,7 @@ #define maxPortLen 6 #define SOCK_TIMEOUT 3 // 3sec timeout (1+ temps refresh plane) + #define PUBL_TIMEOUT 2 // 2sec entre chaque publication sur multicast UDP (pour avions) struct context{ diff --git a/central-manager/lib/local/middleware.c b/central-manager/lib/local/middleware.c index b19a33c..f969012 100644 --- a/central-manager/lib/local/middleware.c +++ b/central-manager/lib/local/middleware.c @@ -11,78 +11,6 @@ -int multicastPlanes(struct middleware_arg* arg){ - /* [0] Initialisation - =========================================================*/ - struct sockaddr_in clientInfo; // contiendra les infos client - socklen_t len; // taille de la socket - int read; // compteurs - char buffer[MAX_BUF_LEN+1]; // buffer requête - struct bind_header request; // requête parsée - - - - /* 1. On attends une connection UDP */ - len = sizeof(struct sockaddr_in); - read = recvfrom(arg->listenSock, buffer, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len); - - /* 2. Si erreur reception ou taille incorrecte -> retour à l'écoute */ - if( read < BINDHDR_LEN ){ - if( DEBUGMOD&BUF ) printf("{%s} read('%s') = %d bytes (expected: %d)\n", arg->entity, buffer, read, (int) (BINDHDR_LEN) ); - return -1; - } - - /* 3. On récupère l'adresse IP du client */ - if( DEBUGMOD&SCK ) printf("{%s} %s:%d connecté\n", arg->entity, inet_ntoa(clientInfo.sin_addr), ntohs(clientInfo.sin_port)); - - - - /* [1] Gestion de la requête - =========================================================*/ - /* 1. On parse la requête */ - memcpy(&request.flags, buffer, sizeof(char)); - memcpy(&request.addr, buffer+sizeof(char), sizeof(char)*15); - memcpy(&request.port, buffer+sizeof(char)*16, sizeof(unsigned short)); - printf("{%s} received: bind_header{flag = %d; addr = '%s'; port = %d}\n", arg->entity, (int) request.flags, request.addr, request.port); - - /* (1) Envoi socket de communication (TCP) - ---------------------------------------------------------*/ - /* 1. Si flag manquant -> on quitte */ - if( !(request.flags&BINDHEAD_TCP) ) - return -1; - - - - strcpy(request.addr, SERV_HOST); - request.port = TCP_LIST; - - /* [2] Envoi de la réponse - =========================================================*/ - /* 1. On sérialise la réponse */ - bzero(buffer, MAX_BUF_LEN); - memcpy(buffer, &request.flags, sizeof(char)); - memcpy(buffer+sizeof(char), &request.addr, sizeof(char)*INET_ADDRSTRLEN); - memcpy(buffer+sizeof(char)*(1+INET_ADDRSTRLEN), &request.port, sizeof(unsigned short)); - - /* 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); - return -2; - } - - printf("{%s} sent: bind_header{flag = %d; addr = '%s'; port = %d}\n", arg->entity, (int) request.flags, request.addr, request.port); - - - return 0; - -} - - - - - - int multicastTerminal(struct middleware_arg* arg){ @@ -166,7 +94,7 @@ int multicastTerminal(struct middleware_arg* arg){ /* [2] Envoi de la réponse =========================================================*/ /* 1. On sérialise la réponse */ - bzero(buffer, MAX_BUF_LEN); + bzero(buffer, MAX_BUF_LEN*sizeof(char)); memcpy(buffer, &request.flags, sizeof(char)); memcpy(buffer+sizeof(char), &request.addr, sizeof(char)*15); memcpy(buffer+sizeof(char)*16, &request.port, sizeof(unsigned short)); diff --git a/central-manager/lib/local/middleware.h b/central-manager/lib/local/middleware.h index 5877aa9..0907c0d 100644 --- a/central-manager/lib/local/middleware.h +++ b/central-manager/lib/local/middleware.h @@ -16,7 +16,7 @@ #include "../header.h" #include "../network/udp/server.h" - int multicastPlanes(struct middleware_arg* ARGS); + // int multicastPlanes(struct middleware_arg* ARGS); int multicastTerminal(struct middleware_arg* ARGS); diff --git a/central-manager/lib/network/udp/client.c b/central-manager/lib/network/udp/client.c new file mode 100644 index 0000000..3bf0ee8 --- /dev/null +++ b/central-manager/lib/network/udp/client.c @@ -0,0 +1,46 @@ +#include "client.h" + + + +int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo){ + + /* [0] Initialisation des variables + =========================================================*/ + *pSocket = -1; + struct timeval timeout; + + + /* [1] Création de la socket + =======================================================*/ + /* 1. Création de la socket */ + *pSocket = socket(AF_INET, SOCK_DGRAM, 0); + + /* 2. Gestion erreur */ + 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 + =========================================================*/ + /* (1) Reset des valeurs */ + bzero(pInfo, sizeof(struct sockaddr_in)); + + /* (2) On définit les infos */ + pInfo->sin_family = AF_INET; + pInfo->sin_port = htons(pPort); + pInfo->sin_addr.s_addr = inet_addr(pAddr); + + + /* [n] Code succès + =========================================================*/ + return 0; +} diff --git a/central-manager/lib/network/udp/client.h b/central-manager/lib/network/udp/client.h new file mode 100644 index 0000000..8c1eeaa --- /dev/null +++ b/central-manager/lib/network/udp/client.h @@ -0,0 +1,50 @@ +/************************** +* UDP Client Dependency * +*************************** +* Designed & Developed by * +* Adrien Marquès * +* * +*************************** +* doowap31@gmail.com * +**************************/ +#ifndef _LIB_NETWORK_UDP_CLIENT_H_ + #define _LIB_NETWORK_UDP_CLIENT_H_ + + + /* Remarque: + * + * Il s'agit en réalité d'un serveur UDP, mais en multicast les membres du groupe pour qui sont copiées les requêtes + * sont par habitude appelés clients + * + */ + + + + #include "../../header.h" + + + /* Créée une socket UDP + crée le sockaddr_in pour la suite + * + * ==IN== + * @pAddr Adresse du groupe multicast UDP + * @pPort Port d'écoute UDP + * + * ==OUT== + * @pSocket Pointeur sur le à rempliR => contiendra un pointeur sur la socket créée + * @pInfo Pointeur sur le à remplir => contiendra un pointeur sur les infos server + * + * ==RETURN== + * @status -1 si erreur, sinon 0 + * + * @history + * [1] Création de la socket + * [2] On définit les infos de la socket + * [3] On crée la socket + * + * + */ + int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo); + + + +#endif \ No newline at end of file