/************************** * Plane * *************************** * Designed & Developed by * * Adrien Marquès * * * *************************** * 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 client* (écoute) ---------------------------------------------------------*/ if( DROP_MULTICAST_SERVER(MCST_HOST, MCST_PORT, &mcast_socket, &udp) < 0 ) return 0; // *un client multicast est en fait un serveur UDP, mais le terme persiste car le service est délivré par le CLIENT UDP /* (2) 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) ); // on indian-switch request.port = ntohs(request.port); printf("* received 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 */ 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 } /******************************** *** 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(); }