Compare commits
66 Commits
multicast-
...
master
Author | SHA1 | Date |
---|---|---|
xdrm-brackets | 2d176987ea | |
SeekDaSky | d11649e9b9 | |
SeekDaSky | 710a5def49 | |
xdrm-brackets | 87509e8efe | |
xdrm-brackets | 4636c79334 | |
SeekDaSky | c8da1b3ba6 | |
SeekDaSky | 821808a420 | |
xdrm-brackets | f5232693d3 | |
xdrm-brackets | 1246fbbdc5 | |
xdrm-brackets | 110598780b | |
xdrm-brackets | 734de323d4 | |
xdrm-brackets | 486216f183 | |
xdrm-brackets | 265feabb59 | |
xdrm-brackets | 6848840638 | |
xdrm-brackets | 87ed0fb7c9 | |
SeekDaSky | b67ddecbab | |
SeekDaSky | 139de56401 | |
xdrm-brackets | 919fac4d67 | |
xdrm-brackets | b21565e682 | |
SeekDaSky | dc7016355a | |
SeekDaSky | 01aeb922c4 | |
xdrm-brackets | 21cc53bc20 | |
SeekDaSky | a2ab8d415e | |
SeekDaSky | 54321deca2 | |
xdrm-brackets | 6017302007 | |
xdrm-brackets | d6b2b82116 | |
SeekDaSky | 1668bca970 | |
SeekDaSky | 6541012e04 | |
xdrm-brackets | 5b7d7d5c80 | |
xdrm-brackets | 05a59c772c | |
xdrm-brackets | 9a6c480290 | |
xdrm-brackets | 6fbd41542b | |
xdrm-brackets | 685d18df8f | |
xdrm-brackets | 4b23207f74 | |
xdrm-brackets | f860c8af0a | |
xdrm-brackets | c868ec22f4 | |
xdrm-brackets | 29393a0747 | |
xdrm-brackets | c3fa24d747 | |
xdrm-brackets | 1501181420 | |
xdrm-brackets | 7b3f8c101c | |
xdrm-brackets | 6cfa351c9a | |
xdrm-brackets | c5e59ccbd8 | |
xdrm-brackets | a31c97942b | |
xdrm-brackets | 061893b35d | |
xdrm-brackets | 4af2f8180c | |
xdrm-brackets | e4b9d5daa6 | |
xdrm-brackets | a8a44d9941 | |
xdrm-brackets | cc78418a53 | |
xdrm-brackets | e6c2bbcfa6 | |
xdrm-brackets | 1a98172fca | |
xdrm-brackets | e8e65f81fb | |
SeekDaSky | face7b0f04 | |
xdrm-brackets | a356548965 | |
xdrm-brackets | e2fe1a7155 | |
xdrm-brackets | b96e89bddb | |
SeekDaSky | 3071b9debe | |
xdrm-brackets | 19a513f207 | |
SeekDaSky | 5d2f912738 | |
xdrm-brackets | 9614928bcf | |
SeekDaSky | 0dbd88c1f8 | |
xdrm-brackets | 79a1258a53 | |
xdrm-brackets | 48f2b33728 | |
xdrm-brackets | 3c241a2a95 | |
xdrm-brackets | 80f0aa95f6 | |
xdrm-brackets | 387e55c092 | |
xdrm-brackets | a20cc18377 |
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
default:
|
||||||
|
@echo "install - will compile and create executables";
|
||||||
|
@echo "clean - will remove executables and clean";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
install-sgca:
|
||||||
|
@echo "(1) Compiling SGCA";
|
||||||
|
@make --directory=./sgca > /dev/null;
|
||||||
|
|
||||||
|
install-plane:
|
||||||
|
@echo "(2) Compiling PLANE";
|
||||||
|
@make --directory=./plane > /dev/null;
|
||||||
|
|
||||||
|
link-sgca:
|
||||||
|
@echo "(3) Linking SGCA executable";
|
||||||
|
@ln -fs ./sgca/boot x-sgca;
|
||||||
|
|
||||||
|
link-plane:
|
||||||
|
@echo "(4) Linking PLANE executable";
|
||||||
|
@ln -fs ./plane/boot x-plane;
|
||||||
|
|
||||||
|
link-viewTerm:
|
||||||
|
@echo "(4) Linking VIEW TERMINAL executable";
|
||||||
|
@echo -e "#!/bin/bash\n\njava -jar ./viewTerm/viewTerm.jar;\n" > ./x-viewTerm;
|
||||||
|
@chmod ug+x ./x-viewTerm;
|
||||||
|
|
||||||
|
link-ctrlTerm:
|
||||||
|
@echo "(5) Linking CTRL TERMINAL executable";
|
||||||
|
@echo -e "#!/bin/bash\n\njava -jar ./ctrlTerm/commandTerm.jar;\n" > ./x-ctrlTerm;
|
||||||
|
@chmod ug+x ./x-ctrlTerm;
|
||||||
|
|
||||||
|
|
||||||
|
install: install-sgca install-plane link-sgca link-plane link-viewTerm link-ctrlTerm
|
||||||
|
@echo;
|
||||||
|
@echo "*** Executables created:";
|
||||||
|
@ls -a . | grep -P "^x-*" | sed 's/^x-/ (*) x-/';
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@find ./x-sgca > /dev/null 2>&1 && rm ./x-sgca || return 0;
|
||||||
|
@find ./x-plane > /dev/null 2>&1 && rm ./x-plane || return 0;
|
||||||
|
@find ./x-viewTerm > /dev/null 2>&1 && rm ./x-viewTerm || return 0;
|
||||||
|
@find ./x-ctrlTerm > /dev/null 2>&1 && rm ./x-ctrlTerm || return 0;
|
||||||
|
@make clean --directory=./sgca > /dev/null;
|
||||||
|
@make clean --directory=./plane > /dev/null;
|
|
@ -1 +0,0 @@
|
||||||
.vscode
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# [1] Create service target (boot)
|
|
||||||
sudo ln -s $(pwd)/sgca /usr/sbin/sgca;
|
|
||||||
|
|
||||||
# [2] Create service unit
|
|
||||||
sudo ln -s $(pwd)/sgca.service /lib/systemd/system/sgca.service;
|
|
||||||
|
|
||||||
# [3] Enable service (optional if no [Install])
|
|
||||||
sudo systemctl enable sgca.service;
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo -ne "\x3\x0\x0" | nc -u localhost 4446;
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo -ne "abcdef\x1\x0\x0\x0\x2\x0\x0\x0\x3\x0\x0\x0\x4\x0\x0\x0\x5\x0\x0\x0" | nc localhost 20556;
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo -ne "\x3\x0\x0" | nc -u localhost 4445;
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
/home/xdrm-brackets/Desktop/git.xdrm.io/sysdis-project/central-manager/boot >> $1 2>&1;
|
|
|
@ -1,351 +0,0 @@
|
||||||
/**************************
|
|
||||||
* Handler Dependency *
|
|
||||||
***************************
|
|
||||||
* Designed & Developed by *
|
|
||||||
* Adrien Marquès *
|
|
||||||
* <xdrm-brackets> *
|
|
||||||
***************************
|
|
||||||
* doowap31@gmail.com *
|
|
||||||
**************************/
|
|
||||||
#include "handler.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Gestion d'une connexion PLANE
|
|
||||||
*
|
|
||||||
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] Initialisation des variables
|
|
||||||
* @loop
|
|
||||||
* (2) Attente de requête
|
|
||||||
* (3) Gestion de la requête
|
|
||||||
* (4) Envoi de la réponse
|
|
||||||
* [5] On libère la mémoire
|
|
||||||
* [6] Fermeture de la connection (SOCKET)
|
|
||||||
* [n] Arrêt du THREAD
|
|
||||||
* 1. On met à jour "activeManagers"
|
|
||||||
* 2. On arrête le THREAD
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void* managePlane(void* THREADABLE_ARGS){
|
|
||||||
|
|
||||||
/* [1] Initialisation des variables
|
|
||||||
=========================================================*/
|
|
||||||
/* 1. Variables utiles */
|
|
||||||
int read, i, index, pindex; // compteurs
|
|
||||||
char buffer[MAX_BUF_LEN]; // buffer
|
|
||||||
struct plane data; // données de l'avion
|
|
||||||
int SOCKET; // Copie de la socket (évite les conflits de références)
|
|
||||||
|
|
||||||
|
|
||||||
/* 2. On récupère les arguments */
|
|
||||||
struct handler_arg* arg = THREADABLE_ARGS;
|
|
||||||
memcpy(&SOCKET, &arg->socket, sizeof(int));
|
|
||||||
if( DEBUGMOD&HDR ) printf("===== managePlane(%p, %p, %d, %p) =====\n", (void*) arg->managers, (void*) arg->activeManagers, arg->socket, (void*) arg->sgca);
|
|
||||||
|
|
||||||
|
|
||||||
/* 3. On récupère le rang du thread parmi les "managers" */
|
|
||||||
index = -1;
|
|
||||||
for( i = 0 ; i < MAX_TCP_THR ; i++ )
|
|
||||||
if( arg->managers[i] == pthread_self() ){ index = i; break; }
|
|
||||||
|
|
||||||
// Erreur de thread
|
|
||||||
if( index == -1 ){
|
|
||||||
if( DEBUGMOD&THR ) printf("{tcp_com}(%d) Unknown thread index. Aborting\n", index);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
while( 1 ){
|
|
||||||
|
|
||||||
/* (2) Récupération de la requête
|
|
||||||
---------------------------------------------------------*/
|
|
||||||
/* 1. On lit sur la socket */
|
|
||||||
read = recv(SOCKET, buffer, MAX_BUF_LEN, 0);
|
|
||||||
|
|
||||||
/* 2.1. Si erreur reception (-1:erreur, 0:fermeture client propre) */
|
|
||||||
if( read <= 0 ){
|
|
||||||
if( DEBUGMOD&BUF ) printf("{tcp_com}(%d) read: %d -> must exit thread\n", index, read);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 2.2. Si message trop court */
|
|
||||||
if( read < PLANE_LEN ){
|
|
||||||
if( DEBUGMOD&BUF ) printf("{tcp_com}(%d) read: %d (expected: %d)\n", index, read, (int) PLANE_LEN);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 3. On parse la requête*/
|
|
||||||
memcpy(&data.code, buffer+sizeof(char)*0+sizeof(int)*0, sizeof(char)*6);
|
|
||||||
memcpy(&data.x, buffer+sizeof(char)*6+sizeof(int)*0, sizeof(int));
|
|
||||||
memcpy(&data.y, buffer+sizeof(char)*6+sizeof(int)*1, sizeof(int));
|
|
||||||
memcpy(&data.z, buffer+sizeof(char)*6+sizeof(int)*2, sizeof(int));
|
|
||||||
memcpy(&data.spd, buffer+sizeof(char)*6+sizeof(int)*4, sizeof(int));
|
|
||||||
memcpy(&data.cap, buffer+sizeof(char)*6+sizeof(int)*3, sizeof(int));
|
|
||||||
|
|
||||||
|
|
||||||
/* (3) Gestion de la requête -> enregistrement
|
|
||||||
---------------------------------------------------------*/
|
|
||||||
pindex = -1;
|
|
||||||
|
|
||||||
/* 1. On regarde si l'avion existe */
|
|
||||||
for( i = 0 ; i < arg->sgca->n ; i++ ){
|
|
||||||
|
|
||||||
// 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 ){
|
|
||||||
|
|
||||||
// On ajoute une entrée à data
|
|
||||||
pindex = arg->sgca->n;
|
|
||||||
arg->sgca->n++;
|
|
||||||
arg->sgca->data = (struct plane*) realloc(arg->sgca->data, sizeof(struct plane)*arg->sgca->n + 1);
|
|
||||||
printf("{tcp_com}(%d) plane '%s' (#%d) created\n", index, data.code, pindex);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3. On copie les constantes */
|
|
||||||
memcpy(&arg->sgca->data[pindex], &data, sizeof(struct plane));
|
|
||||||
|
|
||||||
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 = arg->sgca->data[pindex].x;
|
|
||||||
data.y = arg->sgca->data[pindex].y;
|
|
||||||
data.z = arg->sgca->data[pindex].z;
|
|
||||||
data.cap = arg->sgca->data[pindex].cap;
|
|
||||||
data.spd = arg->sgca->data[pindex].spd;
|
|
||||||
|
|
||||||
/* 2. Vérification du FLAG (modifications) si requêtes d'update */
|
|
||||||
//TODO: Gestion arg->sgca->update[pindex].flags|UPD_SPEED etc.. pour ajout du flag+elements dans reponse
|
|
||||||
|
|
||||||
/* 3. On sérialise la réponse */
|
|
||||||
bzero(buffer, MAX_BUF_LEN*sizeof(char));
|
|
||||||
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &data.code, sizeof(char)*6);
|
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*0, &data.x, sizeof(int));
|
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*1, &data.y, sizeof(int));
|
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*2, &data.z, sizeof(int));
|
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*4, &data.spd, sizeof(int));
|
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*3, &data.cap, sizeof(int));
|
|
||||||
|
|
||||||
|
|
||||||
/* (5) Envoi de la réponse
|
|
||||||
---------------------------------------------------------*/
|
|
||||||
read = send(SOCKET, buffer, PLANE_LEN/sizeof(char) + 1, 0);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* [5] On libère la mémoire
|
|
||||||
=========================================================*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* [6] Fermeture de la connection (SOCKET)
|
|
||||||
=========================================================*/
|
|
||||||
printf("{tcp_com}(%d) Fermeture de la socket de communication!\n", index);
|
|
||||||
close(SOCKET);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* [n] Arrêt du THREAD
|
|
||||||
============================================================================*/
|
|
||||||
/* 1. On met à jour "activeManagers" */
|
|
||||||
if( index != -1 )
|
|
||||||
arg->activeManagers[index] = 0;
|
|
||||||
|
|
||||||
/* 2. On arrête le THREAD */
|
|
||||||
if( DEBUGMOD&THR ) printf("{tcp_com}(%d) libéré\n", index);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Gestion d'une connexion TERMINAL
|
|
||||||
*
|
|
||||||
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] Initialisation des variables
|
|
||||||
* [2] Récupération de la requête
|
|
||||||
* [3] Traitement de la requête
|
|
||||||
* [4] Création de la réponse
|
|
||||||
* [5] Envoi de la réponse
|
|
||||||
* [6] On vide les buffers
|
|
||||||
* [7] Fermeture de la connection (SOCKET)
|
|
||||||
* [n] Arrêt du THREAD
|
|
||||||
* 1. On récupère le rang dans les "managers"
|
|
||||||
* 2. On met à jour "activeManagers"
|
|
||||||
* 3. On arrête le THREAD
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void* manageViewTerm(void* THREADABLE_ARGS){
|
|
||||||
|
|
||||||
/* [1] Initialisation des variables
|
|
||||||
=========================================================*/
|
|
||||||
int read; // compteur
|
|
||||||
struct sockaddr_in clientInfo;
|
|
||||||
socklen_t len;
|
|
||||||
char request[MAX_BUF_LEN]; // Requête
|
|
||||||
// char response[MAX_BUF_LEN]; // Réponse
|
|
||||||
|
|
||||||
/* 2. On récupère les arguments */
|
|
||||||
struct handler_arg* arg = THREADABLE_ARGS;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do{
|
|
||||||
|
|
||||||
printf("{udp_x-term}{udp_com} waiting for terminal request\n");
|
|
||||||
/* [2] Récupération de la requête
|
|
||||||
=========================================================*/
|
|
||||||
/* 1. On lit sur la socket */
|
|
||||||
len = sizeof(struct sockaddr_in);
|
|
||||||
read = recvfrom(arg->socket, request, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
|
||||||
|
|
||||||
/* 2. Si erreur reception */
|
|
||||||
if( DEBUGMOD&BUF ) printf("{udp_x-term}{udp_com} READ = %d\n", read);
|
|
||||||
|
|
||||||
if( read < 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* 3. On désérialise la requête*/
|
|
||||||
printf("{udp_x-term}{udp_com} TERMINAL Request(%d bytes) : '%s'\n", read, request);
|
|
||||||
|
|
||||||
/* [3] Gestion de la requête
|
|
||||||
=========================================================*/
|
|
||||||
|
|
||||||
|
|
||||||
/* [4] Envoi reponse
|
|
||||||
=========================================================*/
|
|
||||||
strcpy(request+strlen(request), "-bla\0");
|
|
||||||
send(arg->socket, request, strlen(request), 0);
|
|
||||||
|
|
||||||
|
|
||||||
}while( 0 );
|
|
||||||
|
|
||||||
/* [n] Arrêt du THREAD
|
|
||||||
============================================================================*/
|
|
||||||
/* 1. On récupère le rang dans les "managers" */
|
|
||||||
int i, index = -1;
|
|
||||||
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
|
||||||
if( arg->managers[i] == pthread_self() ){ index = i; break; }
|
|
||||||
|
|
||||||
/* 2. On met à jour "activeManagers" */
|
|
||||||
if( index != -1 )
|
|
||||||
arg->activeManagers[index] = 0;
|
|
||||||
|
|
||||||
/* 3. On arrête le THREAD */
|
|
||||||
if( DEBUGMOD&THR ) printf("{udp_x-term}{udp_com}(%d) libéré\n", index);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Gestion d'une connexion TERMINAL
|
|
||||||
*
|
|
||||||
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] Initialisation des variables
|
|
||||||
* [2] Récupération de la requête
|
|
||||||
* [3] Traitement de la requête
|
|
||||||
* [4] Création de la réponse
|
|
||||||
* [5] Envoi de la réponse
|
|
||||||
* [6] On vide les buffers
|
|
||||||
* [7] Fermeture de la connection (SOCKET)
|
|
||||||
* [n] Arrêt du THREAD
|
|
||||||
* 1. On récupère le rang dans les "managers"
|
|
||||||
* 2. On met à jour "activeManagers"
|
|
||||||
* 3. On arrête le THREAD
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void* manageCtrlTerm(void* THREADABLE_ARGS){
|
|
||||||
|
|
||||||
/* [1] Initialisation des variables
|
|
||||||
=========================================================*/
|
|
||||||
int read; // compteur
|
|
||||||
struct sockaddr_in clientInfo;
|
|
||||||
socklen_t len;
|
|
||||||
char request[MAX_BUF_LEN]; // Requête
|
|
||||||
// char response[MAX_BUF_LEN]; // Réponse
|
|
||||||
|
|
||||||
/* 2. On récupère les arguments */
|
|
||||||
struct handler_arg* arg = THREADABLE_ARGS;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do{
|
|
||||||
|
|
||||||
printf("{udp_x-term}{udp_com} waiting for terminal request\n");
|
|
||||||
/* [2] Récupération de la requête
|
|
||||||
=========================================================*/
|
|
||||||
/* 1. On lit sur la socket */
|
|
||||||
len = sizeof(struct sockaddr_in);
|
|
||||||
read = recvfrom(arg->socket, request, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
|
||||||
|
|
||||||
/* 2. Si erreur reception */
|
|
||||||
if( DEBUGMOD&BUF ) printf("{udp_x-term}{udp_com} READ = %d\n", read);
|
|
||||||
|
|
||||||
if( read < 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* 3. On désérialise la requête*/
|
|
||||||
printf("{udp_x-term}{udp_com} TERMINAL Request(%d bytes) : '%s'\n", read, request);
|
|
||||||
|
|
||||||
/* [3] Gestion de la requête
|
|
||||||
=========================================================*/
|
|
||||||
|
|
||||||
|
|
||||||
/* [4] Envoi reponse
|
|
||||||
=========================================================*/
|
|
||||||
strcpy(request+strlen(request), "-bla\0");
|
|
||||||
send(arg->socket, request, strlen(request), 0);
|
|
||||||
|
|
||||||
|
|
||||||
}while( 0 );
|
|
||||||
|
|
||||||
/* [n] Arrêt du THREAD
|
|
||||||
============================================================================*/
|
|
||||||
/* 1. On récupère le rang dans les "managers" */
|
|
||||||
int i, index = -1;
|
|
||||||
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
|
||||||
if( arg->managers[i] == pthread_self() ){ index = i; break; }
|
|
||||||
|
|
||||||
/* 2. On met à jour "activeManagers" */
|
|
||||||
if( index != -1 )
|
|
||||||
arg->activeManagers[index] = 0;
|
|
||||||
|
|
||||||
/* 3. On arrête le THREAD */
|
|
||||||
if( DEBUGMOD&THR ) printf("{udp_x-term}{udp_com}(%d) libéré\n", index);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
/**************************
|
|
||||||
* Middleware Dependency *
|
|
||||||
***************************
|
|
||||||
* Designed & Developed by *
|
|
||||||
* Adrien Marquès *
|
|
||||||
* <xdrm-brackets> *
|
|
||||||
***************************
|
|
||||||
* doowap31@gmail.com *
|
|
||||||
**************************/
|
|
||||||
#include "middleware.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int multicastTerminal(struct middleware_arg* arg){
|
|
||||||
/* [0] Initialisation
|
|
||||||
=========================================================*/
|
|
||||||
struct sockaddr_in comInfo; // contiendra les infos de la socket COM
|
|
||||||
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) Création socket de communication (si demandé)
|
|
||||||
---------------------------------------------------------*/
|
|
||||||
/* 1. Si on veut un port de communicatin */
|
|
||||||
if( request.flags&BINDHEAD_SCK ){
|
|
||||||
|
|
||||||
/* 2. On bind une socket sur un port random */
|
|
||||||
if( DROP_UDP_SERVER(SERV_HOST, 0, arg->comSock, &comInfo, 0) < 0 ){
|
|
||||||
|
|
||||||
if( DEBUGMOD&SCK ) printf("{%s} Erreur de création de la socket COM\n", arg->entity);
|
|
||||||
|
|
||||||
/* 3. On ferme la socket et enleve le FLAG pour dire qu'on a pas pu ouvrir le port */
|
|
||||||
close(*arg->comSock);
|
|
||||||
request.flags -= BINDHEAD_SCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 2.2 Si on veut on port de communication */
|
|
||||||
/* (2) Récupération port random
|
|
||||||
---------------------------------------------------------*/
|
|
||||||
if( request.flags&BINDHEAD_SCK ){
|
|
||||||
|
|
||||||
/* 1. On récupère le port de la socket de communication */
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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_SCK;
|
|
||||||
|
|
||||||
/* 3. Si on a le port -> on le met dans la reponse */
|
|
||||||
}else{
|
|
||||||
strcpy(request.addr, SERV_HOST);
|
|
||||||
request.port = comInfo.sin_port;
|
|
||||||
if( DEBUGMOD&SCK ) printf("{%s}{udp_com} socket opened on %s:%d\n", arg->entity, request.addr, ntohs(request.port));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* [2] Envoi de la réponse
|
|
||||||
=========================================================*/
|
|
||||||
/* 1. On sérialise la réponse */
|
|
||||||
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));
|
|
||||||
|
|
||||||
/* 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, ntohs(request.port));
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- You may freely edit this file. See commented blocks below for -->
|
|
||||||
<!-- some examples of how to customize the build. -->
|
|
||||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
|
||||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
|
||||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
|
||||||
<!-- the Compile on Save feature is turned off for the project. -->
|
|
||||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
|
||||||
<!-- in the project's Project Properties dialog box.-->
|
|
||||||
<project name="CommandTerminal" default="default" basedir=".">
|
|
||||||
<description>Builds, tests, and runs the project CommandTerminal.</description>
|
|
||||||
<import file="nbproject/build-impl.xml"/>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
There exist several targets which are by default empty and which can be
|
|
||||||
used for execution of your tasks. These targets are usually executed
|
|
||||||
before and after some main targets. They are:
|
|
||||||
|
|
||||||
-pre-init: called before initialization of project properties
|
|
||||||
-post-init: called after initialization of project properties
|
|
||||||
-pre-compile: called before javac compilation
|
|
||||||
-post-compile: called after javac compilation
|
|
||||||
-pre-compile-single: called before javac compilation of single file
|
|
||||||
-post-compile-single: called after javac compilation of single file
|
|
||||||
-pre-compile-test: called before javac compilation of JUnit tests
|
|
||||||
-post-compile-test: called after javac compilation of JUnit tests
|
|
||||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
|
||||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
|
||||||
-pre-jar: called before JAR building
|
|
||||||
-post-jar: called after JAR building
|
|
||||||
-post-clean: called after cleaning build products
|
|
||||||
|
|
||||||
(Targets beginning with '-' are not intended to be called on their own.)
|
|
||||||
|
|
||||||
Example of inserting an obfuscator after compilation could look like this:
|
|
||||||
|
|
||||||
<target name="-post-compile">
|
|
||||||
<obfuscate>
|
|
||||||
<fileset dir="${build.classes.dir}"/>
|
|
||||||
</obfuscate>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
For list of available properties check the imported
|
|
||||||
nbproject/build-impl.xml file.
|
|
||||||
|
|
||||||
|
|
||||||
Another way to customize the build is by overriding existing main targets.
|
|
||||||
The targets of interest are:
|
|
||||||
|
|
||||||
-init-macrodef-javac: defines macro for javac compilation
|
|
||||||
-init-macrodef-junit: defines macro for junit execution
|
|
||||||
-init-macrodef-debug: defines macro for class debugging
|
|
||||||
-init-macrodef-java: defines macro for class execution
|
|
||||||
-do-jar: JAR building
|
|
||||||
run: execution of project
|
|
||||||
-javadoc-build: Javadoc generation
|
|
||||||
test-report: JUnit report generation
|
|
||||||
|
|
||||||
An example of overriding the target for project execution could look like this:
|
|
||||||
|
|
||||||
<target name="run" depends="CommandTerminal-impl.jar">
|
|
||||||
<exec dir="bin" executable="launcher.exe">
|
|
||||||
<arg file="${dist.jar}"/>
|
|
||||||
</exec>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
Notice that the overridden target depends on the jar target and not only on
|
|
||||||
the compile target as the regular run target does. Again, for a list of available
|
|
||||||
properties which you can use, check the target you are overriding in the
|
|
||||||
nbproject/build-impl.xml file.
|
|
||||||
|
|
||||||
-->
|
|
||||||
</project>
|
|
|
@ -1,3 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
X-COMMENT: Main-Class will be added automatically by build
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +0,0 @@
|
||||||
build.xml.data.CRC32=fdad8e2e
|
|
||||||
build.xml.script.CRC32=1cd81838
|
|
||||||
build.xml.stylesheet.CRC32=8064a381@1.74.1.48
|
|
||||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
|
||||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
|
||||||
nbproject/build-impl.xml.data.CRC32=fdad8e2e
|
|
||||||
nbproject/build-impl.xml.script.CRC32=95faf5a3
|
|
||||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48
|
|
|
@ -1,73 +0,0 @@
|
||||||
annotation.processing.enabled=true
|
|
||||||
annotation.processing.enabled.in.editor=false
|
|
||||||
annotation.processing.processor.options=
|
|
||||||
annotation.processing.processors.list=
|
|
||||||
annotation.processing.run.all.processors=true
|
|
||||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
|
||||||
build.classes.dir=${build.dir}/classes
|
|
||||||
build.classes.excludes=**/*.java,**/*.form
|
|
||||||
# This directory is removed when the project is cleaned:
|
|
||||||
build.dir=build
|
|
||||||
build.generated.dir=${build.dir}/generated
|
|
||||||
build.generated.sources.dir=${build.dir}/generated-sources
|
|
||||||
# Only compile against the classpath explicitly listed here:
|
|
||||||
build.sysclasspath=ignore
|
|
||||||
build.test.classes.dir=${build.dir}/test/classes
|
|
||||||
build.test.results.dir=${build.dir}/test/results
|
|
||||||
# Uncomment to specify the preferred debugger connection transport:
|
|
||||||
#debug.transport=dt_socket
|
|
||||||
debug.classpath=\
|
|
||||||
${run.classpath}
|
|
||||||
debug.test.classpath=\
|
|
||||||
${run.test.classpath}
|
|
||||||
# Files in build.classes.dir which should be excluded from distribution jar
|
|
||||||
dist.archive.excludes=
|
|
||||||
# This directory is removed when the project is cleaned:
|
|
||||||
dist.dir=dist
|
|
||||||
dist.jar=${dist.dir}/CommandTerminal.jar
|
|
||||||
dist.javadoc.dir=${dist.dir}/javadoc
|
|
||||||
excludes=
|
|
||||||
includes=**
|
|
||||||
jar.compress=false
|
|
||||||
javac.classpath=
|
|
||||||
# Space-separated list of extra javac options
|
|
||||||
javac.compilerargs=
|
|
||||||
javac.deprecation=false
|
|
||||||
javac.processorpath=\
|
|
||||||
${javac.classpath}
|
|
||||||
javac.source=1.8
|
|
||||||
javac.target=1.8
|
|
||||||
javac.test.classpath=\
|
|
||||||
${javac.classpath}:\
|
|
||||||
${build.classes.dir}
|
|
||||||
javac.test.processorpath=\
|
|
||||||
${javac.test.classpath}
|
|
||||||
javadoc.additionalparam=
|
|
||||||
javadoc.author=false
|
|
||||||
javadoc.encoding=${source.encoding}
|
|
||||||
javadoc.noindex=false
|
|
||||||
javadoc.nonavbar=false
|
|
||||||
javadoc.notree=false
|
|
||||||
javadoc.private=false
|
|
||||||
javadoc.splitindex=true
|
|
||||||
javadoc.use=true
|
|
||||||
javadoc.version=false
|
|
||||||
javadoc.windowtitle=
|
|
||||||
main.class=commandterminal.CommandTerminal
|
|
||||||
manifest.file=manifest.mf
|
|
||||||
meta.inf.dir=${src.dir}/META-INF
|
|
||||||
mkdist.disabled=false
|
|
||||||
platform.active=default_platform
|
|
||||||
run.classpath=\
|
|
||||||
${javac.classpath}:\
|
|
||||||
${build.classes.dir}
|
|
||||||
# Space-separated list of JVM arguments used when running the project.
|
|
||||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
|
||||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
|
||||||
run.jvmargs=
|
|
||||||
run.test.classpath=\
|
|
||||||
${javac.test.classpath}:\
|
|
||||||
${build.test.classes.dir}
|
|
||||||
source.encoding=UTF-8
|
|
||||||
src.dir=src
|
|
||||||
test.src.dir=test
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
|
||||||
<type>org.netbeans.modules.java.j2seproject</type>
|
|
||||||
<configuration>
|
|
||||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
|
||||||
<name>CommandTerminal</name>
|
|
||||||
<source-roots>
|
|
||||||
<root id="src.dir"/>
|
|
||||||
</source-roots>
|
|
||||||
<test-roots>
|
|
||||||
<root id="test.src.dir"/>
|
|
||||||
</test-roots>
|
|
||||||
</data>
|
|
||||||
</configuration>
|
|
||||||
</project>
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package commandterminal;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.DatagramPacket;
|
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author lmascaro
|
|
||||||
*/
|
|
||||||
public class CommandTerminal {
|
|
||||||
|
|
||||||
private final static int SGCA_MULTICAST_PORT = 4446;
|
|
||||||
private final static String SCGA_MULTICAST_ADDRESS = "224.0.0.3";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param args the command line arguments
|
|
||||||
*/
|
|
||||||
public static void main(String[] args){
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handshake
|
|
||||||
*/
|
|
||||||
|
|
||||||
try {
|
|
||||||
DatagramSocket socket = new DatagramSocket();
|
|
||||||
ByteBuffer buf = ByteBuffer.allocate(21);
|
|
||||||
buf.clear();
|
|
||||||
buf.put((byte)(0x01|0x02));
|
|
||||||
|
|
||||||
DatagramPacket payload = new DatagramPacket(buf.array(),buf.array().length,InetAddress.getByName(SCGA_MULTICAST_ADDRESS),SGCA_MULTICAST_PORT);
|
|
||||||
socket.send(payload);
|
|
||||||
|
|
||||||
socket.receive(payload);
|
|
||||||
|
|
||||||
buf = ByteBuffer.wrap(payload.getData());
|
|
||||||
|
|
||||||
if(buf.get() == 3){
|
|
||||||
System.out.println("--Connection request successful");
|
|
||||||
byte address[] = new byte[15];
|
|
||||||
buf = buf.get(address,0,15);
|
|
||||||
String addressString = new String(address);
|
|
||||||
InetAddress sgcaAddress = InetAddress.getByName(addressString);
|
|
||||||
//emulate an unsigned short
|
|
||||||
char cast = buf.getChar();
|
|
||||||
int port = (int) cast;
|
|
||||||
System.out.println("----Address : "+sgcaAddress.getHostAddress());
|
|
||||||
System.out.println("----Port : "+port);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch ( IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package commandterminal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author lmascaro
|
|
||||||
*/
|
|
||||||
public enum OpCode {
|
|
||||||
ISALIVE,
|
|
||||||
CAP,
|
|
||||||
ALT,
|
|
||||||
SPEED,
|
|
||||||
SUCCESS,
|
|
||||||
ERROR
|
|
||||||
}
|
|
Binary file not shown.
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class ControlTerminal {
|
||||||
|
|
||||||
|
private final static int SGCA_MULTICAST_PORT = 4446;
|
||||||
|
private final static String SCGA_MULTICAST_ADDRESS = "224.0.0.3";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args the command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args){
|
||||||
|
System.out.println("\033[2J");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handshake
|
||||||
|
*/
|
||||||
|
int port = 0;
|
||||||
|
String addressString = "0.0.0.0";
|
||||||
|
|
||||||
|
try {
|
||||||
|
DatagramSocket socket = new DatagramSocket();
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(21);
|
||||||
|
buf.clear();
|
||||||
|
buf.put((byte)(0x05));
|
||||||
|
|
||||||
|
DatagramPacket payload = new DatagramPacket(buf.array(),buf.array().length,InetAddress.getByName(SCGA_MULTICAST_ADDRESS),SGCA_MULTICAST_PORT);
|
||||||
|
socket.send(payload);
|
||||||
|
|
||||||
|
socket.receive(payload);
|
||||||
|
|
||||||
|
buf = ByteBuffer.wrap(payload.getData());
|
||||||
|
if(buf.get() == 5){
|
||||||
|
System.out.println("--Connection request successful");
|
||||||
|
byte address[] = new byte[4];
|
||||||
|
buf = buf.get(address,0,4);
|
||||||
|
InetAddress addressObj = InetAddress.getByAddress(address);
|
||||||
|
addressString = addressObj.getHostAddress();
|
||||||
|
//emulate an unsigned short
|
||||||
|
char cast = buf.getChar();
|
||||||
|
port = (int) cast;
|
||||||
|
System.out.println("----Address : "+addressString);
|
||||||
|
System.out.println("----Port : "+port);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch ( IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opening final socket
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
//create all objects
|
||||||
|
AsynchronousDatagramSocket socket = new AsynchronousDatagramSocket();
|
||||||
|
PlaneContainer container = new PlaneContainer();
|
||||||
|
Printer printer = new Printer();
|
||||||
|
Pinger pinger = new Pinger(socket,InetAddress.getByName(addressString),port);
|
||||||
|
|
||||||
|
//bind them
|
||||||
|
socket.bindContainer(container);
|
||||||
|
container.bindPrinter(printer);
|
||||||
|
container.bindSocket(socket);
|
||||||
|
printer.bindContainer(container);
|
||||||
|
|
||||||
|
|
||||||
|
//send first packet
|
||||||
|
InetAddress SGCAaddress = InetAddress.getByName(addressString);
|
||||||
|
DatagramPacket p = new DatagramPacket(new byte[13],13,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("First packet sent");
|
||||||
|
|
||||||
|
//send first feedback packet
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(27);
|
||||||
|
buf.put((byte) 0x01);
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("Feedback request sent");
|
||||||
|
|
||||||
|
System.out.println("length: "+"aze".getBytes().length);
|
||||||
|
|
||||||
|
//run Pinger
|
||||||
|
new Thread(pinger).start();
|
||||||
|
|
||||||
|
//now we let the objects do the job
|
||||||
|
Scanner s = new Scanner(System.in);
|
||||||
|
int planeNumber;
|
||||||
|
int data;
|
||||||
|
Plane plane;
|
||||||
|
ArrayList<String> keys;
|
||||||
|
byte flags;
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
String input = s.nextLine();
|
||||||
|
if(input.length() == 0){
|
||||||
|
//if empty line, we send a feedback request
|
||||||
|
buf = ByteBuffer.allocate(27);
|
||||||
|
buf.put((byte) 0x01);
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("Request sent, waiting for response");
|
||||||
|
|
||||||
|
}else if(input.equals("u")){
|
||||||
|
System.out.println("Please enter plane number");
|
||||||
|
try{
|
||||||
|
planeNumber = s.nextInt();
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("Wrong input please retry");
|
||||||
|
s.nextLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
keys = new ArrayList(container.getMap().keySet());
|
||||||
|
plane = container.getMap().get(keys.get(planeNumber-1));
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("Unknown plane please retry");
|
||||||
|
s.nextLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
flags = 0x01;
|
||||||
|
while(true){
|
||||||
|
System.out.println("Enter the information you want to update (1: alt,2:cap,3:speed)");
|
||||||
|
try{
|
||||||
|
data = s.nextInt();
|
||||||
|
switch(data){
|
||||||
|
case 1:
|
||||||
|
System.out.println("Enter the new altitude");
|
||||||
|
data = s.nextInt();
|
||||||
|
plane.setZ(data);
|
||||||
|
flags = (byte) (flags|0x08);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
System.out.println("Enter the new cap");
|
||||||
|
data = s.nextInt();
|
||||||
|
plane.setCap(data);
|
||||||
|
flags = (byte) (flags|0x02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
System.out.println("Enter the new speed");
|
||||||
|
data = s.nextInt();
|
||||||
|
plane.setSpeed(data);
|
||||||
|
flags = (byte) (flags|0x04);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("Wrong input please retry");
|
||||||
|
s.nextLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("Wrong input please retry");
|
||||||
|
s.nextLine();
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println("Do you want to update more data on this plane (y/n)");
|
||||||
|
|
||||||
|
if(s.next().equals("n")){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container.setExpectedFlags(flags);
|
||||||
|
buf = ByteBuffer.allocate(27);
|
||||||
|
buf.put(flags);
|
||||||
|
buf.put(plane.toBytes());
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("Request sent, waiting for response");
|
||||||
|
s.nextLine();
|
||||||
|
}else{
|
||||||
|
System.out.println("Unknown command, please retry");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
public class InvalidFlagException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidFlagException(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidFlagException(String message){
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
public class Pinger implements Runnable{
|
||||||
|
|
||||||
|
private AsynchronousDatagramSocket socket;
|
||||||
|
private InetAddress addr;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
public Pinger(AsynchronousDatagramSocket socket,InetAddress addr,int port){
|
||||||
|
this.socket = socket;
|
||||||
|
this.addr = addr;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DatagramPacket p;
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(27);
|
||||||
|
while(true){
|
||||||
|
try {
|
||||||
|
Thread.sleep(8000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,this.addr,this.port);
|
||||||
|
try {
|
||||||
|
this.socket.send(p);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class Plane{
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
private int z;
|
||||||
|
private int cap;
|
||||||
|
private int speed;
|
||||||
|
|
||||||
|
private boolean isDead;
|
||||||
|
|
||||||
|
public Plane(String code,int x, int y, int z, int cap, int speed){
|
||||||
|
this.code = code;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.cap = cap;
|
||||||
|
this.speed = speed;
|
||||||
|
this.isDead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZ(int z) {
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCap() {
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDead(){
|
||||||
|
return this.isDead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCap(int cap) {
|
||||||
|
this.cap = cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpeed(int speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Die Motherfucker
|
||||||
|
public void die(){
|
||||||
|
this.isDead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLine(int i){
|
||||||
|
switch(i){
|
||||||
|
case 0:
|
||||||
|
return "--------------------------------";
|
||||||
|
case 1:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m Code: "+this.code+"\t\t\t|";
|
||||||
|
}else{
|
||||||
|
return "\033[4;37;42m Code: "+this.code+"\t\t\t|";
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
return "\033[0m --Coords: {"+this.x+";"+this.y+";"+this.z+"} \t|";
|
||||||
|
case 3:
|
||||||
|
return "\033[0m --Cap: "+this.cap+"\t\t\t|";
|
||||||
|
case 4:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m ATTENTION: avion hors ligne\t|\033[0m";
|
||||||
|
}else if(this.speed<300){
|
||||||
|
return "\033[5;37;41m --Speed: "+this.speed+"\t\t\t|\033[0m";
|
||||||
|
}else{
|
||||||
|
return "\033[0m --Speed: "+this.speed+"\t\t\t|";
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toBytes(){
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(26);
|
||||||
|
buf.put(this.code.getBytes());
|
||||||
|
//EOL char
|
||||||
|
buf.put((byte)0);
|
||||||
|
buf.putInt(this.x);
|
||||||
|
buf.putInt(this.y);
|
||||||
|
buf.putInt(this.z);
|
||||||
|
buf.putInt(this.cap);
|
||||||
|
buf.putInt(this.speed);
|
||||||
|
|
||||||
|
return buf.array();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
public class PlaneContainer {
|
||||||
|
|
||||||
|
private HashMap<String,Plane> map;
|
||||||
|
private AsynchronousDatagramSocket socket;
|
||||||
|
private Printer printer;
|
||||||
|
private byte expectedFlags = 0x01;
|
||||||
|
|
||||||
|
public PlaneContainer(){
|
||||||
|
this.map = new HashMap<String,Plane>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindSocket(AsynchronousDatagramSocket s){
|
||||||
|
this.socket = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindPrinter(Printer p){
|
||||||
|
this.printer = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpectedFlags(byte flags){
|
||||||
|
this.expectedFlags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyReceive() throws InvalidFlagException{
|
||||||
|
DatagramPacket packet = this.socket.synchronousReceive();
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.wrap(packet.getData());
|
||||||
|
|
||||||
|
byte flag;
|
||||||
|
byte nbrPlane;
|
||||||
|
ArrayList<String> codes;
|
||||||
|
|
||||||
|
flag = buf.get();
|
||||||
|
nbrPlane = buf.get();
|
||||||
|
|
||||||
|
codes = new ArrayList<String>(nbrPlane);
|
||||||
|
|
||||||
|
//System.out.println("Processing "+nbrPlane+" planes");
|
||||||
|
|
||||||
|
if(this.expectedFlags != flag){
|
||||||
|
if((this.expectedFlags&(byte)0x02) == 2 && (flag&(byte)0x02) != 2){
|
||||||
|
System.out.println("\033[5;37;41m Could not apply cap \033[0m");
|
||||||
|
}
|
||||||
|
if((this.expectedFlags&(byte)0x04) == 4 && (flag&(byte)0x04) != 4){
|
||||||
|
System.out.println("\033[5;37;41m Could not apply speed \033[0m");
|
||||||
|
}
|
||||||
|
if((this.expectedFlags&(byte)0x08) == 8 && (flag&(byte)0x08) != 8){
|
||||||
|
System.out.println("\033[5;37;41m Could not apply alt \033[0m");
|
||||||
|
}
|
||||||
|
System.out.println("\033[5;37;41m One or more fields could not be updated \033[0m");
|
||||||
|
if((flag&(byte)0x10) == 1){
|
||||||
|
System.out.println("\033[5;37;41m Plane crashed gracefully \033[0m");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.expectedFlags = 0x01;
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flag == 0){
|
||||||
|
//this is a ping response
|
||||||
|
return;
|
||||||
|
}else if((flag&(byte)0x01) != 1){
|
||||||
|
throw new InvalidFlagException("Flag is not a feedback flag :"+flag);
|
||||||
|
}else{
|
||||||
|
String code;
|
||||||
|
byte rawCode[] = new byte[5];
|
||||||
|
Plane plane;
|
||||||
|
for(int i = 0;i<nbrPlane;i++){
|
||||||
|
//get plane code
|
||||||
|
buf = buf.get(rawCode,0,5);
|
||||||
|
code = new String(rawCode);
|
||||||
|
plane = this.map.get(code);
|
||||||
|
codes.add(code);
|
||||||
|
|
||||||
|
//remove EOL char
|
||||||
|
buf.get();
|
||||||
|
|
||||||
|
if(plane != null){
|
||||||
|
//fill the plane
|
||||||
|
plane.setX(buf.getInt());
|
||||||
|
plane.setY(buf.getInt());
|
||||||
|
plane.setZ(buf.getInt());
|
||||||
|
plane.setCap(buf.getInt());
|
||||||
|
plane.setSpeed(buf.getInt());
|
||||||
|
}else{
|
||||||
|
plane = new Plane(code,buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt());
|
||||||
|
this.map.put(code, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check for dead planes
|
||||||
|
for(String code : this.map.keySet()){
|
||||||
|
if(!codes.contains(code)){
|
||||||
|
this.map.get(code).die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.printer.notifyReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String,Plane> getMap(){
|
||||||
|
return this.map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Printer {
|
||||||
|
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
|
public Printer(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void notifyReceive(){
|
||||||
|
System.out.println("\033[2J \033[H");
|
||||||
|
HashMap<String,Plane> map = this.container.getMap();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
String lines[] = new String[5];
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(map.keySet().size() == 0){
|
||||||
|
System.out.println("\033[37;43m No plane connected \033[0m");
|
||||||
|
}else{
|
||||||
|
for(String code : map.keySet()){
|
||||||
|
if(i <= 1){
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}else{
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Please enter your command (ENTER to update data, u to update a plane)");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package DatagramSocket;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import ControlTerminal.InvalidFlagException;
|
||||||
|
import ControlTerminal.PlaneContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
||||||
|
|
||||||
|
public final static int MAX_MESSAGE_SIZE = 300;
|
||||||
|
|
||||||
|
private SynchronizedBuffer<DatagramPacket> buf;
|
||||||
|
private DatagramSocket socket;
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
|
public AsynchronousDatagramSocket() throws SocketException{
|
||||||
|
this.buf = new SynchronizedBuffer<>();
|
||||||
|
this.socket = new DatagramSocket();
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsynchronousDatagramSocket(int port) throws SocketException{
|
||||||
|
this.buf = new SynchronizedBuffer<>();
|
||||||
|
this.socket = new DatagramSocket(port);
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(DatagramPacket dp) throws IOException{
|
||||||
|
this.socket.send(dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean asynchronousReceive(DatagramPacket dp){
|
||||||
|
if(this.buf.available() == 0){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
dp = this.buf.removeElement(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatagramPacket synchronousReceive(){
|
||||||
|
return this.buf.removeElement(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean available(){
|
||||||
|
return this.buf.available()>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(){
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DatagramPacket packet;
|
||||||
|
while(true){
|
||||||
|
packet = new DatagramPacket(new byte[MAX_MESSAGE_SIZE],MAX_MESSAGE_SIZE);
|
||||||
|
try {
|
||||||
|
this.socket.receive(packet);
|
||||||
|
this.buf.addElement(packet);
|
||||||
|
this.container.notifyReceive();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(AsynchronousDatagramSocket.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (InvalidFlagException e) {
|
||||||
|
System.out.println("\033[01;31m Unexpected flag received \033[0m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,5 +23,5 @@ all: boot
|
||||||
|
|
||||||
# cleans the compiled files
|
# cleans the compiled files
|
||||||
clean:
|
clean:
|
||||||
rm boot;
|
@rm ./lib/network/**/*.o;
|
||||||
rm ./lib/network/**/*.o
|
@rm ./boot;
|
||||||
|
|
|
@ -10,10 +10,11 @@
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
|
|
||||||
int TCP_CONNECT(int* pSocket, const char* 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
|
/* [0] Initialisation des variables
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
|
struct timeval timeout;
|
||||||
*pSocket = -1;
|
*pSocket = -1;
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +27,16 @@ int TCP_CONNECT(int* pSocket, const char* pAddr, const int pPort, struct sockadd
|
||||||
if( *pSocket < 0 )
|
if( *pSocket < 0 )
|
||||||
return -1;
|
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
|
/* [2] On définit les infos de la socket
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
|
@ -35,7 +46,7 @@ int TCP_CONNECT(int* pSocket, const char* pAddr, const int pPort, struct sockadd
|
||||||
/* (2) On définit les infos */
|
/* (2) On définit les infos */
|
||||||
pInfo->sin_family = AF_INET;
|
pInfo->sin_family = AF_INET;
|
||||||
pInfo->sin_port = htons(pPort);
|
pInfo->sin_port = htons(pPort);
|
||||||
pInfo->sin_addr.s_addr = inet_addr(pAddr);
|
pInfo->sin_addr.s_addr = pAddr;
|
||||||
|
|
||||||
|
|
||||||
/* [3] On se connecte au serveur
|
/* [3] On se connecte au serveur
|
||||||
|
|
|
@ -18,8 +18,9 @@
|
||||||
/* Créée une socket TCP et la connecte + crée le sockaddr_in pour la suite
|
/* Créée une socket TCP et la connecte + crée le sockaddr_in pour la suite
|
||||||
*
|
*
|
||||||
* ==IN==
|
* ==IN==
|
||||||
* @pAddr<const char*> Adresse du serveur TCP
|
* @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==
|
* ==OUT==
|
||||||
* @pSocket<int*> Pointeur sur le <int> à remplir => contiendra un pointeur sur la socket créée
|
* @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
|
* [3] On se connecte au serveur
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int TCP_CONNECT(int* pSocket, const char* 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
|
#endif
|
|
@ -35,7 +35,13 @@ int DROP_MULTICAST_SERVER(const char* pAddr, const int pPort, int* pListenSock,
|
||||||
timeout.tv_sec = SOCK_TIMEOUT;
|
timeout.tv_sec = SOCK_TIMEOUT;
|
||||||
timeout.tv_usec = 0;
|
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);
|
close(*pListenSock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
200
plane/plane.c
200
plane/plane.c
|
@ -31,6 +31,7 @@ int open_communication(){
|
||||||
char buffer[MAX_BUF_LEN] = {0}; // buffer
|
char buffer[MAX_BUF_LEN] = {0}; // buffer
|
||||||
int status;
|
int status;
|
||||||
struct bind_header request;
|
struct bind_header request;
|
||||||
|
struct in_addr ip; // pour afficher l'ip en dot notation
|
||||||
|
|
||||||
/* [1] Socket Multicast UDP
|
/* [1] Socket Multicast UDP
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
|
@ -38,8 +39,13 @@ int open_communication(){
|
||||||
|
|
||||||
/* (1) Création socket multicast client* (écoute)
|
/* (1) Création socket multicast client* (écoute)
|
||||||
---------------------------------------------------------*/
|
---------------------------------------------------------*/
|
||||||
if( DROP_MULTICAST_SERVER(MCST_HOST, MCST_PORT, &mcast_socket, &udp) < 0 )
|
if( DROP_MULTICAST_SERVER(MCST_HOST, MCST_PORT, &mcast_socket, &udp) < 0 ){
|
||||||
|
printf("/!\\ Cannot drop multicast server\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("* Multicast server bound to multicast group\n");
|
||||||
|
|
||||||
// *un client multicast est en fait un serveur UDP, mais le terme persiste car le service est délivré par le CLIENT UDP
|
// *un client multicast est en fait un serveur UDP, mais le terme persiste car le service est délivré par le CLIENT UDP
|
||||||
|
|
||||||
|
@ -52,26 +58,39 @@ int open_communication(){
|
||||||
/* 2. Gestion erreur */
|
/* 2. Gestion erreur */
|
||||||
if( status < 0 ){
|
if( status < 0 ){
|
||||||
close(mcast_socket);
|
close(mcast_socket);
|
||||||
|
printf("/!\\ Cannot get TCP credentials (ip/port)\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3. Vérification taille */
|
/* 3. Vérification taille */
|
||||||
if( status < BINDHDR_LEN ){
|
if( status < BINDHDR_LEN ){
|
||||||
close(mcast_socket);
|
close(mcast_socket);
|
||||||
|
printf("/!\\ Invalid TCP credentials (ip/port)\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 4. On récupère les données */
|
/* 4. On récupère les données */
|
||||||
bzero(&request, sizeof(struct bind_header));
|
bzero(&request, sizeof(struct bind_header));
|
||||||
|
|
||||||
memcpy(&request.addr, buffer, sizeof(char) );
|
memcpy(&request.flags, buffer, sizeof(char) );
|
||||||
memcpy(&request.addr, buffer+sizeof(char), sizeof(char)*INET_ADDRSTRLEN );
|
memcpy(&request.addr, buffer+sizeof(char), sizeof(in_addr_t) );
|
||||||
memcpy(&request.port, buffer+sizeof(char)*(1+INET_ADDRSTRLEN), sizeof(unsigned short) );
|
memcpy(&request.port, buffer+sizeof(char)+sizeof(in_addr_t), sizeof(unsigned short) );
|
||||||
|
|
||||||
// on indian-switch
|
// on indian-switch
|
||||||
|
request.addr = ntohl(request.addr);
|
||||||
request.port = ntohs(request.port);
|
request.port = ntohs(request.port);
|
||||||
|
ip.s_addr = request.addr;
|
||||||
|
|
||||||
|
/* 5. On vérifie les flags */
|
||||||
|
if( !(request.flags&BINDHEAD_TCP) || request.flags&BINDHEAD_UDP ){
|
||||||
|
close(mcast_socket);
|
||||||
|
printf("/!\\ Received incorrect TCP credentials (ip/port)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// printf("* hex("); for( int i = 0 ; i < BINDHDR_LEN/sizeof(char) ; i++ ) printf("\\x%02X", buffer[i]); printf(")\n");
|
// 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 = %s; port = %d;}\n\n", request.flags, request.addr, request.port);
|
printf("* Received TCP credentials (flags: %x, ip: %s:%d)\n", request.flags, inet_ntoa(ip), request.port);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,8 +103,12 @@ int open_communication(){
|
||||||
/* (1) Création socket TCP + connection
|
/* (1) Création socket TCP + connection
|
||||||
---------------------------------------------------------*/
|
---------------------------------------------------------*/
|
||||||
/* 1. Création socket TCP + connection serveur */
|
/* 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 ){
|
||||||
|
printf("/!\\ Can't connect to TCP socket\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("* Connected to TCP server\n");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -93,12 +116,25 @@ int open_communication(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void close_communication(){
|
void close_communication(){
|
||||||
// fonction à implémenter qui permet de fermer la communication
|
// fonction à implémenter qui permet de fermer la communication
|
||||||
// avec le gestionnaire de vols
|
// avec le gestionnaire de vols
|
||||||
|
if( commu_socket > -1 )
|
||||||
|
close(commu_socket);
|
||||||
|
|
||||||
|
printf("=== PLANE CRASHED ===\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_data(){
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void send_data(char flags){
|
||||||
|
|
||||||
/* [0] Initialisation des variables
|
/* [0] Initialisation des variables
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
|
@ -106,7 +142,6 @@ void send_data(){
|
||||||
struct plane_data request;
|
struct plane_data request;
|
||||||
int read;
|
int read;
|
||||||
|
|
||||||
|
|
||||||
/* [1] Envoi des caractéristiques
|
/* [1] Envoi des caractéristiques
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
/* 1. Vérification socket */
|
/* 1. Vérification socket */
|
||||||
|
@ -115,39 +150,29 @@ void send_data(){
|
||||||
|
|
||||||
/* 2. création objet */
|
/* 2. création objet */
|
||||||
strcpy(request.code, numero_vol);
|
strcpy(request.code, numero_vol);
|
||||||
request.x = crd.x;
|
request.x = htonl( crd.x );
|
||||||
request.y = crd.y;
|
request.y = htonl( crd.y );
|
||||||
request.z = crd.z;
|
request.z = htonl( crd.z );
|
||||||
request.cap = ctrl.cap;
|
request.cap = htonl( ctrl.cap );
|
||||||
request.spd = ctrl.speed;
|
request.spd = htonl( ctrl.speed );
|
||||||
|
|
||||||
/* 3. Copie buffer */
|
/* 3. Copie buffer */
|
||||||
strcpy(buffer, request.code);
|
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &flags, sizeof(char) );
|
||||||
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &request.code, sizeof(char)*6 );
|
memcpy(buffer+sizeof(char)*1+sizeof(int)*0, &request.code, sizeof(char)*6 );
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*0, &request.x, sizeof(int) );
|
memcpy(buffer+sizeof(char)*7+sizeof(int)*0, &request.x, sizeof(int) );
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*1, &request.y, sizeof(int) );
|
memcpy(buffer+sizeof(char)*7+sizeof(int)*1, &request.y, sizeof(int) );
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*2, &request.z, sizeof(int) );
|
memcpy(buffer+sizeof(char)*7+sizeof(int)*2, &request.z, sizeof(int) );
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*3, &request.cap, sizeof(int) );
|
memcpy(buffer+sizeof(char)*7+sizeof(int)*3, &request.cap, sizeof(int) );
|
||||||
memcpy(buffer+sizeof(char)*6+sizeof(int)*4, &request.spd, sizeof(int) );
|
memcpy(buffer+sizeof(char)*7+sizeof(int)*4, &request.spd, sizeof(int) );
|
||||||
|
|
||||||
read = send(commu_socket, buffer, PLANE_DATA_LEN/sizeof(char) + 1, 0);
|
read = send(commu_socket, buffer, (1+PLANE_DATA_LEN)/sizeof(char), 0);
|
||||||
|
|
||||||
if( read <= 0 ){
|
if( read <= 0 ){
|
||||||
printf("Erreur d'envoi\n");
|
printf("Cannot send\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// printf("* hex("); for( int i = 0 ; i < PLANE_DATA_LEN/sizeof(char) ; i++ ) printf("\\x%02X", buffer[i]); printf(")\n");
|
// 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
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +181,10 @@ void send_data(){
|
||||||
********************************/
|
********************************/
|
||||||
|
|
||||||
// initialise aléatoirement les paramètres initiaux de l'plane
|
// initialise aléatoirement les paramètres initiaux de l'plane
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void init_plane(){
|
void init_plane(){
|
||||||
// initialisation aléatoire du compteur aléatoire
|
// initialisation aléatoire du compteur aléatoire
|
||||||
time_t seed;
|
time_t seed;
|
||||||
|
@ -181,28 +210,61 @@ void init_plane(){
|
||||||
}
|
}
|
||||||
|
|
||||||
// modifie la valeur de l'plane avec la valeur passée en paramètre
|
// 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
|
// 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;
|
ctrl.cap = cap;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// modifie l'z de l'plane avec la valeur passée en paramètre
|
// 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 )
|
if( alt < 0 )
|
||||||
|
return 01;
|
||||||
|
|
||||||
crd.z = alt;
|
crd.z = alt;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// affiche les caractéristiques courantes de l'plane
|
// affiche les caractéristiques courantes de l'plane
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void display_data(){
|
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 | (%d,%d,%d) - speed: %d - cap: %d\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
|
// recalcule la localisation de l'plane en fonction de sa speed et de son cap
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void calc_ctrl(){
|
void calc_ctrl(){
|
||||||
float ctrl_x, ctrl_y;
|
float ctrl_x, ctrl_y;
|
||||||
|
|
||||||
|
@ -234,13 +296,67 @@ void calc_ctrl(){
|
||||||
}
|
}
|
||||||
|
|
||||||
// fonction principale : gère l'exécution de l'plane au fil du temps
|
// fonction principale : gère l'exécution de l'plane au fil du temps
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void update(){
|
void update(){
|
||||||
|
int received;
|
||||||
|
struct sgca_req request;
|
||||||
|
char buffer[MAX_BUF_LEN] = {0};
|
||||||
|
char persistentFlags = REQ_OFF;
|
||||||
|
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
|
|
||||||
sleep(PAUSE);
|
|
||||||
calc_ctrl();
|
calc_ctrl();
|
||||||
send_data();
|
send_data(persistentFlags);
|
||||||
|
persistentFlags = REQ_OFF;
|
||||||
|
|
||||||
|
/* [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 != (sizeof(char)+3*sizeof(int)) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
printf("** Received update request **\n");
|
||||||
|
|
||||||
|
|
||||||
|
/* [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_speed(request.spd) == -1 )
|
||||||
|
request.flags -= REQ_SPD;
|
||||||
|
|
||||||
|
if( request.flags&REQ_CAP )
|
||||||
|
if( update_cap(request.cap) == -1 )
|
||||||
|
request.flags -= REQ_CAP;
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Gestion des flags persistents
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. On remplit le champ */
|
||||||
|
persistentFlags = request.flags;
|
||||||
|
printf("Response flags : %d\n", request.flags);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,10 +369,14 @@ int main(){
|
||||||
display_data();
|
display_data();
|
||||||
|
|
||||||
// on quitte si on arrive à pas contacter le gestionnaire de vols
|
// on quitte si on arrive à pas contacter le gestionnaire de vols
|
||||||
|
printf("\n=== CONNECTION PROTOCOL ===\n");
|
||||||
if( !open_communication() ){
|
if( !open_communication() ){
|
||||||
|
printf("/!\\ Cannot connect to SGCA.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// on se déplace une fois toutes les initialisations faites
|
// on se déplace une fois toutes les initialisations faites
|
||||||
|
printf("\n=== COMMUNICATION PROTOCOL ===\n");
|
||||||
update();
|
update();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
|
@ -49,14 +49,27 @@
|
||||||
int spd;
|
int spd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BINDHDR_LEN ( sizeof(char)*(1+INET_ADDRSTRLEN)+sizeof(unsigned short) )
|
#define REQ_FBK 0x01
|
||||||
#define BINDHEAD_CTL 0x01 // is command terminal (else: view terminal)
|
#define REQ_CAP 0x02
|
||||||
#define BINDHEAD_SCK 0x02 // ask for com socket
|
#define REQ_SPD 0x04
|
||||||
#define BINDHEAD_TCP 0x04 // ask TCP instead of UDP
|
#define REQ_ALT 0x08
|
||||||
|
#define REQ_OFF 0x10
|
||||||
|
|
||||||
|
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)
|
||||||
|
#define BINDHEAD_CTL 0x04 // is ctrlTerm (else: viewTerm)
|
||||||
|
|
||||||
struct bind_header{
|
struct bind_header{
|
||||||
char flags;
|
char flags;
|
||||||
char addr[INET_ADDRSTRLEN];
|
in_addr_t addr;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
.vscode
|
||||||
|
*.o
|
||||||
|
boot
|
|
@ -21,10 +21,13 @@ lib/local/middleware.o: lib/header.h lib/local/middleware.h lib/local/middleware
|
||||||
lib/local/handler.o: lib/header.h lib/local/handler.h lib/local/handler.c
|
lib/local/handler.o: lib/header.h lib/local/handler.h lib/local/handler.c
|
||||||
gcc $(CFLAGS) -c -o lib/local/handler.o lib/local/handler.c
|
gcc $(CFLAGS) -c -o lib/local/handler.o lib/local/handler.c
|
||||||
|
|
||||||
|
lib/network/common.o: lib/header.h lib/network/common.h lib/network/common.c
|
||||||
|
gcc $(CFLAGS) -c -o lib/network/common.o lib/network/common.c
|
||||||
|
|
||||||
|
|
||||||
# Compiles the SGCA
|
# Compiles the SGCA
|
||||||
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
|
boot: lib/network/common.o 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
|
gcc $(CFLAGS) -o boot lib/network/udp/server.o lib/network/udp/client.o lib/network/common.o lib/network/tcp/server.o lib/local/middleware.o lib/local/handler.o central-manager.c
|
||||||
|
|
||||||
|
|
||||||
# Run full compilation
|
# Run full compilation
|
||||||
|
@ -32,6 +35,7 @@ all: boot
|
||||||
|
|
||||||
# cleans the compiled files
|
# cleans the compiled files
|
||||||
clean:
|
clean:
|
||||||
rm boot;
|
@rm lib/network/*.o;
|
||||||
rm lib/network/**/*.o;
|
@rm lib/network/**/*.o;
|
||||||
rm lib/local/*.o;
|
@rm lib/local/*.o;
|
||||||
|
@rm boot;
|
|
@ -17,60 +17,75 @@
|
||||||
* [0] Initialisation des variables
|
* [0] Initialisation des variables
|
||||||
* [1] Lancement des THREADS d'écoute
|
* [1] Lancement des THREADS d'écoute
|
||||||
* 1. On démarre le SERVEUR TCP d'écoute globale
|
* 1. On démarre le SERVEUR TCP d'écoute globale
|
||||||
* 2. On démarre le SERVEUR UDP d'écoute globale
|
* 2. On récupère l'IP locale
|
||||||
|
* 3. On démarre le SERVEUR UDP d'écoute globale
|
||||||
* [2] On attends la fin de tous les THREADS
|
* [2] On attends la fin de tous les THREADS
|
||||||
* [3] On libère les variables globale
|
* [3] On libère les variables globale
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int main(int argc, char* argv[]){
|
int main(int argc, char* argv[]){
|
||||||
|
|
||||||
printf("**** Execution tree structure\n");
|
printf("[Copyright (R) 2017]\n");
|
||||||
printf("** [procedureName]\n");
|
printf(" - Adrien Marquès aka. xdrm-brackets (C shit)\n");
|
||||||
printf("** {threadName}\n");
|
printf(" - Lucas Mascaro aka. SeekDaSky (java shit)\n");
|
||||||
printf("** [parent]{child}[subchild] Description\n\n\n");
|
printf("* From the developers of the 'WebSocket' library for the UPPA University\n\n\n");
|
||||||
|
printf("Notice: {threadName}{subThread}(subThreadId)\n\n");
|
||||||
printf("**** Execution tree\n");
|
printf("**** Execution tree\n");
|
||||||
|
|
||||||
/* [0] Initialisation des variables
|
/* [0] Initialisation des variables
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
/* 1. Variables globales */
|
/* 1. Variables globales */
|
||||||
sgca.n = 0;
|
sgca.n = 0;
|
||||||
sgca.data = (struct plane*) malloc( sizeof(struct plane) );
|
sgca.unit = (struct context_unit*) malloc( sizeof(struct context_unit) );
|
||||||
|
struct in_addr* SERV_HOST;
|
||||||
|
|
||||||
/* 2. Variables locales */
|
/* 2. On récupère l'IP locale' */
|
||||||
struct listen_arg tcp_listn_arg = { SERV_HOST, TCP_LIST, NULL, &managePlane };
|
SERV_HOST = GET_LOCAL_IP();
|
||||||
struct listen_arg udp_mcast_arg = { MCST_HOST, UDP_MCST, NULL, NULL };
|
if( SERV_HOST == NULL ){
|
||||||
struct listen_arg udp_vterm_arg = { MCST_VTER, UDP_VTER, &multicastTerminal, &manageViewTerm };
|
printf("/!\\ Cannot fetch local ip address. Aborting!\n");
|
||||||
struct listen_arg udp_cterm_arg = { MCST_CTER, UDP_CTER, &multicastTerminal, &manageCtrlTerm };
|
free(sgca.unit);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
printf("LOCAL IP: %s\n", inet_ntoa(*SERV_HOST));
|
||||||
|
|
||||||
|
/* 3. Variables locales */
|
||||||
|
struct listen_arg tcp_listn_arg = { SERV_HOST->s_addr, TCP_LIST, NULL, &managePlane };
|
||||||
|
struct listen_arg udp_mcast_arg = { inet_addr(MCST_HOST), UDP_MCST, NULL, NULL };
|
||||||
|
struct listen_arg udp_vterm_arg = { inet_addr(MCST_VTER), UDP_VTER, &multicastTerminal, &manageViewTerm };
|
||||||
|
struct listen_arg udp_cterm_arg = { inet_addr(MCST_CTER), UDP_CTER, &multicastTerminal, &manageCtrlTerm };
|
||||||
|
|
||||||
|
|
||||||
/* [1] Lancement des THREADS d'écoute
|
/* [1] Lancement des THREADS d'écoute
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
/* (1) Ecoute TCP */
|
/* (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");
|
if( DEBUGMOD&THR ) printf("{tcp_listn} started\n");
|
||||||
|
|
||||||
/* (2) Ecoute UDP multicast */
|
/* (2) Ecoute UDP multicast */
|
||||||
pthread_create(&listenManagers[1], NULL, MCAST_PUBLISH, (void*) &udp_mcast_arg);
|
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 */
|
/* (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");
|
if( DEBUGMOD&THR ) printf("{udp_vterm} started\n");
|
||||||
|
|
||||||
/* (4) Ecoute UDP ctrlTerm */
|
/* (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");
|
if( DEBUGMOD&THR ) printf("{udp_cterm} started\n");
|
||||||
|
|
||||||
|
|
||||||
/* [2] On attends la fin de tous les THREADS
|
/* [2] On attends la fin de tous les THREADS
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
for( char i = 0 ; i < 4 ; i++ )
|
char i;
|
||||||
|
for( i = 0 ; i < 4 ; i++ )
|
||||||
pthread_join(listenManagers[(int)i], NULL);
|
pthread_join(listenManagers[(int)i], NULL);
|
||||||
|
|
||||||
|
|
||||||
/* [3] On libère les variables globales
|
/* [3] On libère les variables globales
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
free(sgca.data);
|
free(sgca.unit);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,7 +111,10 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
|
||||||
socklen_t len; // taille de la socket
|
socklen_t len; // taille de la socket
|
||||||
int index, i; // compteurs
|
int index, i; // compteurs
|
||||||
struct listen_arg* arg = THREADABLE_ARGS; // Addr + Port serveur
|
struct listen_arg* arg = THREADABLE_ARGS; // Addr + Port serveur
|
||||||
|
struct in_addr ip; // Pour afficher l'IP en dot notation
|
||||||
|
int rtnPort; // Port utilisé par le serveur
|
||||||
|
|
||||||
|
ip.s_addr = arg->addr;
|
||||||
|
|
||||||
// retour de @DROP_TCP_SERVER
|
// retour de @DROP_TCP_SERVER
|
||||||
int LISTENSOCK; // contiendra la socket d'écoute TCP
|
int LISTENSOCK; // contiendra la socket d'écoute TCP
|
||||||
|
@ -104,12 +122,13 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
/* [1] On démarre le SERVEUR TCP d'écoute globale
|
/* [1] On démarre le SERVEUR TCP d'écoute globale
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
if( DROP_TCP_SERVER(arg->port, &LISTENSOCK) < 0 ){
|
rtnPort = DROP_TCP_SERVER(arg->port, &LISTENSOCK);
|
||||||
|
if( rtnPort < 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
|
// 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);
|
close(LISTENSOCK);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -117,7 +136,9 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printf("{tcp_listn} listen on %s:%d\n", arg->addr, arg->port);
|
printf("{tcp_listn} listen on %s:%d\n", inet_ntoa(ip), rtnPort);
|
||||||
|
if( rtnPort != arg->port )
|
||||||
|
printf("{tcp_listn} /!\\ Another SGCA might be running, port %d is already used\n", arg->port);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +160,7 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
|
||||||
break;
|
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) */
|
/* 4. On cherche un "manager" libre (inactif) */
|
||||||
for( i = 0 ; i < MAX_TCP_THR ; i++ )
|
for( i = 0 ; i < MAX_TCP_THR ; i++ )
|
||||||
|
@ -149,18 +170,18 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
|
||||||
if( index != -1 ){
|
if( index != -1 ){
|
||||||
|
|
||||||
// Construction arguments thread
|
// Construction arguments thread
|
||||||
struct handler_arg thread_args = { TCPManagers, activeTCPManagers, CLIENT_SOCKET, &sgca };
|
struct handler_arg thread_args = { TCPManagers, UDPManagers, activeTCPManagers, activeUDPManagers, CLIENT_SOCKET, &sgca };
|
||||||
|
|
||||||
/* 5. On lance un thread pour le traitement de ce client */
|
/* 5. On lance un thread pour le traitement de ce client */
|
||||||
pthread_create(&TCPManagers[index], NULL, arg->handler, (void*) &thread_args);
|
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 */
|
/* 6. On signale que ce "manager" est maintenant actif */
|
||||||
activeTCPManagers[index] = 1;
|
activeTCPManagers[index] = 1;
|
||||||
|
|
||||||
}else
|
}else
|
||||||
if( DEBUGMOD&THR ) printf("{tcp_listn} Aucun thread libre\n");
|
if( DEBUGMOD&THR ) printf("{tcp_listn} No available thread\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +194,7 @@ void* LISTEN_TCP(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
/* [4] On ferme la SOCKET d'écoute globale
|
/* [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);
|
close(LISTENSOCK);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -212,33 +233,45 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){
|
||||||
char entity[10]; // identifiant pour debug
|
char entity[10]; // identifiant pour debug
|
||||||
int returned; // Contrôle d'exécution middleware
|
int returned; // Contrôle d'exécution middleware
|
||||||
struct middleware_arg marg; // paramètres pour middleware
|
struct middleware_arg marg; // paramètres pour middleware
|
||||||
|
struct in_addr ip; // Permet d'afficher les IP en dot notation
|
||||||
|
int rtnPort; // Returned port (if already used)
|
||||||
|
|
||||||
/* 2. On parse les arguments */
|
/* 2. On parse les arguments */
|
||||||
struct listen_arg* arg = THREADABLE_ARGS; // Addr + Port serveur
|
struct listen_arg* arg = THREADABLE_ARGS; // Addr + Port serveur
|
||||||
|
|
||||||
if( strcmp(arg->addr, MCST_VTER) == 0 && arg->port == UDP_VTER ) strcpy(entity, "udp_vterm");
|
if( arg->port == UDP_VTER ) strcpy(entity, "udp_vterm");
|
||||||
if( strcmp(arg->addr, MCST_CTER) == 0 && arg->port == UDP_CTER ) strcpy(entity, "udp_cterm");
|
if( arg->port == UDP_CTER ) strcpy(entity, "udp_cterm");
|
||||||
if( strcmp(arg->addr, MCST_HOST) == 0 && arg->port == UDP_MCST ) strcpy(entity, "udp_mcast");
|
if( arg->port == UDP_MCST ) strcpy(entity, "udp_mcast");
|
||||||
|
|
||||||
// retour de @DROP_UDP_SERVER
|
// retour de @DROP_UDP_SERVER
|
||||||
int SOCKET;
|
int SOCKET;
|
||||||
|
|
||||||
|
ip.s_addr = arg->addr;
|
||||||
|
|
||||||
|
|
||||||
/* [1] On démarre le SERVEUR UDP d'écoute globale
|
/* [1] On démarre le SERVEUR UDP d'écoute globale
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
if( DROP_UDP_SERVER(arg->addr, arg->port, &SOCKET, &listenInfo, strcmp(arg->addr, SERV_HOST) != 0) < 0 ){
|
/* 1. On crée la socket */
|
||||||
|
rtnPort = DROP_UDP_SERVER(arg->addr, arg->port, &SOCKET, &listenInfo, 1);
|
||||||
|
if( rtnPort < 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
|
// 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);
|
close(SOCKET);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("{%s} listen on %s:%d\n", entity, arg->addr, arg->port);
|
/* 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), rtnPort);
|
||||||
|
|
||||||
|
if( rtnPort != arg->port )
|
||||||
|
printf("{%s} /!\\ Another SGCA might be running, port %d is already used\n", entity, arg->port);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,18 +326,19 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){
|
||||||
if( index != -1 ){
|
if( index != -1 ){
|
||||||
|
|
||||||
// Construction arguments thread
|
// Construction arguments thread
|
||||||
struct handler_arg thread_args = { UDPManagers, activeUDPManagers, CLIENT_SOCKET, &sgca };
|
|
||||||
|
struct handler_arg thread_args = { TCPManagers, UDPManagers, activeTCPManagers, activeUDPManagers, CLIENT_SOCKET, &sgca };
|
||||||
|
|
||||||
/* 2.1. On lance un thread pour le traitement de ce client */
|
/* 2.1. On lance un thread pour le traitement de ce client */
|
||||||
pthread_create(&UDPManagers[index], NULL, arg->handler, (void*) &thread_args);
|
pthread_create(&UDPManagers[index], NULL, arg->handler, (void*) &thread_args);
|
||||||
|
|
||||||
if( DEBUGMOD&THR ) printf("{%s}{udp_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 */
|
/* 2.2. On signale que ce "manager" est maintenant actif */
|
||||||
activeUDPManagers[index] = 1;
|
activeUDPManagers[index] = 1;
|
||||||
|
|
||||||
}else
|
}else
|
||||||
if( DEBUGMOD&THR ) printf("{%s} Aucun thread UDP libre!\n", entity);
|
if( DEBUGMOD&THR ) printf("{%s} No available thread\n", entity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +346,7 @@ void* LISTEN_UDP(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
/* [n] On ferme la SOCKET d'écoute globale
|
/* [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);
|
close(SOCKET);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -342,6 +376,7 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
|
||||||
struct sockaddr_in targetInfo; // contiendra les infos de la cible de la socket client
|
struct sockaddr_in targetInfo; // contiendra les infos de la cible de la socket client
|
||||||
char buffer[MAX_BUF_LEN]; // buffer de requêtes (envois)
|
char buffer[MAX_BUF_LEN]; // buffer de requêtes (envois)
|
||||||
struct bind_header request; // requête brute
|
struct bind_header request; // requête brute
|
||||||
|
struct in_addr ip; // Permet d'afficher les IP en dot notation
|
||||||
|
|
||||||
/* 2. On parse les arguments */
|
/* 2. On parse les arguments */
|
||||||
struct listen_arg* arg = THREADABLE_ARGS; // Addr + Port serveur
|
struct listen_arg* arg = THREADABLE_ARGS; // Addr + Port serveur
|
||||||
|
@ -349,6 +384,8 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
|
||||||
// retour de @UDP_SOCKET
|
// retour de @UDP_SOCKET
|
||||||
int SOCKET;
|
int SOCKET;
|
||||||
|
|
||||||
|
ip.s_addr = arg->addr;
|
||||||
|
|
||||||
|
|
||||||
/* [1] On initialise la socket CLIENT UDP
|
/* [1] On initialise la socket CLIENT UDP
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
|
@ -363,7 +400,7 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("{udp_mcast} bound to %s:%d\n", arg->addr, arg->port);
|
printf("{udp_mcast} bound to %s:%d\n", inet_ntoa(ip), arg->port);
|
||||||
|
|
||||||
|
|
||||||
/* [2] On construit la requête à envoyer
|
/* [2] On construit la requête à envoyer
|
||||||
|
@ -371,15 +408,24 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
|
||||||
/* 1. Initialisation du buffer */
|
/* 1. Initialisation du buffer */
|
||||||
bzero(buffer, MAX_BUF_LEN*sizeof(char));
|
bzero(buffer, MAX_BUF_LEN*sizeof(char));
|
||||||
|
|
||||||
/* 2. Remplissage de la requête brute */
|
/* 2. On récupère l'IP locale */
|
||||||
|
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} Closing publisher socket!\n");
|
||||||
|
close(SOCKET);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. Remplissage de la requête brute */
|
||||||
request.flags = BINDHEAD_TCP;
|
request.flags = BINDHEAD_TCP;
|
||||||
strcpy(request.addr, SERV_HOST);
|
request.addr = htonl(servip->s_addr);
|
||||||
request.port = htons(TCP_LIST);
|
request.port = htons(TCP_LIST);
|
||||||
|
|
||||||
/* 3. Copie dans le buffer */
|
/* 4. Copie dans le buffer */
|
||||||
memcpy(buffer, &request.flags, sizeof(char) );
|
memcpy(buffer, &request.flags, sizeof(char) );
|
||||||
memcpy(buffer+sizeof(char), &request.addr, sizeof(char)*INET_ADDRSTRLEN);
|
memcpy(buffer+sizeof(char), &request.addr, sizeof(in_addr_t) );
|
||||||
memcpy(buffer+sizeof(char)*(INET_ADDRSTRLEN+1), &request.port, sizeof(unsigned short));
|
memcpy(buffer+sizeof(char)+sizeof(in_addr_t), &request.port, sizeof(unsigned short) );
|
||||||
|
|
||||||
|
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
|
@ -392,7 +438,7 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
|
||||||
/* [4] On envoie les information de la socket TCP
|
/* [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 ){
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +449,7 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
/* [n] On ferme la SOCKET CLIENT UDP
|
/* [n] On ferme la SOCKET CLIENT UDP
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
printf("{udp_mcast} FERMETURE SOCKET CLIENT UDP!\n");
|
printf("{udp_mcast} Closing publisher socket\n");
|
||||||
close(SOCKET);
|
close(SOCKET);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
|
@ -8,10 +8,12 @@
|
||||||
* doowap31@gmail.com *
|
* doowap31@gmail.com *
|
||||||
**************************/
|
**************************/
|
||||||
#include "lib/header.h"
|
#include "lib/header.h"
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* local dependencies */
|
/* local dependencies */
|
||||||
|
#include "lib/network/common.h"
|
||||||
#include "lib/network/tcp/server.h"
|
#include "lib/network/tcp/server.h"
|
||||||
#include "lib/network/udp/server.h"
|
#include "lib/network/udp/server.h"
|
||||||
#include "lib/network/udp/client.h"
|
#include "lib/network/udp/client.h"
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# [1] Create script file
|
||||||
|
cd `pwd`/..;
|
||||||
|
make all;
|
||||||
|
cp boot install/sgca;
|
||||||
|
make clean;
|
||||||
|
cd install;
|
||||||
|
|
||||||
|
|
||||||
|
# [2] Create service target (boot)
|
||||||
|
sudo ln -s $(pwd)/sgca /usr/sbin/sgca;
|
||||||
|
|
||||||
|
# [3] Create service unit
|
||||||
|
sudo ln -s $(pwd)/sgca.service /lib/systemd/system/sgca.service;
|
||||||
|
|
||||||
|
# [4] Enable service (optional if no [Install])
|
||||||
|
sudo systemctl enable sgca.service;
|
||||||
|
|
||||||
|
# [5] Create log file
|
||||||
|
sudo touch /var/log/sgca;
|
|
@ -5,6 +5,6 @@ Requires=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
User=xdrm-brackets
|
User=root
|
||||||
Group=xdrm-brackets
|
Group=root
|
||||||
ExecStart=/usr/sbin/sgca /var/log/sgca
|
ExecStart=/usr/sbin/sgca
|
|
@ -4,8 +4,12 @@
|
||||||
sudo rm /usr/sbin/sgca;
|
sudo rm /usr/sbin/sgca;
|
||||||
|
|
||||||
# [2] Disable service
|
# [2] Disable service
|
||||||
|
sudo systemctl stop sgca.service;
|
||||||
sudo systemctl disable sgca.service;
|
sudo systemctl disable sgca.service;
|
||||||
|
|
||||||
# [3] Remove service unit
|
# [3] Remove service unit
|
||||||
sudo rm /lib/systemd/system/sgca.service;
|
sudo rm /lib/systemd/system/sgca.service;
|
||||||
|
|
||||||
|
# [4] Remove log file
|
||||||
|
sudo rm /var/log/sgca;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#define TERMREQ_CAP 0x02
|
#define TERMREQ_CAP 0x02
|
||||||
#define TERMREQ_SPD 0x04
|
#define TERMREQ_SPD 0x04
|
||||||
#define TERMREQ_ALT 0x08
|
#define TERMREQ_ALT 0x08
|
||||||
|
#define TERMREQ_OFF 0x10
|
||||||
|
|
||||||
#define PLANE_LEN ( sizeof(char)*6+sizeof(int)*5 )
|
#define PLANE_LEN ( sizeof(char)*6+sizeof(int)*5 )
|
||||||
struct plane{
|
struct plane{
|
||||||
|
@ -26,11 +27,21 @@
|
||||||
int z;
|
int z;
|
||||||
int cap;
|
int cap;
|
||||||
int spd;
|
int spd;
|
||||||
|
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{
|
struct term_req{
|
||||||
char flags;
|
char flags;
|
||||||
struct plane udpate;
|
struct plane update;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct term_res{
|
struct term_res{
|
||||||
|
@ -40,14 +51,14 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define BINDHDR_LEN ( sizeof(char)*(1+INET_ADDRSTRLEN)+sizeof(unsigned short) )
|
#define BINDHDR_LEN ( sizeof(char)+sizeof(in_addr_t)+sizeof(unsigned short) )
|
||||||
#define BINDHEAD_CTL 0x01 // is command terminal (else: view terminal)
|
#define BINDHEAD_UDP 0x01 // is terminal (ask for UDP socket)
|
||||||
#define BINDHEAD_SCK 0x02 // ask for com socket (terminal)
|
#define BINDHEAD_TCP 0x02 // is plane (ask for TCP socket)
|
||||||
#define BINDHEAD_TCP 0x04 // ask TCP com socket (plane)
|
#define BINDHEAD_CTL 0x04 // is ctrlTerm (else: viewTerm)
|
||||||
|
|
||||||
struct bind_header{
|
struct bind_header{
|
||||||
char flags;
|
char flags;
|
||||||
char addr[INET_ADDRSTRLEN];
|
in_addr_t addr;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,12 +14,16 @@
|
||||||
#define BUFFERS 0x04 // debug des BUFFERS
|
#define BUFFERS 0x04 // debug des BUFFERS
|
||||||
#define HEADERS 0x08 // debug des HEADERS de fonctions
|
#define HEADERS 0x08 // debug des HEADERS de fonctions
|
||||||
#define THREADS 0x10 // debug des THREADS
|
#define THREADS 0x10 // debug des THREADS
|
||||||
|
#define COMMUNI 0x20 // debug des COMMUNICATIONS
|
||||||
|
#define SOCKADV 0x40 // debug des ADVANCED SOCKET
|
||||||
|
|
||||||
#define SCK 0x01 // FILTRE pour SOCKET
|
#define SCK 0x01 // FILTRE pour SOCKET
|
||||||
#define RVL 0x02 // FILTRE pour REVEALS
|
#define RVL 0x02 // FILTRE pour REVEALS
|
||||||
#define BUF 0x04 // FILTRE pour BUFFERS
|
#define BUF 0x04 // FILTRE pour BUFFERS
|
||||||
#define HDR 0x08 // FILTRE pour HEADERS
|
#define HDR 0x08 // FILTRE pour HEADERS
|
||||||
#define THR 0x10 // FILTRE pour THREADS
|
#define THR 0x10 // FILTRE pour THREADS
|
||||||
|
#define COM 0x20 // FILTRE pour COMMUNICATIONS
|
||||||
|
#define SAD 0x40 // FILTRE pour ADVANCED SOCKET
|
||||||
|
|
||||||
// possibilité de cumuler les DEBUGMODES
|
// possibilité de cumuler les DEBUGMODES
|
||||||
#define DEBUGMOD ( SOCKETS | THREADS | BUFFERS ) // REVEALS + HEADER + THREADS
|
#define DEBUGMOD ( SOCKETS | THREADS | BUFFERS ) // REVEALS + HEADER + THREADS
|
|
@ -20,6 +20,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
/* sys */
|
/* sys */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -36,7 +37,6 @@
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
|
|
||||||
/* vars */
|
/* vars */
|
||||||
#define SERV_HOST "127.0.0.1" // adresse serveur
|
|
||||||
#define MCST_HOST "224.0.0.1" // adresse groupe multicast UDP -> plane
|
#define MCST_HOST "224.0.0.1" // adresse groupe multicast UDP -> plane
|
||||||
#define MCST_VTER "224.0.0.2" // adresse groupe multicast UDP -> viewTerm
|
#define MCST_VTER "224.0.0.2" // adresse groupe multicast UDP -> viewTerm
|
||||||
#define MCST_CTER "224.0.0.3" // adresse groupe multicast UDP -> ctrlTerm
|
#define MCST_CTER "224.0.0.3" // adresse groupe multicast UDP -> ctrlTerm
|
||||||
|
@ -52,13 +52,21 @@
|
||||||
#define maxHostLen 64
|
#define maxHostLen 64
|
||||||
#define maxPortLen 6
|
#define maxPortLen 6
|
||||||
|
|
||||||
#define SOCK_TIMEOUT 3 // 3sec timeout (1+ temps refresh plane)
|
#define CTRL_TIMEOUT 10 // 10sec timeout (pour ctrlTerm)
|
||||||
|
#define SOCK_TIMEOUT 4 // 4sec timeout (1+ temps refresh plane)
|
||||||
#define PUBL_TIMEOUT 2 // 2sec entre chaque publication sur multicast UDP (pour avions)
|
#define PUBL_TIMEOUT 2 // 2sec entre chaque publication sur multicast UDP (pour avions)
|
||||||
|
|
||||||
|
|
||||||
|
struct context_unit{
|
||||||
|
int socket; // socket associée à un avion
|
||||||
|
struct plane data; // données d'un avion
|
||||||
|
char thrId; // TCP thread index
|
||||||
|
char flags; // persistent flags
|
||||||
|
};
|
||||||
|
|
||||||
struct context{
|
struct context{
|
||||||
unsigned int n; // nombre d'avions
|
unsigned int n; // nombre d'avions
|
||||||
struct plane* data; // buffer tes données avion
|
struct context_unit* unit; // les données des avions
|
||||||
};
|
};
|
||||||
|
|
||||||
struct middleware_arg{
|
struct middleware_arg{
|
||||||
|
@ -68,14 +76,16 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
struct handler_arg{
|
struct handler_arg{
|
||||||
pthread_t* managers;
|
pthread_t* TCPManagers;
|
||||||
int* activeManagers;
|
pthread_t* UDPManagers;
|
||||||
|
int* activeTCPManagers;
|
||||||
|
int* activeUDPManagers;
|
||||||
int socket;
|
int socket;
|
||||||
struct context* sgca;
|
struct context* sgca;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct listen_arg{
|
struct listen_arg{
|
||||||
const char addr[16]; // socket address
|
in_addr_t addr; // socket address
|
||||||
const unsigned short port; // socket port
|
const unsigned short port; // socket port
|
||||||
int (*middleware)(struct middleware_arg*); // middleware function
|
int (*middleware)(struct middleware_arg*); // middleware function
|
||||||
void* (*handler)(void*); // management function (thread)
|
void* (*handler)(void*); // management function (thread)
|
|
@ -0,0 +1,615 @@
|
||||||
|
/**************************
|
||||||
|
* Handler Dependency *
|
||||||
|
***************************
|
||||||
|
* Designed & Developed by *
|
||||||
|
* Adrien Marquès *
|
||||||
|
* <xdrm-brackets> *
|
||||||
|
***************************
|
||||||
|
* doowap31@gmail.com *
|
||||||
|
**************************/
|
||||||
|
#include "handler.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Gestion d'une connexion PLANE
|
||||||
|
*
|
||||||
|
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
||||||
|
*
|
||||||
|
* @history
|
||||||
|
* [1] Initialisation des variables
|
||||||
|
* @loop
|
||||||
|
* (2) Attente de requête
|
||||||
|
* (3) Gestion de la requête
|
||||||
|
* (4) Envoi de la réponse
|
||||||
|
* [5] On notifie que l'avion est déconnecté (crash)
|
||||||
|
* [6] On libère la mémoire
|
||||||
|
* [7] Fermeture de la connection (SOCKET)
|
||||||
|
* [n] Arrêt du THREAD
|
||||||
|
* 1. On met à jour "activeManagers"
|
||||||
|
* 2. On arrête le THREAD
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void* managePlane(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
|
/* [1] Initialisation des variables
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. Variables utiles */
|
||||||
|
int read, i, index, pindex; // compteurs
|
||||||
|
char buffer[MAX_BUF_LEN]; // buffer
|
||||||
|
struct plane data; // données de l'avion
|
||||||
|
int SOCKET; // Copie de la socket (évite les conflits de références)
|
||||||
|
char tmpFlags;
|
||||||
|
|
||||||
|
|
||||||
|
/* 2. On récupère les arguments */
|
||||||
|
struct handler_arg* arg = THREADABLE_ARGS;
|
||||||
|
memcpy(&SOCKET, &arg->socket, sizeof(int));
|
||||||
|
if( DEBUGMOD&HDR ) printf("===== managePlane(%p, %p, %d, %p) =====\n", (void*) arg->TCPManagers, (void*) arg->activeTCPManagers, arg->socket, (void*) arg->sgca);
|
||||||
|
|
||||||
|
|
||||||
|
/* 3. On récupère le rang du thread parmi les "managers" */
|
||||||
|
index = -1;
|
||||||
|
for( i = 0 ; i < MAX_TCP_THR ; i++ )
|
||||||
|
if( arg->TCPManagers[i] == pthread_self() ){ index = i; break; }
|
||||||
|
|
||||||
|
// Erreur de thread
|
||||||
|
if( index == -1 ){
|
||||||
|
if( DEBUGMOD&THR ) printf("{tcp_com}(%d) Unknown thread index. Aborting\n", index);
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pindex = -1; // on ne connait pas encore l'avion
|
||||||
|
|
||||||
|
while( 1 ){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Récupération de la requête
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* 1. On lit sur la socket */
|
||||||
|
read = recv(SOCKET, buffer, MAX_BUF_LEN, 0);
|
||||||
|
|
||||||
|
/* 2.1. Si erreur reception (-1:erreur, 0:fermeture client propre) */
|
||||||
|
if( read <= 0 ){
|
||||||
|
if( DEBUGMOD&BUF ) printf("{tcp_com}(%d) Error receiving (%d), must exit thread\n", index, read);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2.2. Si message trop court */
|
||||||
|
if( read != PLANE_LEN+1 ){
|
||||||
|
if( DEBUGMOD&BUF ) printf("{tcp_com}(%d) Error receiving (%d bytes, but %d expected)\n", index, read, (int) (PLANE_LEN+1) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 3. On parse la requête (indianness: network order) */
|
||||||
|
memcpy(&tmpFlags, buffer+sizeof(char)*0+sizeof(int)*0, sizeof(char) );
|
||||||
|
memcpy(&data.code, buffer+sizeof(char)*1+sizeof(int)*0, sizeof(char)*6 );
|
||||||
|
memcpy(&data.x, buffer+sizeof(char)*7+sizeof(int)*0, sizeof(int) );
|
||||||
|
memcpy(&data.y, buffer+sizeof(char)*7+sizeof(int)*1, sizeof(int) );
|
||||||
|
memcpy(&data.z, buffer+sizeof(char)*7+sizeof(int)*2, sizeof(int) );
|
||||||
|
memcpy(&data.spd, buffer+sizeof(char)*7+sizeof(int)*4, sizeof(int) );
|
||||||
|
memcpy(&data.cap, buffer+sizeof(char)*7+sizeof(int)*3, sizeof(int) );
|
||||||
|
|
||||||
|
/* 4. Gestion de l'indianness */
|
||||||
|
data.x = ntohl(data.x);
|
||||||
|
data.y = ntohl(data.y);
|
||||||
|
data.z = ntohl(data.z);
|
||||||
|
data.cap = ntohl(data.cap);
|
||||||
|
data.spd = ntohl(data.spd);
|
||||||
|
data.online = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (3) Gestion de la requête -> enregistrement
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* 1. On cherche le rang de l'avion si on l'a pas déja */
|
||||||
|
if( pindex <= -1 ){
|
||||||
|
|
||||||
|
/* 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->unit[i].data.code, data.code) == 0 ){
|
||||||
|
pindex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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->unit = (struct context_unit*) realloc(arg->sgca->unit, sizeof(struct context_unit)*arg->sgca->n + 1);
|
||||||
|
arg->sgca->unit[pindex].socket = SOCKET;
|
||||||
|
arg->sgca->unit[pindex].thrId = 0xf0;
|
||||||
|
printf("{tcp_com}(%d) plane '%s' (#%d) created\n", index, data.code, pindex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4. On copie/met à jour les valeurs */
|
||||||
|
if( tmpFlags != TERMREQ_OFF ){ // gestion réponse ctrlTerm
|
||||||
|
arg->sgca->unit[pindex].flags = tmpFlags; // on met à jour les flags
|
||||||
|
while( arg->sgca->unit[pindex].thrId == 0xf0 ); // on attend le numéro de thread
|
||||||
|
printf("{tcp_com}(%d) Waking up UDP threaad@%d for ctrlTerm response\n", index, arg->sgca->unit[pindex].thrId);
|
||||||
|
pthread_kill(arg->UDPManagers[(int)arg->sgca->unit[pindex].thrId], SIGCONT); // on réveille le thread
|
||||||
|
arg->sgca->unit[pindex].thrId = 0xf0; // on laisse la place pour qqn d'autre
|
||||||
|
}
|
||||||
|
memcpy(&arg->sgca->unit[pindex].data, &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->unit[pindex].data.code, arg->sgca->unit[pindex].data.x, arg->sgca->unit[pindex].data.y, arg->sgca->unit[pindex].data.z, arg->sgca->unit[pindex].data.cap, arg->sgca->unit[pindex].data.spd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [5] On notifie que l'avoin est déconnecté (crash)
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. On notifie le crash */
|
||||||
|
arg->sgca->unit[pindex].data.online = 0;
|
||||||
|
arg->sgca->unit[pindex].socket = -1;
|
||||||
|
|
||||||
|
|
||||||
|
/* [6] On libère la mémoire
|
||||||
|
=========================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/* [7] Fermeture de la connection (SOCKET)
|
||||||
|
=========================================================*/
|
||||||
|
printf("{tcp_com}(%d) Closing communication socket\n", index);
|
||||||
|
close(SOCKET);
|
||||||
|
|
||||||
|
|
||||||
|
/* [n] Arrêt du THREAD
|
||||||
|
============================================================================*/
|
||||||
|
/* 1. On met à jour "activeManagers" */
|
||||||
|
if( index != -1 )
|
||||||
|
arg->activeTCPManagers[index] = 0;
|
||||||
|
|
||||||
|
/* 2. On arrête le THREAD */
|
||||||
|
if( DEBUGMOD&THR ) printf("{tcp_com}(%d) freed\n", index);
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Gestion d'une connexion TERMINAL
|
||||||
|
*
|
||||||
|
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
||||||
|
*
|
||||||
|
* @history
|
||||||
|
* [1] Initialisation des variables
|
||||||
|
*
|
||||||
|
* @loop
|
||||||
|
* [2] Récupération des données
|
||||||
|
* [3] Construction de la requête
|
||||||
|
* [4] Envoi de la requête
|
||||||
|
* [5] Timeout
|
||||||
|
*
|
||||||
|
* [6] On vide les buffers
|
||||||
|
* [7] Fermeture de la connection (SOCKET)
|
||||||
|
* [n] Arrêt du THREAD
|
||||||
|
* 1. On récupère le rang dans les "managers"
|
||||||
|
* 2. On met à jour "activeManagers"
|
||||||
|
* 3. On arrête le THREAD
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void* manageViewTerm(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
|
/* [1] Initialisation des variables
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. Initialisation des variables */
|
||||||
|
struct sockaddr_in clientInfo;
|
||||||
|
socklen_t len;
|
||||||
|
char loop = 1;
|
||||||
|
size_t buflen;
|
||||||
|
int sent; // compteurs d'envoi
|
||||||
|
int i, index = -1; // Compteurs globaux
|
||||||
|
char* buffer = malloc(1); // Buffer d'envoi
|
||||||
|
int SOCKET;
|
||||||
|
|
||||||
|
/* 2. On récupère les arguments */
|
||||||
|
struct handler_arg* arg = THREADABLE_ARGS;
|
||||||
|
memcpy(&SOCKET, &arg->socket, sizeof(int));
|
||||||
|
|
||||||
|
/* 3. On récupère le rang dans les "managers" */
|
||||||
|
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
||||||
|
if( arg->UDPManagers[i] == pthread_self() ){ index = i; break; }
|
||||||
|
|
||||||
|
printf("{udp_vterm}{com}(%d) starting terminal routine (rate: %d sec)\n", index, PUBL_TIMEOUT);
|
||||||
|
|
||||||
|
|
||||||
|
/* 4. Attente d'un client */
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
if( recvfrom(SOCKET, buffer, MAX_BUF_LEN*sizeof(char), 0, (struct sockaddr*) &clientInfo, &len) < 0 ){
|
||||||
|
printf("{udp_vterm}{com}(%d) No terminal detected, exiting\n", index);
|
||||||
|
loop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( loop ) printf("{udp_cterm}{com}(%d) Terminal connected\n", index);
|
||||||
|
|
||||||
|
|
||||||
|
while( loop ){
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Récupération des données
|
||||||
|
=========================================================*/
|
||||||
|
getPlaneData(&buffer, &buflen, arg->sgca);
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Envoi de la requête
|
||||||
|
=========================================================*/
|
||||||
|
/* 2. Envoi */
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
sent = sendto(SOCKET, buffer, buflen + 1, 0, (struct sockaddr*) &clientInfo, len);
|
||||||
|
|
||||||
|
/* 3. Gestion erreur */
|
||||||
|
if( sent <= 0 ){
|
||||||
|
printf("{udp_vterm}{com}(%d) Unable to send data\n", index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Réception feedback
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. Réception feedback (0x10) */
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
sent = recvfrom(SOCKET, buffer, 1, 0, (struct sockaddr*) &clientInfo, &len);
|
||||||
|
|
||||||
|
/* 2. Gestion erreur (erreur ou mauvais feedback != 0x10) */
|
||||||
|
if( sent <= 0 || buffer[0] != TERMREQ_OFF ){
|
||||||
|
printf("{udp_vterm}{com}(%d) Unable to recv feedback -> exiting\n", index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Timeout
|
||||||
|
=========================================================*/
|
||||||
|
sleep(PUBL_TIMEOUT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [n] Arrêt du THREAD
|
||||||
|
============================================================================*/
|
||||||
|
/* 1. On met à jour "activeManagers" */
|
||||||
|
if( index != -1 )
|
||||||
|
arg->activeUDPManagers[index] = 0;
|
||||||
|
|
||||||
|
/* 2. On ferme la socket + libère la mémoire */
|
||||||
|
close(SOCKET);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
|
||||||
|
/* 3. On arrête le THREAD */
|
||||||
|
if( DEBUGMOD&THR ) printf("{udp_vterm}{com}(%d) freed\n", index);
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Gestion d'une connexion TERMINAL
|
||||||
|
*
|
||||||
|
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
||||||
|
*
|
||||||
|
* @history
|
||||||
|
* [1] Initialisation des variables
|
||||||
|
* [2] Récupération de la requête
|
||||||
|
* [3] Traitement de la requête
|
||||||
|
* [4] Création de la réponse
|
||||||
|
* [5] Envoi de la réponse
|
||||||
|
* [6] On vide les buffers
|
||||||
|
* [7] Fermeture de la connection (SOCKET)
|
||||||
|
* [n] Arrêt du THREAD
|
||||||
|
* 1. On récupère le rang dans les "managers"
|
||||||
|
* 2. On met à jour "activeManagers"
|
||||||
|
* 3. On arrête le THREAD
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void* manageCtrlTerm(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
|
/* [1] Initialisation des variables
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. Initialisation des variables */
|
||||||
|
struct sockaddr_in clientInfo;
|
||||||
|
socklen_t len;
|
||||||
|
size_t dataLen;
|
||||||
|
char loop = 1, update = 0, fbk = 0;
|
||||||
|
int count, last; // compteurs d'envoi
|
||||||
|
int i, index = -1; // Compteurs globaux
|
||||||
|
int pindex; // index of the current plane
|
||||||
|
char buffer[MAX_BUF_LEN]; // Buffer d'envoi
|
||||||
|
char* dataBuffer = malloc(1);
|
||||||
|
struct term_req request; // Requête
|
||||||
|
char flags;
|
||||||
|
int SOCKET;
|
||||||
|
struct in_addr* ip = malloc(sizeof(struct in_addr));
|
||||||
|
|
||||||
|
|
||||||
|
/* 2. On récupère les arguments */
|
||||||
|
struct handler_arg* arg = THREADABLE_ARGS;
|
||||||
|
memcpy(&SOCKET, &arg->socket, sizeof(int));
|
||||||
|
|
||||||
|
/* 3. On récupère le rang dans les "managers" */
|
||||||
|
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
||||||
|
if( arg->UDPManagers[i] == pthread_self() ){ index = i; break; }
|
||||||
|
|
||||||
|
printf("{udp_cterm}{com}(%d) starting terminal routine\n", index);
|
||||||
|
|
||||||
|
/* 4. Attente d'un client */
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
if( recvfrom(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;
|
||||||
|
}else{
|
||||||
|
ip->s_addr = clientInfo.sin_addr.s_addr;
|
||||||
|
printf("{udp_cterm}{com}(%d) Terminal connected from %s:%d\n", index, inet_ntoa(*ip), ntohs(clientInfo.sin_port));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ip);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while( loop ){
|
||||||
|
|
||||||
|
pindex = -1;
|
||||||
|
|
||||||
|
/* [2] Récupération de la requête
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. On lit sur la socket */
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
|
||||||
|
count = recvfrom(SOCKET, buffer, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
||||||
|
|
||||||
|
/* 2. Si erreur reception */
|
||||||
|
if( count <= 0 ) // because of timeout or error
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( count < TERMREQ_LEN ){
|
||||||
|
send(SOCKET, "\0\0", sizeof(char)*2, 0);
|
||||||
|
if( DEBUGMOD&BUF ) printf("{udp_cterm}{com}(%d) Error receiving request\n", index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. On désérialise la requête*/
|
||||||
|
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 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Gestion de la requête
|
||||||
|
=========================================================*/
|
||||||
|
/* 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 );
|
||||||
|
fbk = request.flags&TERMREQ_FBK;
|
||||||
|
if( !( update || fbk ) ){
|
||||||
|
send(SOCKET, "\x00\0", sizeof(char)*2, 0);
|
||||||
|
if( request.flags != 0 )
|
||||||
|
printf("{udp_cterm}{com}(%d) Invalid flags\n", index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("{udp_cterm}{com}(%d) Plane req { flags: %d; plane: #%s { z=%d; cap=%d; speed=%d } }\n", index, request.flags, request.update.code, ntohl(request.update.z), ntohl(request.update.cap), ntohl(request.update.spd));
|
||||||
|
|
||||||
|
/* [4] Gestion de la mise à jour de valeurs
|
||||||
|
=========================================================*/
|
||||||
|
while( update ){
|
||||||
|
|
||||||
|
/* (1) Recherche de l'avion
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* 1. On cherche l'avion par code */
|
||||||
|
for( i = 0 ; i < arg->sgca->n ; i++ ){
|
||||||
|
|
||||||
|
/* 2. Si l'avion existe et online -> on passe à la suite */
|
||||||
|
if( strcmp(arg->sgca->unit[i].data.code, request.update.code) == 0 && arg->sgca->unit[i].data.online == 1 ){
|
||||||
|
pindex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 3. Si on a pas trouvé -> on quitte l'udpdate */
|
||||||
|
if( pindex <= -1 || arg->sgca->unit[pindex].socket <= -1 ){
|
||||||
|
printf("{udp_cterm}{com}(%d) Plane unknown or unreachable, passing\n", index);
|
||||||
|
request.flags = TERMREQ_OFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Transfert de la requête à l'avion
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* 1. On prépare la requête */
|
||||||
|
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
|
||||||
|
|
||||||
|
/* 2. On remplit le buffer d'envoi */
|
||||||
|
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 );
|
||||||
|
count += last;
|
||||||
|
|
||||||
|
/* 3. On envoie la requête à l'avion */
|
||||||
|
if( send(arg->sgca->unit[pindex].socket, buffer, count/sizeof(char), 0) <= 0 ){
|
||||||
|
printf("{udp_cterm}{com}(%d) Cannot send request to plane\n", index);
|
||||||
|
request.flags = TERMREQ_OFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (3) Gestion de la réponse de l'avion
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
// Attente du flag de réponse
|
||||||
|
arg->sgca->unit[pindex].thrId = index;
|
||||||
|
sleep(2);
|
||||||
|
flags = arg->sgca->unit[pindex].flags; // on récupère les flags
|
||||||
|
arg->sgca->unit[pindex].flags = TERMREQ_OFF; // on reset les flags
|
||||||
|
|
||||||
|
if( flags == TERMREQ_OFF ){
|
||||||
|
printf("{udp_cterm}{com}(%d) Cannot get response from plane %d bytes (%d expected)\n", index, count, (int) PLANE_LEN);
|
||||||
|
request.flags = TERMREQ_OFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("{udp_cterm}{com}(%d) Plane res { flags: %d }\n", index, flags);
|
||||||
|
|
||||||
|
/* 2. Gestion de la validation de l'update */
|
||||||
|
if( !(flags&TERMREQ_ALT) && request.flags&TERMREQ_ALT )
|
||||||
|
request.flags -= TERMREQ_ALT;
|
||||||
|
|
||||||
|
if( !(flags&TERMREQ_CAP) && request.flags&TERMREQ_CAP )
|
||||||
|
request.flags -= TERMREQ_CAP;
|
||||||
|
|
||||||
|
if( !(flags&TERMREQ_SPD) && request.flags&TERMREQ_SPD )
|
||||||
|
request.flags -= TERMREQ_SPD;
|
||||||
|
|
||||||
|
/* 3. Si pas de demande des données -> on pré-remplie la requête */
|
||||||
|
if( !fbk ){
|
||||||
|
dataBuffer = realloc(dataBuffer, sizeof(char)*2 );
|
||||||
|
dataBuffer[0] = request.flags;
|
||||||
|
dataBuffer[1] = 0;
|
||||||
|
dataLen = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fbk ){
|
||||||
|
|
||||||
|
/* [5] Données des avions
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. On récupère les données */
|
||||||
|
getPlaneData(&dataBuffer, &dataLen, arg->sgca);
|
||||||
|
|
||||||
|
/* 2. Si update, on mixe les flags */
|
||||||
|
if( update )
|
||||||
|
dataBuffer[0] |= request.flags;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [6] Réponse au terminal
|
||||||
|
=========================================================*/
|
||||||
|
printf("{udp_cterm}{com}(%d) Sending response { flags: %d; n: %d }\n", index, dataBuffer[0], dataBuffer[1]);
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
if( sendto(SOCKET, dataBuffer, dataLen, 0, (struct sockaddr*) &clientInfo, len) < 0 )
|
||||||
|
printf("{udp_cterm}{com}(%d) Cannot answer to terminal\n", index);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [n] Arrêt du THREAD
|
||||||
|
============================================================================*/
|
||||||
|
/* 1. On met à jour "activeManagers" */
|
||||||
|
if( index != -1 )
|
||||||
|
arg->activeUDPManagers[index] = 0;
|
||||||
|
|
||||||
|
/* 2. On ferme la socket */
|
||||||
|
close(SOCKET);
|
||||||
|
free(dataBuffer);
|
||||||
|
|
||||||
|
/* 3. On arrête le THREAD */
|
||||||
|
if( DEBUGMOD&THR ) printf("{udp_cterm}{com}(%d) freed\n", index);
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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->unit[i].data.code, sizeof(char)*6);
|
||||||
|
response.data[i].x = htonl( pContext->unit[i].data.x );
|
||||||
|
response.data[i].y = htonl( pContext->unit[i].data.y );
|
||||||
|
response.data[i].z = htonl( pContext->unit[i].data.z );
|
||||||
|
response.data[i].cap = htonl( pContext->unit[i].data.cap );
|
||||||
|
response.data[i].spd = htonl( pContext->unit[i].data.spd );
|
||||||
|
response.data[i].online = pContext->unit[i].data.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);
|
||||||
|
|
||||||
|
}
|
|
@ -19,5 +19,6 @@
|
||||||
void* manageViewTerm(void* THREADABLE_ARGS);
|
void* manageViewTerm(void* THREADABLE_ARGS);
|
||||||
void* manageCtrlTerm(void* THREADABLE_ARGS);
|
void* manageCtrlTerm(void* THREADABLE_ARGS);
|
||||||
|
|
||||||
|
void getPlaneData(char** pBuffer, size_t* pLen, struct context* pContext);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**************************
|
||||||
|
* Middleware Dependency *
|
||||||
|
***************************
|
||||||
|
* Designed & Developed by *
|
||||||
|
* Adrien Marquès *
|
||||||
|
* <xdrm-brackets> *
|
||||||
|
***************************
|
||||||
|
* doowap31@gmail.com *
|
||||||
|
**************************/
|
||||||
|
#include "middleware.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int multicastTerminal(struct middleware_arg* arg){
|
||||||
|
/* [0] Initialisation
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. Initialisation des variables */
|
||||||
|
struct sockaddr_in comInfo; // contiendra les infos de la socket COM
|
||||||
|
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
|
||||||
|
struct in_addr ip; // Pour afficher une ip en dot notation
|
||||||
|
|
||||||
|
/* 2. On récupère l'IP locale */
|
||||||
|
struct in_addr* SERV_IP = GET_LOCAL_IP();
|
||||||
|
if( SERV_IP == NULL ){
|
||||||
|
printf("{%s} /!\\ Cannot fetch local ip address. Aborting!\n", arg->entity);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. On attends une connection UDP */
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
read = recvfrom(arg->listenSock, buffer, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
||||||
|
|
||||||
|
/* 4. 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5. 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(in_addr_t));
|
||||||
|
memcpy(&request.port, buffer+sizeof(char)+sizeof(in_addr_t), sizeof(unsigned short));
|
||||||
|
request.addr = ntohl(request.addr);
|
||||||
|
ip.s_addr = request.addr;
|
||||||
|
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) ){
|
||||||
|
printf("{%s} Invalid flag\n", arg->entity);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. Si mauvais flag (mauvais type de terminal) */
|
||||||
|
if( request.flags&BINDHEAD_CTL ){
|
||||||
|
|
||||||
|
// vterm avec flag cterm
|
||||||
|
if( strcmp(arg->entity, "udp_vterm") == 0 ){
|
||||||
|
printf("{%s} Invalid flag\n", arg->entity);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cterm avec flag vterm
|
||||||
|
}else if( strcmp(arg->entity, "udp_cterm") == 0 ){
|
||||||
|
printf("{%s} Invalid flag\n", arg->entity);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Création socket de communication (si demandé)
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* 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} 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) */
|
||||||
|
/* 3.1. Si viewTerm -> default timeout (4sec) */
|
||||||
|
if( strcmp(arg->entity, "udp_vterm") == 0 ){
|
||||||
|
if( setTimeout(*arg->comSock, SOCK_TIMEOUT, TIMEOUT_RECV|TIMEOUT_SEND) < 0 ){
|
||||||
|
if( DEBUGMOD&SCK ) printf("{%s} Cannot set RECV not SEND timeout\n", arg->entity);
|
||||||
|
}else
|
||||||
|
if( DEBUGMOD&SCK ) printf("{%s} SEND/RECV timeout set to %d\n", arg->entity, SOCK_TIMEOUT);
|
||||||
|
/* 3.2. Si ctrlTerm -> 10sec timeout */
|
||||||
|
}else
|
||||||
|
if( setTimeout(*arg->comSock, CTRL_TIMEOUT, TIMEOUT_RECV|TIMEOUT_SEND) < 0 ){
|
||||||
|
if( DEBUGMOD&SCK ) printf("{%s} Cannot set RECV not SEND timeout\n", arg->entity);
|
||||||
|
}else
|
||||||
|
if( DEBUGMOD&SCK ) printf("{%s} SEND/RECV timeout set to %d\n", arg->entity, CTRL_TIMEOUT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Récupération port random
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* 1. On récupère le port de la socket de communication */
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
if( getsockname(*arg->comSock, (struct sockaddr*) &comInfo, &len) < 0 ){
|
||||||
|
|
||||||
|
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);
|
||||||
|
request.flags -= BINDHEAD_UDP;
|
||||||
|
|
||||||
|
/* 3. Si on a le port -> on le met dans la reponse */
|
||||||
|
}else{
|
||||||
|
request.addr = SERV_IP->s_addr;
|
||||||
|
request.port = comInfo.sin_port;
|
||||||
|
if( DEBUGMOD&SCK ) printf("{%s}{com} socket opened on %s:%d\n", arg->entity, inet_ntoa(*SERV_IP), ntohs(request.port));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Envoi de la réponse
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. On sérialise la réponse */
|
||||||
|
bzero(buffer, MAX_BUF_LEN*sizeof(char));
|
||||||
|
memcpy(buffer, &request.flags, sizeof(char));
|
||||||
|
memcpy(buffer+sizeof(char), &request.addr, sizeof(in_addr_t));
|
||||||
|
memcpy(buffer+sizeof(char)+sizeof(in_addr_t), &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} Cannot answer to client\n", arg->entity);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
#include "../header.h"
|
#include "../header.h"
|
||||||
#include "../network/udp/server.h"
|
#include "../network/udp/server.h"
|
||||||
|
#include "../network/common.h"
|
||||||
|
|
||||||
// int multicastPlanes(struct middleware_arg* ARGS);
|
|
||||||
int multicastTerminal(struct middleware_arg* ARGS);
|
int multicastTerminal(struct middleware_arg* ARGS);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/**************************
|
||||||
|
* Network Common Depend. *
|
||||||
|
***************************
|
||||||
|
* Designed & Developed by *
|
||||||
|
* Adrien Marquès *
|
||||||
|
* <xdrm-brackets> *
|
||||||
|
***************************
|
||||||
|
* doowap31@gmail.com *
|
||||||
|
**************************/
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct in_addr* GET_LOCAL_IP(){
|
||||||
|
/* [0] Initialisation des variables
|
||||||
|
=========================================================*/
|
||||||
|
struct ifaddrs *list; // list of interfaces
|
||||||
|
struct ifaddrs *it; // interface iterator
|
||||||
|
struct sockaddr_in *info; // interface info
|
||||||
|
struct in_addr *result; // ip trouvée
|
||||||
|
result = malloc( sizeof(struct in_addr) );
|
||||||
|
|
||||||
|
|
||||||
|
/* [1] On récupère la liste des interfaces
|
||||||
|
=========================================================*/
|
||||||
|
getifaddrs(&list);
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Parcourt des interfaces
|
||||||
|
=========================================================*/
|
||||||
|
for( it = list ; it ; it = it->ifa_next ){
|
||||||
|
|
||||||
|
/* 1. Si "lo" -> suivant */
|
||||||
|
if( strcmp(it->ifa_name, "lo") == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* 2. Si pas IPV4 -> suivant */
|
||||||
|
if( it->ifa_addr->sa_family != AF_INET )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* 3. Si ok, on retourne l'ip */
|
||||||
|
info = (struct sockaddr_in*) it->ifa_addr;
|
||||||
|
memcpy(result, &info->sin_addr, sizeof(struct in_addr));
|
||||||
|
freeifaddrs(list);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Cas échéant -> aucun résultat
|
||||||
|
=========================================================*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int checkMulticastGroup(in_addr_t pAddr){
|
||||||
|
// printf("Checking if multicast '%d' is already used\n");
|
||||||
|
|
||||||
|
/* [0] Initialisation des variables
|
||||||
|
=========================================================*/
|
||||||
|
// int sock, nb;
|
||||||
|
|
||||||
|
|
||||||
|
/* [1] Création d'une socket UDP
|
||||||
|
=========================================================*/
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/**************************
|
||||||
|
* Network Common Depend. *
|
||||||
|
***************************
|
||||||
|
* Designed & Developed by *
|
||||||
|
* Adrien Marquès *
|
||||||
|
* <xdrm-brackets> *
|
||||||
|
***************************
|
||||||
|
* doowap31@gmail.com *
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
#ifndef _LIB_NETWORK_COMMON_H_
|
||||||
|
#define _LIB_NETWORK_COMMON_H_
|
||||||
|
|
||||||
|
#include "../header.h"
|
||||||
|
#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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Vérifie si un groupe multicast est déja utilisé
|
||||||
|
*
|
||||||
|
* @in
|
||||||
|
* pAddr<in_addr_t> Adresse du groupe multicast
|
||||||
|
*
|
||||||
|
* @out
|
||||||
|
* -1 en cas d'échec
|
||||||
|
* 0 sinon
|
||||||
|
*
|
||||||
|
* @history
|
||||||
|
* [1] Initialisation des variables
|
||||||
|
* [2] On Vérifie si le groupe a du traffic
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int checkMulticastGroup(in_addr_t pAddr);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -22,7 +22,6 @@ int DROP_TCP_SERVER(const int pPort, int* pListenSock){
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
static struct sockaddr_in addr; // contiendra les infos du serveur
|
static struct sockaddr_in addr; // contiendra les infos du serveur
|
||||||
int STATUS; // status
|
int STATUS; // status
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
*pListenSock = -1;
|
*pListenSock = -1;
|
||||||
|
|
||||||
|
@ -37,15 +36,6 @@ int DROP_TCP_SERVER(const int pPort, int* pListenSock){
|
||||||
/* 2. Gestion erreur */
|
/* 2. Gestion erreur */
|
||||||
if( *pListenSock < 0 ) return -1;
|
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
|
/* [2] On définit les infos de la socket
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
|
@ -61,7 +51,13 @@ int DROP_TCP_SERVER(const int pPort, int* pListenSock){
|
||||||
/* [3] On publie la SOCKET
|
/* [3] On publie la SOCKET
|
||||||
=======================================================*/
|
=======================================================*/
|
||||||
/* 1. Publication socket */
|
/* 1. Publication socket */
|
||||||
STATUS = bind(*pListenSock, (struct sockaddr*) &addr, sizeof(addr));
|
int count = -1;
|
||||||
|
do{
|
||||||
|
count++;
|
||||||
|
addr.sin_port = htons(pPort+count);
|
||||||
|
STATUS = bind(*pListenSock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in));
|
||||||
|
if( DEBUGMOD&SAD ) printf("\tudp:%d used, trying udp:%d\n", pPort+count-1, pPort+count);
|
||||||
|
}while( STATUS < 0 && count < 10 );
|
||||||
|
|
||||||
if( DEBUGMOD&SCK && DEBUGMOD&HDR ) printf(" * [drop_tcp_server] bind: %d\n", STATUS);
|
if( DEBUGMOD&SCK && DEBUGMOD&HDR ) printf(" * [drop_tcp_server] bind: %d\n", STATUS);
|
||||||
|
|
||||||
|
@ -84,6 +80,6 @@ int DROP_TCP_SERVER(const int pPort, int* pListenSock){
|
||||||
|
|
||||||
/* [n] Code succès
|
/* [n] Code succès
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
return 0;
|
return pPort+count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo){
|
int UDP_SOCKET(int* pSocket, in_addr_t pAddr, const int pPort, struct sockaddr_in* pInfo){
|
||||||
|
|
||||||
/* [0] Initialisation des variables
|
/* [0] Initialisation des variables
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
*pSocket = -1;
|
*pSocket = -1;
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
|
|
||||||
/* [1] Création de la socket
|
/* [1] Création de la socket
|
||||||
|
@ -19,15 +18,6 @@ int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr
|
||||||
if( *pSocket < 0 )
|
if( *pSocket < 0 )
|
||||||
return -1;
|
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
|
/* [2] On définit les infos de la socket
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
|
@ -37,7 +27,7 @@ int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr
|
||||||
/* (2) On définit les infos */
|
/* (2) On définit les infos */
|
||||||
pInfo->sin_family = AF_INET;
|
pInfo->sin_family = AF_INET;
|
||||||
pInfo->sin_port = htons(pPort);
|
pInfo->sin_port = htons(pPort);
|
||||||
pInfo->sin_addr.s_addr = inet_addr(pAddr);
|
pInfo->sin_addr.s_addr = pAddr;
|
||||||
|
|
||||||
|
|
||||||
/* [n] Code succès
|
/* [n] Code succès
|
|
@ -26,7 +26,7 @@
|
||||||
/* Créée une socket UDP + crée le sockaddr_in pour la suite
|
/* Créée une socket UDP + crée le sockaddr_in pour la suite
|
||||||
*
|
*
|
||||||
* ==IN==
|
* ==IN==
|
||||||
* @pAddr<const char*> Adresse du groupe multicast UDP
|
* @pAddr<in_addr_t> Adresse du groupe multicast UDP
|
||||||
* @pPort<const int> Port d'écoute UDP
|
* @pPort<const int> Port d'écoute UDP
|
||||||
*
|
*
|
||||||
* ==OUT==
|
* ==OUT==
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo);
|
int UDP_SOCKET(int* pSocket, in_addr_t pAddr, const int pPort, struct sockaddr_in* pInfo);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,15 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int DROP_UDP_SERVER(const char* pAddr, const int pPort, int* pListenSock, struct sockaddr_in* pInfo, const char pMcast){
|
int DROP_UDP_SERVER(in_addr_t pAddr, const int pPort, int* pListenSock, struct sockaddr_in* pInfo, const char pMcast){
|
||||||
if( DEBUGMOD&HDR ) printf("====== DROP_UDP_MCAST(%s, %d, %p, %p, %d) ======\n\n", pAddr, pPort, (void*) pListenSock, (void*) pInfo, (int) pMcast);
|
if( DEBUGMOD&HDR ) printf("====== DROP_UDP_MCAST(%x, %d, %p, %p, %d) ======\n\n", pAddr, pPort, (void*) pListenSock, (void*) pInfo, (int) pMcast);
|
||||||
|
|
||||||
/* [0] Initialisation des variables
|
/* [0] Initialisation des variables
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
int STATUS; // status
|
int STATUS; // status
|
||||||
struct ip_mreq mcastReq;
|
struct ip_mreq mcastReq;
|
||||||
*pListenSock = -1;
|
*pListenSock = -1;
|
||||||
struct timeval timeout;
|
struct in_addr tmp;
|
||||||
|
|
||||||
|
|
||||||
/* [1] Création de la socket
|
/* [1] Création de la socket
|
||||||
|
@ -33,15 +33,6 @@ int DROP_UDP_SERVER(const char* pAddr, const int pPort, int* pListenSock, struct
|
||||||
/* 2. Gestion erreur */
|
/* 2. Gestion erreur */
|
||||||
if( *pListenSock < 0 ) return -1;
|
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
|
/* [2] On définit les infos de la socket
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
|
@ -57,7 +48,13 @@ int DROP_UDP_SERVER(const char* pAddr, const int pPort, int* pListenSock, struct
|
||||||
/* [3] On publie la SOCKET
|
/* [3] On publie la SOCKET
|
||||||
=======================================================*/
|
=======================================================*/
|
||||||
/* 1. Publication socket */
|
/* 1. Publication socket */
|
||||||
|
int count = -1;
|
||||||
|
do{
|
||||||
|
count++;
|
||||||
|
pInfo->sin_port = htons(pPort+count);
|
||||||
STATUS = bind(*pListenSock, (struct sockaddr*) pInfo, sizeof(struct sockaddr_in));
|
STATUS = bind(*pListenSock, (struct sockaddr*) pInfo, sizeof(struct sockaddr_in));
|
||||||
|
if( DEBUGMOD&SAD ) printf("\tudp:%d used, trying udp:%d\n", pPort+count-1, pPort+count);
|
||||||
|
}while( STATUS < 0 && count < 10 );
|
||||||
|
|
||||||
if( DEBUGMOD&SCK && DEBUGMOD&HDR ) printf(" * [drop_udp_server] bind: %d\n", STATUS);
|
if( DEBUGMOD&SCK && DEBUGMOD&HDR ) printf(" * [drop_udp_server] bind: %d\n", STATUS);
|
||||||
|
|
||||||
|
@ -67,8 +64,10 @@ int DROP_UDP_SERVER(const char* pAddr, const int pPort, int* pListenSock, struct
|
||||||
/* 3. Demande groupe multicast (si demandé) */
|
/* 3. Demande groupe multicast (si demandé) */
|
||||||
if( pMcast ){
|
if( pMcast ){
|
||||||
|
|
||||||
if( DEBUGMOD&SCK && DEBUGMOD&HDR ) printf(" * [drop_udp_server] join mcast group: %s\n", pAddr);
|
tmp.s_addr = pAddr;
|
||||||
mcastReq.imr_multiaddr.s_addr = inet_addr(pAddr);
|
|
||||||
|
if( DEBUGMOD&SCK && DEBUGMOD&HDR ) printf(" * [drop_udp_server] join mcast group: %s\n", inet_ntoa(tmp));
|
||||||
|
mcastReq.imr_multiaddr.s_addr = pAddr;
|
||||||
mcastReq.imr_interface.s_addr = htonl(INADDR_ANY);
|
mcastReq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
if( setsockopt(*pListenSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcastReq, sizeof(mcastReq)) < 0 ){
|
if( setsockopt(*pListenSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcastReq, sizeof(mcastReq)) < 0 ){
|
||||||
|
@ -81,6 +80,6 @@ int DROP_UDP_SERVER(const char* pAddr, const int pPort, int* pListenSock, struct
|
||||||
|
|
||||||
/* [n] Code succès
|
/* [n] Code succès
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
return 0;
|
return pPort+count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
/* Créé et met un serveur UDP d'écoute MULTICAST ou CLASSIQUE
|
/* Créé et met un serveur UDP d'écoute MULTICAST ou CLASSIQUE
|
||||||
*
|
*
|
||||||
* ==IN==
|
* ==IN==
|
||||||
* @pAddr<const char*> Adresse du groupe multicast UDP
|
* @pAddr<in_addr_t> Adresse du groupe multicast UDP
|
||||||
* @pPort<const int> Port d'écoute UDP
|
* @pPort<const int> Port d'écoute UDP
|
||||||
* @pMcast<const char> Si multicast ou non
|
* @pMcast<const char> Si multicast ou non
|
||||||
*
|
*
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
* [n] On renvoie la socket par référence
|
* [n] On renvoie la socket par référence
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int DROP_UDP_SERVER(const char* pAddr, const int pPort, int* pListenSock, struct sockaddr_in* pInfo, const char pMcast);
|
int DROP_UDP_SERVER(in_addr_t pAddr, const int pPort, int* pListenSock, struct sockaddr_in* pInfo, const char pMcast);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,20 @@ import java.net.SocketException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import ViewTerminal.InvalidFlagException;
|
||||||
|
import ViewTerminal.PlaneContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author lmascaro
|
* @author lmascaro
|
||||||
*/
|
*/
|
||||||
public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
||||||
|
|
||||||
private final static int MAX_MESSAGE_SIZE = 300;
|
public final static int MAX_MESSAGE_SIZE = 300;
|
||||||
|
|
||||||
private SynchronizedBuffer<DatagramPacket> buf;
|
private SynchronizedBuffer<DatagramPacket> buf;
|
||||||
private DatagramSocket socket;
|
private DatagramSocket socket;
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
public AsynchronousDatagramSocket() throws SocketException{
|
public AsynchronousDatagramSocket() throws SocketException{
|
||||||
this.buf = new SynchronizedBuffer<>();
|
this.buf = new SynchronizedBuffer<>();
|
||||||
|
@ -36,6 +40,10 @@ public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
public void send(DatagramPacket dp) throws IOException{
|
public void send(DatagramPacket dp) throws IOException{
|
||||||
this.socket.send(dp);
|
this.socket.send(dp);
|
||||||
}
|
}
|
||||||
|
@ -49,8 +57,8 @@ public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void synchronousReceive(DatagramPacket dp){
|
public DatagramPacket synchronousReceive(){
|
||||||
dp = this.buf.removeElement(true);
|
return this.buf.removeElement(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean available(){
|
public boolean available(){
|
||||||
|
@ -64,12 +72,18 @@ public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
DatagramPacket packet = new DatagramPacket(new byte[MAX_MESSAGE_SIZE],MAX_MESSAGE_SIZE);
|
DatagramPacket packet;
|
||||||
|
while(true){
|
||||||
|
packet = new DatagramPacket(new byte[MAX_MESSAGE_SIZE],MAX_MESSAGE_SIZE);
|
||||||
try {
|
try {
|
||||||
this.socket.receive(packet);
|
this.socket.receive(packet);
|
||||||
this.buf.addElement(packet);
|
this.buf.addElement(packet);
|
||||||
|
this.container.notifyReceive();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(AsynchronousDatagramSocket.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(AsynchronousDatagramSocket.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (InvalidFlagException e) {
|
||||||
|
System.out.println("\033[01;31m Unexpected flag received \033[0m");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package DatagramSocket;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class SynchronizedBuffer<T>{
|
||||||
|
|
||||||
|
private LinkedList<T> elements = new LinkedList<T>();
|
||||||
|
|
||||||
|
public synchronized T removeElement(boolean sync){
|
||||||
|
if(!sync && this.elements.isEmpty()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(this.elements.isEmpty()){
|
||||||
|
try {
|
||||||
|
this.wait();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Logger.getLogger(SynchronizedBuffer.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.elements.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addElement(T elem){
|
||||||
|
this.elements.add(elem);
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int available(){
|
||||||
|
return this.elements.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
public class InvalidFlagException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidFlagException(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidFlagException(String message){
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
public class Plane {
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
private int z;
|
||||||
|
private int cap;
|
||||||
|
private int speed;
|
||||||
|
|
||||||
|
private boolean isDead;
|
||||||
|
|
||||||
|
public Plane(String code,int x, int y, int z, int cap, int speed){
|
||||||
|
this.code = code;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.cap = cap;
|
||||||
|
this.speed = speed;
|
||||||
|
this.isDead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZ(int z) {
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCap() {
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDead(){
|
||||||
|
return this.isDead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCap(int cap) {
|
||||||
|
this.cap = cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpeed(int speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Die Motherfucker
|
||||||
|
public void die(){
|
||||||
|
this.isDead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLine(int i){
|
||||||
|
switch(i){
|
||||||
|
case 0:
|
||||||
|
return "--------------------------------";
|
||||||
|
case 1:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m Code: "+this.code+"\t\t\t|";
|
||||||
|
}else{
|
||||||
|
return "\033[4;37;42m Code: "+this.code+"\t\t\t|";
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
return "\033[0m --Coords: {"+this.x+";"+this.y+";"+this.z+"} \t|";
|
||||||
|
case 3:
|
||||||
|
return "\033[0m --Cap: "+this.cap+"\t\t\t|";
|
||||||
|
case 4:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m ATTENTION: avion hors ligne\t|\033[0m";
|
||||||
|
}else if(this.speed<300){
|
||||||
|
return "\033[5;37;41m --Speed: "+this.speed+"\t\t\t|\033[0m";
|
||||||
|
}else{
|
||||||
|
return "\033[0m --Speed: "+this.speed+"\t\t\t|";
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
public class PlaneContainer {
|
||||||
|
|
||||||
|
private HashMap<String,Plane> map;
|
||||||
|
private AsynchronousDatagramSocket socket;
|
||||||
|
private Printer printer;
|
||||||
|
|
||||||
|
public PlaneContainer(){
|
||||||
|
this.map = new HashMap<String,Plane>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindSocket(AsynchronousDatagramSocket s){
|
||||||
|
this.socket = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindPrinter(Printer p){
|
||||||
|
this.printer = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyReceive() throws InvalidFlagException{
|
||||||
|
DatagramPacket packet = this.socket.synchronousReceive();
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(1);
|
||||||
|
buf.put((byte)16);
|
||||||
|
DatagramPacket ping = new DatagramPacket(buf.array(),buf.array().length,packet.getAddress(),packet.getPort());
|
||||||
|
try {
|
||||||
|
this.socket.send(ping);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = ByteBuffer.wrap(packet.getData());
|
||||||
|
|
||||||
|
byte flag;
|
||||||
|
byte nbrPlane;
|
||||||
|
ArrayList<String> codes;
|
||||||
|
|
||||||
|
flag = buf.get();
|
||||||
|
nbrPlane = buf.get();
|
||||||
|
|
||||||
|
codes = new ArrayList<String>(nbrPlane);
|
||||||
|
|
||||||
|
//System.out.println("Processing "+nbrPlane+" planes");
|
||||||
|
|
||||||
|
if(flag != 1){
|
||||||
|
throw new InvalidFlagException("Flag is not a feedback flag :"+flag);
|
||||||
|
}else{
|
||||||
|
String code;
|
||||||
|
byte rawCode[] = new byte[5];
|
||||||
|
Plane plane;
|
||||||
|
for(int i = 0;i<nbrPlane;i++){
|
||||||
|
//get plane code
|
||||||
|
buf = buf.get(rawCode,0,5);
|
||||||
|
code = new String(rawCode);
|
||||||
|
plane = this.map.get(code);
|
||||||
|
codes.add(code);
|
||||||
|
|
||||||
|
//remove EOL char
|
||||||
|
buf.get();
|
||||||
|
|
||||||
|
if(plane != null){
|
||||||
|
//fill the plane
|
||||||
|
plane.setX(buf.getInt());
|
||||||
|
plane.setY(buf.getInt());
|
||||||
|
plane.setZ(buf.getInt());
|
||||||
|
plane.setCap(buf.getInt());
|
||||||
|
plane.setSpeed(buf.getInt());
|
||||||
|
}else{
|
||||||
|
plane = new Plane(code,buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt());
|
||||||
|
this.map.put(code, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check for dead planes
|
||||||
|
for(String code : this.map.keySet()){
|
||||||
|
if(!codes.contains(code)){
|
||||||
|
this.map.get(code).die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.printer.notifyReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String,Plane> getMap(){
|
||||||
|
return this.map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Printer {
|
||||||
|
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
|
public Printer(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyReceive(){
|
||||||
|
System.out.println("\033[2J \033[H");
|
||||||
|
HashMap<String,Plane> map = this.container.getMap();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
String lines[] = new String[5];
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(map.keySet().size() == 0){
|
||||||
|
System.out.println("\033[37;43m Aucun avion connecté au système \033[0m");
|
||||||
|
}else{
|
||||||
|
for(String code : map.keySet()){
|
||||||
|
if(i <= 1){
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}else{
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class ViewTerminal {
|
||||||
|
|
||||||
|
private final static int SGCA_MULTICAST_PORT = 4445;
|
||||||
|
private final static String SCGA_MULTICAST_ADDRESS = "224.0.0.2";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args the command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args){
|
||||||
|
System.out.println("\033[2J");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handshake
|
||||||
|
*/
|
||||||
|
int port = 0;
|
||||||
|
String addressString = "0.0.0.0";
|
||||||
|
|
||||||
|
try {
|
||||||
|
DatagramSocket socket = new DatagramSocket();
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(21);
|
||||||
|
buf.clear();
|
||||||
|
buf.put((byte)(0x01));
|
||||||
|
|
||||||
|
DatagramPacket payload = new DatagramPacket(buf.array(),buf.array().length,InetAddress.getByName(SCGA_MULTICAST_ADDRESS),SGCA_MULTICAST_PORT);
|
||||||
|
socket.send(payload);
|
||||||
|
|
||||||
|
socket.receive(payload);
|
||||||
|
|
||||||
|
buf = ByteBuffer.wrap(payload.getData());
|
||||||
|
if(buf.get() == 1){
|
||||||
|
System.out.println("--Connection request successful");
|
||||||
|
byte address[] = new byte[4];
|
||||||
|
buf = buf.get(address,0,4);
|
||||||
|
InetAddress addressObj = InetAddress.getByAddress(address);
|
||||||
|
addressString = addressObj.getHostAddress();
|
||||||
|
//emulate an unsigned short
|
||||||
|
char cast = buf.getChar();
|
||||||
|
port = (int) cast;
|
||||||
|
System.out.println("----Address : "+addressString);
|
||||||
|
System.out.println("----Port : "+port);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch ( IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opening final socket
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
//create all objects
|
||||||
|
AsynchronousDatagramSocket socket = new AsynchronousDatagramSocket();
|
||||||
|
PlaneContainer container = new PlaneContainer();
|
||||||
|
Printer printer = new Printer();
|
||||||
|
|
||||||
|
//bind them
|
||||||
|
socket.bindContainer(container);
|
||||||
|
container.bindPrinter(printer);
|
||||||
|
container.bindSocket(socket);
|
||||||
|
printer.bindContainer(container);
|
||||||
|
|
||||||
|
//send first packet
|
||||||
|
DatagramPacket p = new DatagramPacket(new byte[13],13,InetAddress.getByName(addressString),port);
|
||||||
|
socket.send(p);
|
||||||
|
|
||||||
|
//now we let the objects do the job
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue