sysdis-project/plane/plane.c

269 lines
7.2 KiB
C

/**************************
* Plane *
***************************
* Designed & Developed by *
* Adrien Marquès *
* <xdrm-brackets> *
***************************
* doowap31@gmail.com *
**************************/
#include "plane.h"
// numéro de vol de l'plane : code sur 5 caractères
char numero_vol[6];
struct coord crd;
struct control ctrl;
int mcast_socket = -1;
int commu_socket = -1;
char buffer[MAX_BUF_LEN] = {0};
int open_communication(){
/* 0. Initialisation des variables */
struct sockaddr_in udp, tcp; // données des sockets
char buffer[MAX_BUF_LEN] = {0}; // buffer
int status;
struct bind_header request;
/* [1] Socket Multicast UDP
=========================================================*/
/* (1) Création socket multicast
---------------------------------------------------------*/
if( UDP_SOCKET(&mcast_socket, MCST_HOST, MCST_PORT, &udp) < 0 )
return 0;
/* (2) Envoi séquence initialisation avion
---------------------------------------------------------*/
/* 1. Construction séquence d'initialisation */
// memcpy(buffer, numero_vol, sizeof(char)*6);
request.flags = BINDHEAD_TCP;
strcpy(request.addr, "000.000.000.000");
request.port = 0;
memcpy(buffer+sizeof(char)*0, &request.flags, sizeof(char));
memcpy(buffer+sizeof(char)*1, &request.addr, sizeof(char)*INET_ADDRSTRLEN);
memcpy(buffer+sizeof(char)*(1+INET_ADDRSTRLEN), &request.port, sizeof(unsigned short));
/* 2. Envoi séquence */
if( sendto(mcast_socket, buffer, BINDHDR_LEN/sizeof(char) +1, 0, (struct sockaddr*) &udp, sizeof(struct sockaddr_in)) < 0 ){
close(mcast_socket);
return 0;
}
/* (3) Attente réponse SGCA -> adresse+port TCP
---------------------------------------------------------*/
/* 1. Attente réponse */
status = recv(mcast_socket, buffer, MAX_BUF_LEN, 0);
/* 2. Gestion erreur */
if( status < 0 ){
close(mcast_socket);
return 0;
}
/* 3. Vérification taille */
if( status < BINDHDR_LEN ){
close(mcast_socket);
return 0;
}
/* 4. On récupère les données */
bzero(&request, sizeof(struct bind_header));
memcpy(&request.addr, buffer, sizeof(char) );
memcpy(&request.addr, buffer+sizeof(char), sizeof(char)*INET_ADDRSTRLEN );
memcpy(&request.port, buffer+sizeof(char)*(1+INET_ADDRSTRLEN), sizeof(unsigned short) );
printf("bind_header{flags = %d; addr = %s; port = %d;}\n\n", request.flags, request.addr, request.port);
/* [2] Socket communication TCP
=========================================================*/
/* (1) Création socket TCP + connection
---------------------------------------------------------*/
/* 1. Création socket TCP + connection serveur */
if( TCP_CONNECT(&commu_socket, request.addr, request.port, &tcp) < 0 )
return 0;
return 1;
}
void close_communication(){
// fonction à implémenter qui permet de fermer la communication
// avec le gestionnaire de vols
}
void send_data(){
/* [0] Initialisation des variables
=========================================================*/
char buffer[MAX_BUF_LEN] = {0};
struct plane_data request;
int read;
/* [1] Envoi des caractéristiques
=========================================================*/
/* 1. Vérification socket */
if( commu_socket < 0 )
return;
/* 2. création objet */
strcpy(request.code, numero_vol);
request.x = crd.x;
request.y = crd.y;
request.z = crd.z;
request.cap = ctrl.cap;
request.spd = ctrl.speed;
/* 3. Copie buffer */
strcpy(buffer, request.code);
memcpy(buffer+sizeof(char)*0+sizeof(int)*0, &request.code, sizeof(char)*6 );
memcpy(buffer+sizeof(char)*6+sizeof(int)*0, &request.x, sizeof(int) );
memcpy(buffer+sizeof(char)*6+sizeof(int)*1, &request.y, sizeof(int) );
memcpy(buffer+sizeof(char)*6+sizeof(int)*2, &request.z, sizeof(int) );
memcpy(buffer+sizeof(char)*6+sizeof(int)*3, &request.cap, sizeof(int) );
memcpy(buffer+sizeof(char)*6+sizeof(int)*4, &request.spd, sizeof(int) );
read = send(commu_socket, buffer, PLANE_DATA_LEN/sizeof(char) + 1, 0);
if( read < 0 ){
printf("Erreur d'envoi\n");
return;
}
/* 4. Récupération réponse */
//TODO: recv()
/* 5. Gestion mise à jour */
//TODO: update_cap etc avec flags
}
/********************************
*** Fonctions gérant le déplacement de l'plane : ne pas modifier
********************************/
// initialise aléatoirement les paramètres initiaux de l'plane
void init_plane(){
// initialisation aléatoire du compteur aléatoire
time_t seed;
time( &seed);
srandom(seed);
// intialisation des paramètres de l'plane
crd.x = 1000 + random() % 1000;
crd.y = 1000 + random() % 1000;
crd.z = 900 + random() % 100;
ctrl.cap = random() % 360;
ctrl.speed = 600 + random() % 200;
// initialisation du numero de l'plane : chaine de 5 caractères
// formée de 2 lettres puis 3 chiffres
numero_vol[0] = (random() % 26) + 'A';
numero_vol[1] = (random() % 26) + 'A';
numero_vol[2] = (random() % 10) + '0';
numero_vol[3] = (random() % 10) + '0';
numero_vol[4] = (random() % 10) + '0';
numero_vol[5] = 0;
}
// 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;
}
// modifie le cap de l'plane avec la valeur passée en paramètre
void update_cap(int cap){
if ((cap >= 0) && (cap < 360))
ctrl.cap = cap;
}
// modifie l'z de l'plane avec la valeur passée en paramètre
void update_z(int alt){
if (alt < 0)
crd.z = alt;
}
// affiche les caractéristiques courantes de l'plane
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);
}
// recalcule la localisation de l'plane en fonction de sa speed et de son cap
void calc_ctrl(){
float ctrl_x, ctrl_y;
if (ctrl.speed < VITMIN){
close_communication();
exit(2);
}
if (crd.z == 0){
close_communication();
exit(3);
}
ctrl_x = cos(ctrl.cap * 2 * M_PI / 360) * ctrl.speed * 10 / VITMIN;
ctrl_y = sin(ctrl.cap * 2 * M_PI / 360) * ctrl.speed * 10 / VITMIN;
// on se déplace d'au moins une case quels que soient le cap et la speed
// sauf si cap est un des angles droit
if ((ctrl_x > 0) && (ctrl_x < 1)) ctrl_x = 1;
if ((ctrl_x < 0) && (ctrl_x > -1)) ctrl_x = -1;
if ((ctrl_y > 0) && (ctrl_y < 1)) ctrl_y = 1;
if ((ctrl_y < 0) && (ctrl_y > -1)) ctrl_y = -1;
crd.x = crd.x + (int)ctrl_x;
crd.y = crd.y + (int)ctrl_y;
display_data();
}
// fonction principale : gère l'exécution de l'plane au fil du temps
void update(){
while( 1 ){
sleep(PAUSE);
calc_ctrl();
send_data();
}
}
int main(){
// on initialise le plane
init_plane();
display_data();
// on quitte si on arrive à pas contacter le gestionnaire de vols
if( !open_communication() ){
exit(1);
}
// on se déplace une fois toutes les initialisations faites
update();
}