Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
xdrm-brackets | 818ceef8df |
4
Makefile
4
Makefile
|
@ -28,7 +28,7 @@ link-viewTerm:
|
|||
|
||||
link-ctrlTerm:
|
||||
@echo "(5) Linking CTRL TERMINAL executable";
|
||||
@echo -e "#!/bin/bash\n\njava -jar ./ctrlTerm/commandTerm.jar;\n" > ./x-ctrlTerm;
|
||||
@echo -e "#!/bin/bash\n\njava -jar ./ctrlTerm/ctrlTerm.jar;\n" > ./x-ctrlTerm;
|
||||
@chmod ug+x ./x-ctrlTerm;
|
||||
|
||||
|
||||
|
@ -44,4 +44,4 @@ clean:
|
|||
@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;
|
||||
@make clean --directory=./plane > /dev/null;
|
||||
|
|
|
@ -1,524 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h> // close
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h> // getaddrinfo, getnameinfo
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#define TERMREQ_FBK 0x01
|
||||
#define TERMREQ_CAP 0x02
|
||||
#define TERMREQ_SPD 0x04
|
||||
#define TERMREQ_ALT 0x08
|
||||
|
||||
#define PLANE_LEN ( sizeof(char)*6+sizeof(int)*5 )
|
||||
struct plane{
|
||||
char code[6];
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int cap;
|
||||
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{
|
||||
char flags;
|
||||
struct plane update;
|
||||
};
|
||||
|
||||
struct term_res{
|
||||
char flags;
|
||||
char n;
|
||||
struct plane* data;
|
||||
};
|
||||
|
||||
|
||||
#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{
|
||||
char flags;
|
||||
in_addr_t addr;
|
||||
unsigned short port;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
socklen_t len;
|
||||
int msocket, csocket;
|
||||
struct sockaddr_in mcast, server;
|
||||
char buffer[512];
|
||||
struct bind_header bh;
|
||||
struct in_addr ip;
|
||||
struct term_req tr;
|
||||
struct term_res trs;
|
||||
int i, nb;
|
||||
struct plane tmp;
|
||||
int count, last;
|
||||
|
||||
strcpy(tmp.code, "\0");
|
||||
|
||||
/************************************************
|
||||
**** DEMANDE MULTICAST ****
|
||||
************************************************/
|
||||
printf("\n\nDEMANDE MCAST\n=============\n");
|
||||
if( 1 ){
|
||||
|
||||
/* [1] Initialisation socket
|
||||
=========================================================*/
|
||||
/* 1. Création socket */
|
||||
msocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if( msocket == -1 )
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* 2. Reset des valeurs */
|
||||
bzero(&mcast, sizeof(struct sockaddr_in));
|
||||
|
||||
/* 3. On définit les infos */
|
||||
mcast.sin_family = AF_INET;
|
||||
mcast.sin_port = htons(4446);
|
||||
mcast.sin_addr.s_addr = inet_addr("224.0.0.3");
|
||||
|
||||
|
||||
/* [2] On demande une socket de communication
|
||||
=========================================================*/
|
||||
/* 1. Création de la requête */
|
||||
len = sizeof(struct sockaddr_in);
|
||||
if( sendto(msocket, "\5\1\2\3\4\0\1", sizeof(char)*7, 0, (struct sockaddr*) &mcast, len) < 0 ){
|
||||
printf("cannot send multicast message.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* [3] On récupère la réponse
|
||||
=========================================================*/
|
||||
/* 1. On récupère la réponse */
|
||||
if( recvfrom(msocket, buffer, 512, 0, (struct sockaddr*) &mcast, &len) < BINDHDR_LEN ){
|
||||
printf("cannot receive multicast response.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* 2. On parse la réponse */
|
||||
memcpy(&bh.flags, buffer, sizeof(char));
|
||||
memcpy(&bh.addr, buffer+sizeof(char), sizeof(in_addr_t));
|
||||
memcpy(&bh.port, buffer+sizeof(char)+sizeof(in_addr_t), sizeof(unsigned short));
|
||||
// bh.addr = ntohl(bh.addr);
|
||||
bh.port = ntohs(bh.port);
|
||||
ip.s_addr = bh.addr;
|
||||
printf("Received: { flags: %d, addr: %x/'%s', port: %d}\n", bh.flags, bh.addr, inet_ntoa(ip), bh.port);
|
||||
|
||||
close(msocket);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************
|
||||
**** CONNECTION UDP ****
|
||||
************************************************/
|
||||
printf("\n\nCONNECTION UDP\n==============\n");
|
||||
if( 1 ){
|
||||
|
||||
/* [1] Initialisation socket
|
||||
=========================================================*/
|
||||
/* 1. Création socket */
|
||||
csocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if( csocket == -1 )
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* 2. Reset des valeurs */
|
||||
bzero(&server, sizeof(struct sockaddr_in));
|
||||
|
||||
/* 3. On définit les infos */
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(bh.port);
|
||||
server.sin_addr.s_addr = ip.s_addr;
|
||||
|
||||
|
||||
/* [2] Initialisation de la connexion
|
||||
=========================================================*/
|
||||
if( sendto(csocket, "0", 1, 0, (struct sockaddr*) &server, len) < 0 ){
|
||||
printf("Cannot send message through command socket.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("Connected to UDP socket\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
sleep(1);
|
||||
|
||||
|
||||
|
||||
/************************************************
|
||||
**** DEMANDE INFO CLASSIQUE ****
|
||||
************************************************/
|
||||
if( 1 ){
|
||||
printf("\n\nDEMANDE DES DONNEES UNIQUEMENT\n==============================\n");
|
||||
|
||||
/* [1] Preparing request
|
||||
=========================================================*/
|
||||
tr.flags = TERMREQ_FBK;
|
||||
strcpy(tr.update.code, "CODE1");
|
||||
tr.update.x = 1;
|
||||
tr.update.y = 2;
|
||||
tr.update.z = 3;
|
||||
tr.update.cap = 4;
|
||||
tr.update.spd = 5;
|
||||
printf("Sending { flags: %d; plane: #%s { z=%d; cap=%d; speed=%d} }\n", tr.flags, tr.update.code, tr.update.z, tr.update.cap, tr.update.spd);
|
||||
|
||||
tr.update.x = htonl(tr.update.x);
|
||||
tr.update.y = htonl(tr.update.y);
|
||||
tr.update.z = htonl(tr.update.z);
|
||||
tr.update.cap = htonl(tr.update.cap);
|
||||
tr.update.spd = htonl(tr.update.spd);
|
||||
|
||||
/* [2] Filling buffer
|
||||
=========================================================*/
|
||||
bzero(buffer, 512);
|
||||
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &tr.flags, sizeof(char));
|
||||
memcpy(buffer+sizeof(char)*1+sizeof(int)*0, &tr.update.code, sizeof(char)*6);
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*0, &tr.update.x, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*1, &tr.update.y, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*2, &tr.update.z, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*3, &tr.update.cap, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*4, &tr.update.spd, sizeof(int));
|
||||
|
||||
|
||||
/* [3] Sending request
|
||||
=========================================================*/
|
||||
if( sendto(csocket, buffer, 7+sizeof(int)*5+1, 0, (struct sockaddr*) &server, len) < 0 ){
|
||||
printf("Cannot ask for simple data.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* [4] Fetch & print data
|
||||
=========================================================*/
|
||||
/* 1. On récupère la réponse */
|
||||
len = sizeof(struct sockaddr_in);
|
||||
nb = recvfrom(csocket, buffer, 512, 0, (struct sockaddr*) &server, &len);
|
||||
|
||||
printf("%d bytes received\n", nb);
|
||||
|
||||
if( nb < 2 ){
|
||||
printf("Error receiving simple data.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* 2. On parse la réponse */
|
||||
count = 0; last = sizeof(char); memcpy(&trs.flags, buffer+count, last);
|
||||
count += last; last = sizeof(char); memcpy(&trs.n, buffer+count, last);
|
||||
|
||||
trs.data = malloc( sizeof(struct plane) * trs.n );
|
||||
|
||||
|
||||
for( i = 0 ; i < trs.n ; i++ ){
|
||||
count += last; last = sizeof(char)*6; memcpy(&trs.data[i].code, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].x, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].y, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].z, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].cap, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].spd, buffer+count, last);
|
||||
|
||||
trs.data[i].x = ntohl(trs.data[i].x);
|
||||
trs.data[i].y = ntohl(trs.data[i].y);
|
||||
trs.data[i].z = ntohl(trs.data[i].z);
|
||||
trs.data[i].cap = ntohl(trs.data[i].cap);
|
||||
trs.data[i].spd = ntohl(trs.data[i].spd);
|
||||
|
||||
printf("Plane[%s@%d] { (%d,%d,%d), cap: %d, spd: %d}\n", trs.data[i].code, i, trs.data[i].x, trs.data[i].y, trs.data[i].z, trs.data[i].cap, trs.data[i].spd);
|
||||
}
|
||||
|
||||
if( trs.n > 0 )
|
||||
memcpy(&tmp, &trs.data[0], sizeof(struct plane));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
sleep(1);
|
||||
|
||||
/************************************************
|
||||
**** DEMANDE MISE A JOUR SIMPLE ****
|
||||
************************************************/
|
||||
if( 1 ){
|
||||
printf("\n\nDEMANDE D'UPDATE SIMPLE\n=======================\n");
|
||||
|
||||
if( trs.n < 1 ){
|
||||
printf("No plane to update.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/* [1] Preparing request
|
||||
=========================================================*/
|
||||
tr.flags = TERMREQ_SPD;
|
||||
memcpy(&tr.update, &tmp, sizeof(struct plane));
|
||||
tr.update.spd = 1000;
|
||||
|
||||
printf("Update req { flags: %d; plane: #%s { z=%d; cap=%d; speed=%d} }\n", tr.flags, tr.update.code, tr.update.z, tr.update.cap, tr.update.spd);
|
||||
tr.update.x = htonl(tr.update.x);
|
||||
tr.update.y = htonl(tr.update.y);
|
||||
tr.update.z = htonl(tr.update.z);
|
||||
tr.update.cap = htonl(tr.update.cap);
|
||||
tr.update.spd = htonl(tr.update.spd);
|
||||
|
||||
/* [2] Filling buffer
|
||||
=========================================================*/
|
||||
bzero(buffer, 512);
|
||||
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &tr.flags, sizeof(char));
|
||||
memcpy(buffer+sizeof(char)*1+sizeof(int)*0, &tr.update.code, sizeof(char)*6);
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*0, &tr.update.x, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*1, &tr.update.y, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*2, &tr.update.z, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*3, &tr.update.cap, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*4, &tr.update.spd, sizeof(int));
|
||||
|
||||
|
||||
/* [3] Sending request
|
||||
=========================================================*/
|
||||
if( sendto(csocket, buffer, 7+sizeof(int)*5+1, 0, (struct sockaddr*) &server, len) < 0 ){
|
||||
printf("Cannot ask for simple update.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* [4] Fetch & print data
|
||||
=========================================================*/
|
||||
/* 1. On récupère la réponse */
|
||||
len = sizeof(struct sockaddr_in);
|
||||
nb = recvfrom(csocket, buffer, 512, 0, (struct sockaddr*) &server, &len);
|
||||
|
||||
printf("%d bytes received\n", nb);
|
||||
|
||||
if( nb < 1 ){
|
||||
printf("Error receiving simple update.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/* 2. On parse la réponse */
|
||||
count = 0; last = sizeof(char); memcpy(&trs.flags, buffer+count, last);
|
||||
count += last; last = sizeof(char); memcpy(&trs.n, buffer+count, last);
|
||||
printf("Flag received : %d\n", trs.flags);
|
||||
|
||||
trs.data = malloc( sizeof(struct plane) * trs.n );
|
||||
|
||||
|
||||
for( i = 0 ; i < trs.n ; i++ ){
|
||||
count += last; last = sizeof(char)*6; memcpy(&trs.data[i].code, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].x, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].y, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].z, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].cap, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].spd, buffer+count, last);
|
||||
|
||||
trs.data[i].x = ntohl(trs.data[i].x);
|
||||
trs.data[i].y = ntohl(trs.data[i].y);
|
||||
trs.data[i].z = ntohl(trs.data[i].z);
|
||||
trs.data[i].cap = ntohl(trs.data[i].cap);
|
||||
trs.data[i].spd = ntohl(trs.data[i].spd);
|
||||
|
||||
printf("Plane[%s@%d] { (%d,%d,%d), cap: %d, spd: %d}\n", trs.data[i].code, i, trs.data[i].x, trs.data[i].y, trs.data[i].z, trs.data[i].cap, trs.data[i].spd);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
sleep(1);
|
||||
|
||||
/************************************************
|
||||
**** DEMANDE MISE A JOUR SIMPLE + DATA ****
|
||||
************************************************/
|
||||
if( 1 ){
|
||||
printf("\n\nDEMANDE D'UPDATE SIMPLE + DATA\n==============================\n");
|
||||
|
||||
|
||||
|
||||
/* [1] Preparing request
|
||||
=========================================================*/
|
||||
tr.flags = TERMREQ_FBK|TERMREQ_ALT;
|
||||
memcpy(&tr.update, &tmp, sizeof(struct plane));
|
||||
tr.update.z = 500;
|
||||
|
||||
printf("Update req { flags: %d; plane: #%s { z=%d; cap=%d; speed=%d} }\n", tr.flags, tr.update.code, tr.update.z, tr.update.cap, tr.update.spd);
|
||||
tr.update.x = htonl(tr.update.x);
|
||||
tr.update.y = htonl(tr.update.y);
|
||||
tr.update.z = htonl(tr.update.z);
|
||||
tr.update.cap = htonl(tr.update.cap);
|
||||
tr.update.spd = htonl(tr.update.spd);
|
||||
|
||||
/* [2] Filling buffer
|
||||
=========================================================*/
|
||||
bzero(buffer, 512);
|
||||
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &tr.flags, sizeof(char));
|
||||
memcpy(buffer+sizeof(char)*1+sizeof(int)*0, &tr.update.code, sizeof(char)*6);
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*0, &tr.update.x, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*1, &tr.update.y, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*2, &tr.update.z, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*3, &tr.update.cap, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*4, &tr.update.spd, sizeof(int));
|
||||
|
||||
|
||||
/* [3] Sending request
|
||||
=========================================================*/
|
||||
if( sendto(csocket, buffer, 7+sizeof(int)*5+1, 0, (struct sockaddr*) &server, len) < 0 ){
|
||||
printf("Cannot ask for simple update.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* [4] Fetch & print data
|
||||
=========================================================*/
|
||||
/* 1. On récupère la réponse */
|
||||
len = sizeof(struct sockaddr_in);
|
||||
nb = recvfrom(csocket, buffer, 512, 0, (struct sockaddr*) &server, &len);
|
||||
|
||||
printf("%d bytes received\n", nb);
|
||||
|
||||
if( nb < 1 ){
|
||||
printf("Error receiving simple update.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/* 2. On parse la réponse */
|
||||
count = 0; last = sizeof(char); memcpy(&trs.flags, buffer+count, last);
|
||||
count += last; last = sizeof(char); memcpy(&trs.n, buffer+count, last);
|
||||
printf("Flag received : %d\n", trs.flags);
|
||||
|
||||
trs.data = malloc( sizeof(struct plane) * trs.n );
|
||||
|
||||
|
||||
for( i = 0 ; i < trs.n ; i++ ){
|
||||
count += last; last = sizeof(char)*6; memcpy(&trs.data[i].code, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].x, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].y, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].z, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].cap, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].spd, buffer+count, last);
|
||||
|
||||
trs.data[i].x = ntohl(trs.data[i].x);
|
||||
trs.data[i].y = ntohl(trs.data[i].y);
|
||||
trs.data[i].z = ntohl(trs.data[i].z);
|
||||
trs.data[i].cap = ntohl(trs.data[i].cap);
|
||||
trs.data[i].spd = ntohl(trs.data[i].spd);
|
||||
|
||||
printf("Plane[%s@%d] { (%d,%d,%d), cap: %d, spd: %d}\n", trs.data[i].code, i, trs.data[i].x, trs.data[i].y, trs.data[i].z, trs.data[i].cap, trs.data[i].spd);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
/************************************************
|
||||
**** DEMANDE MISE A JOUR COMBINEE ****
|
||||
************************************************/
|
||||
if( 1 ){
|
||||
printf("\n\nDEMANDE D'UPDATE MULTIPLE + DATA\n================================\n");
|
||||
|
||||
|
||||
|
||||
/* [1] Preparing request
|
||||
=========================================================*/
|
||||
tr.flags = TERMREQ_FBK|TERMREQ_ALT|TERMREQ_CAP|TERMREQ_SPD;
|
||||
memcpy(&tr.update, &tmp, sizeof(struct plane));
|
||||
tr.update.z = 2001;
|
||||
tr.update.cap = 21;
|
||||
tr.update.spd = 201;
|
||||
|
||||
printf("Update req { flags: %d; plane: #%s { z=%d; cap=%d; speed=%d} }\n", tr.flags, tr.update.code, tr.update.z, tr.update.cap, tr.update.spd);
|
||||
tr.update.x = htonl(tr.update.x);
|
||||
tr.update.y = htonl(tr.update.y);
|
||||
tr.update.z = htonl(tr.update.z);
|
||||
tr.update.cap = htonl(tr.update.cap);
|
||||
tr.update.spd = htonl(tr.update.spd);
|
||||
|
||||
/* [2] Filling buffer
|
||||
=========================================================*/
|
||||
bzero(buffer, 512);
|
||||
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &tr.flags, sizeof(char));
|
||||
memcpy(buffer+sizeof(char)*1+sizeof(int)*0, &tr.update.code, sizeof(char)*6);
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*0, &tr.update.x, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*1, &tr.update.y, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*2, &tr.update.z, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*3, &tr.update.cap, sizeof(int));
|
||||
memcpy(buffer+sizeof(char)*7+sizeof(int)*4, &tr.update.spd, sizeof(int));
|
||||
|
||||
|
||||
/* [3] Sending request
|
||||
=========================================================*/
|
||||
if( sendto(csocket, buffer, 7+sizeof(int)*5+1, 0, (struct sockaddr*) &server, len) < 0 ){
|
||||
printf("Cannot ask for simple update.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* [4] Fetch & print data
|
||||
=========================================================*/
|
||||
/* 1. On récupère la réponse */
|
||||
len = sizeof(struct sockaddr_in);
|
||||
nb = recvfrom(csocket, buffer, 512, 0, (struct sockaddr*) &server, &len);
|
||||
|
||||
printf("%d bytes received\n", nb);
|
||||
|
||||
if( nb < 1 ){
|
||||
printf("Error receiving simple update.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/* 2. On parse la réponse */
|
||||
count = 0; last = sizeof(char); memcpy(&trs.flags, buffer+count, last);
|
||||
count += last; last = sizeof(char); memcpy(&trs.n, buffer+count, last);
|
||||
printf("Flag received : %d\n", trs.flags);
|
||||
|
||||
trs.data = malloc( sizeof(struct plane) * trs.n );
|
||||
|
||||
|
||||
for( i = 0 ; i < trs.n ; i++ ){
|
||||
count += last; last = sizeof(char)*6; memcpy(&trs.data[i].code, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].x, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].y, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].z, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].cap, buffer+count, last);
|
||||
count += last; last = sizeof(int); memcpy(&trs.data[i].spd, buffer+count, last);
|
||||
|
||||
trs.data[i].x = ntohl(trs.data[i].x);
|
||||
trs.data[i].y = ntohl(trs.data[i].y);
|
||||
trs.data[i].z = ntohl(trs.data[i].z);
|
||||
trs.data[i].cap = ntohl(trs.data[i].cap);
|
||||
trs.data[i].spd = ntohl(trs.data[i].spd);
|
||||
|
||||
printf("Plane[%s@%d] { (%d,%d,%d), cap: %d, spd: %d}\n", trs.data[i].code, i, trs.data[i].x, trs.data[i].y, trs.data[i].z, trs.data[i].cap, trs.data[i].spd);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,204 +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 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;
|
||||
}
|
||||
}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;
|
||||
}
|
||||
}
|
||||
System.out.println("flags: "+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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package ControlTerminal;
|
||||
|
||||
public class InvalidFlagException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidFlagException(){
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidFlagException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
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<50){
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
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;
|
||||
|
||||
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.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 == 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;
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
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)");
|
||||
}
|
||||
}
|
|
@ -1,89 +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 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +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 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#include "client.h"
|
||||
|
||||
|
||||
|
||||
int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo){
|
||||
|
||||
/* [0] Initialisation des variables
|
||||
=========================================================*/
|
||||
*pSocket = -1;
|
||||
struct timeval timeout;
|
||||
|
||||
|
||||
/* [1] Création de la socket
|
||||
=======================================================*/
|
||||
/* 1. Création de la socket */
|
||||
*pSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
/* 2. Gestion erreur */
|
||||
if( *pSocket < 0 )
|
||||
return -1;
|
||||
|
||||
/* 3. Timeout */
|
||||
timeout.tv_sec = SOCK_TIMEOUT;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
if( setsockopt(*pSocket, SOL_SOCKET, SO_RCVTIMEO|SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
|
||||
close(*pSocket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* [2] On définit les infos de la socket
|
||||
=========================================================*/
|
||||
/* (1) Reset des valeurs */
|
||||
bzero(pInfo, sizeof(struct sockaddr_in));
|
||||
|
||||
/* (2) On définit les infos */
|
||||
pInfo->sin_family = AF_INET;
|
||||
pInfo->sin_port = htons(pPort);
|
||||
pInfo->sin_addr.s_addr = inet_addr(pAddr);
|
||||
|
||||
|
||||
/* [n] Code succès
|
||||
=========================================================*/
|
||||
return 0;
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/**************************
|
||||
* UDP Client Dependency *
|
||||
***************************
|
||||
* Designed & Developed by *
|
||||
* Adrien Marquès *
|
||||
* <xdrm-brackets> *
|
||||
***************************
|
||||
* doowap31@gmail.com *
|
||||
**************************/
|
||||
#ifndef _LIB_NETWORK_UDP_CLIENT_H_
|
||||
#define _LIB_NETWORK_UDP_CLIENT_H_
|
||||
|
||||
|
||||
/* Remarque:
|
||||
*
|
||||
* Il s'agit en réalité d'un serveur UDP, mais en multicast les membres du groupe pour qui sont copiées les requêtes
|
||||
* sont par habitude appelés clients
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "../../header.h"
|
||||
|
||||
|
||||
/* Créée une socket UDP + crée le sockaddr_in pour la suite
|
||||
*
|
||||
* ==IN==
|
||||
* @pAddr<const char*> Adresse du groupe multicast UDP
|
||||
* @pPort<const int> Port d'écoute UDP
|
||||
*
|
||||
* ==OUT==
|
||||
* @pSocket<int*> Pointeur sur le <int> à rempliR => contiendra un pointeur sur la socket créée
|
||||
* @pInfo<sockaddr_in*> Pointeur sur le <sockaddr_In> à remplir => contiendra un pointeur sur les infos server
|
||||
*
|
||||
* ==RETURN==
|
||||
* @status<int> -1 si erreur, sinon 0
|
||||
*
|
||||
* @history
|
||||
* [1] Création de la socket
|
||||
* [2] On définit les infos de la socket
|
||||
* [3] On crée la socket
|
||||
*
|
||||
*
|
||||
*/
|
||||
int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo);
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,21 +0,0 @@
|
|||
#!/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;
|
|
@ -1,10 +0,0 @@
|
|||
[Unit]
|
||||
Description=Systeme de Gestion du Controle Aerien
|
||||
Requires=network.target
|
||||
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
ExecStart=/usr/sbin/sgca
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# [1] Remove service target (boot)
|
||||
sudo rm /usr/sbin/sgca;
|
||||
|
||||
# [2] Disable service
|
||||
sudo systemctl stop sgca.service;
|
||||
sudo systemctl disable sgca.service;
|
||||
|
||||
# [3] Remove service unit
|
||||
sudo rm /lib/systemd/system/sgca.service;
|
||||
|
||||
# [4] Remove log file
|
||||
sudo rm /var/log/sgca;
|
||||
|
|
@ -1,89 +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 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 ViewTerminal.InvalidFlagException;
|
||||
import ViewTerminal.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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +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 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package ViewTerminal;
|
||||
|
||||
public class InvalidFlagException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidFlagException(){
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidFlagException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
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<50){
|
||||
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 "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,102 +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 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue