[CREATED] ctrlTerm emulation in C
This commit is contained in:
parent
4af2f8180c
commit
061893b35d
|
@ -0,0 +1,348 @@
|
||||||
|
#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;
|
||||||
|
int count, last;
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
**** DEMANDE MULTICAST ****
|
||||||
|
************************************************/
|
||||||
|
printf("DEMANDE MCAST\n=============\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("CONNECTION UDP\n==============\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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
**** DEMANDE INFO CLASSIQUE ****
|
||||||
|
************************************************/
|
||||||
|
if( 1 ){
|
||||||
|
printf("DEMANDE DES DONNEES UNIQUEMENT\n==============================\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
**** DEMANDE MISE A JOUR SIMPLE ****
|
||||||
|
************************************************/
|
||||||
|
if( 1 ){
|
||||||
|
printf("DEMANDE D'UPDATE SIMPLE\n=======================\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, &trs.data[0], 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
**** DEMANDE MISE A JOUR COMBINEE ****
|
||||||
|
************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue