|  | @@ -8,6 +8,7 @@
 | 
											
												
													
														|  |  #include <stdio.h>
 |  |  #include <stdio.h>
 | 
											
												
													
														|  |  #include <stdlib.h>
 |  |  #include <stdlib.h>
 | 
											
												
													
														|  |  #include <pthread.h>
 |  |  #include <pthread.h>
 | 
											
												
													
														|  | 
 |  | +#include <signal.h>
 | 
											
												
													
														|  |  #include "arraylist.h"
 |  |  #include "arraylist.h"
 | 
											
												
													
														|  |  #include "bomberstudent_server.h"
 |  |  #include "bomberstudent_server.h"
 | 
											
												
													
														|  |  #include "error.h"
 |  |  #include "error.h"
 | 
											
										
											
												
													
														|  | @@ -17,25 +18,61 @@ arraylist get;
 | 
											
												
													
														|  |  arraylist post;
 |  |  arraylist post;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  /* --- Fonctions privées --- */
 |  |  /* --- Fonctions privées --- */
 | 
											
												
													
														|  | -void* udp_thread(void* data){
 |  | 
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/**
 | 
											
												
													
														|  | 
 |  | + * Thread de gestion d'un client
 | 
											
												
													
														|  | 
 |  | + * @param data
 | 
											
												
													
														|  | 
 |  | + * @return 
 | 
											
												
													
														|  | 
 |  | + */
 | 
											
												
													
														|  | 
 |  | +void* client_thread(void* data) {
 | 
											
												
													
														|  | 
 |  | +    int* tmp, cliId, nbError = 0;
 | 
											
												
													
														|  | 
 |  | +    Client* cli;
 | 
											
												
													
														|  | 
 |  | +    //Recup la valeur de data
 | 
											
												
													
														|  | 
 |  | +    tmp = (int*) data;
 | 
											
												
													
														|  | 
 |  | +    cliId = *tmp;
 | 
											
												
													
														|  | 
 |  | +    //Recup le client
 | 
											
												
													
														|  | 
 |  | +    cli = get_client(cliId);
 | 
											
												
													
														|  | 
 |  | +    if (cli == NULL) {
 | 
											
												
													
														|  | 
 |  | +        adderror("Le client n'existe pas");
 | 
											
												
													
														|  | 
 |  | +        return NULL;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    //Attente requete du client
 | 
											
												
													
														|  | 
 |  | +    while (true) {
 | 
											
												
													
														|  | 
 |  | +        if (!receive_client(cli)) {
 | 
											
												
													
														|  | 
 |  | +            adderror("Erreur lors de la reception d'une requete du client");
 | 
											
												
													
														|  | 
 |  | +            nbError++;
 | 
											
												
													
														|  | 
 |  | +        } else {
 | 
											
												
													
														|  | 
 |  | +            nbError = 0;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        //Si trop d'erreur d'affilé
 | 
											
												
													
														|  | 
 |  | +        if (nbError == NBERRORRESET) {
 | 
											
												
													
														|  | 
 |  | +            //Fermeture du client et fin du thread
 | 
											
												
													
														|  | 
 |  | +            remove_client(cliId);
 | 
											
												
													
														|  | 
 |  | +            break;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    return NULL;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +void* udp_thread(void* data) {
 | 
											
												
													
														|  |      Server s;
 |  |      Server s;
 | 
											
												
													
														|  |      char buffer[BUFFER_SIZE];
 |  |      char buffer[BUFFER_SIZE];
 | 
											
												
													
														|  |      //Cast data en serveur
 |  |      //Cast data en serveur
 | 
											
												
													
														|  |      s = (Server) data;
 |  |      s = (Server) data;
 | 
											
												
													
														|  |      //Detache le thread
 |  |      //Detache le thread
 | 
											
												
													
														|  | -    if(pthread_detach(pthread_self()) != 0){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (pthread_detach(pthread_self()) != 0) {
 | 
											
												
													
														|  |          return NULL;
 |  |          return NULL;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      //Boucle attente
 |  |      //Boucle attente
 | 
											
												
													
														|  | -    while(true){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    while (true) {
 | 
											
												
													
														|  |          //Attente connexion
 |  |          //Attente connexion
 | 
											
												
													
														|  | -        if(s->server_receive(s, buffer, BUFFER_SIZE) == ERR){
 |  | 
 | 
											
												
													
														|  | 
 |  | +        if (s->server_receive(s, buffer, BUFFER_SIZE) == ERR) {
 | 
											
												
													
														|  |              addserror("Impossible de recevoir le demande de recherche");
 |  |              addserror("Impossible de recevoir le demande de recherche");
 | 
											
												
													
														|  |              continue;
 |  |              continue;
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          //Si la phrase est correcte
 |  |          //Si la phrase est correcte
 | 
											
												
													
														|  | -        if(strncmp(buffer, SEARCH_SERV, strlen(buffer)) == 0){
 |  | 
 | 
											
												
													
														|  | -            if(!s->server_send(s, "i'm a bomberstudent server")){
 |  | 
 | 
											
												
													
														|  | 
 |  | +        if (strncmp(buffer, SEARCH_SERV, strlen(buffer)) == 0) {
 | 
											
												
													
														|  | 
 |  | +            if (!s->server_send(s, "i'm a bomberstudent server")) {
 | 
											
												
													
														|  |                  addserror("Impossible de repondre à la recherche");
 |  |                  addserror("Impossible de repondre à la recherche");
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
										
											
												
													
														|  | @@ -43,68 +80,64 @@ void* udp_thread(void* data){
 | 
											
												
													
														|  |      return NULL;
 |  |      return NULL;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -//Thread initialisation de la communication principale entre client et serveur
 |  | 
 | 
											
												
													
														|  | -//Connexion utilisé pour traiter les requetes emise par le client
 |  | 
 | 
											
												
													
														|  | -void* tcp_cli_thread(void* data){
 |  | 
 | 
											
												
													
														|  | -    Server s;
 |  | 
 | 
											
												
													
														|  | -    //Cast data en serveur
 |  | 
 | 
											
												
													
														|  | -    s = (Server) data;
 |  | 
 | 
											
												
													
														|  | -    //Detache le thread
 |  | 
 | 
											
												
													
														|  | -    if(pthread_detach(pthread_self()) != 0){
 |  | 
 | 
											
												
													
														|  | -        return NULL;
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -    //Boucle attente
 |  | 
 | 
											
												
													
														|  | -    while(true){
 |  | 
 | 
											
												
													
														|  | -        
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -    return NULL;
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -//Thread initialisation de la communication utilisé par le serveur pour notifier les clients
 |  | 
 | 
											
												
													
														|  | -void* tcp_serv_thread(void* data){
 |  | 
 | 
											
												
													
														|  | -    Server s;
 |  | 
 | 
											
												
													
														|  | 
 |  | +void* tcp_thread(void* data) {
 | 
											
												
													
														|  | 
 |  | +    Server* s;
 | 
											
												
													
														|  | 
 |  | +    boolean res;
 | 
											
												
													
														|  | 
 |  | +    int cliId;
 | 
											
												
													
														|  | 
 |  | +    pthread_t client;
 | 
											
												
													
														|  |      //Cast data en serveur
 |  |      //Cast data en serveur
 | 
											
												
													
														|  | -    s = (Server) data;
 |  | 
 | 
											
												
													
														|  | 
 |  | +    s = (Server*) data;
 | 
											
												
													
														|  |      //Detache le thread
 |  |      //Detache le thread
 | 
											
												
													
														|  | -    if(pthread_detach(pthread_self()) != 0){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (pthread_detach(pthread_self()) != 0) {
 | 
											
												
													
														|  |          return NULL;
 |  |          return NULL;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      //Boucle attente
 |  |      //Boucle attente
 | 
											
												
													
														|  | -    while(true){
 |  | 
 | 
											
												
													
														|  | -        
 |  | 
 | 
											
												
													
														|  | 
 |  | +    while (true) {
 | 
											
												
													
														|  | 
 |  | +        res = s[0]->server_accept(s[0]);
 | 
											
												
													
														|  | 
 |  | +        res = res && s[1]->server_accept(s[1]);
 | 
											
												
													
														|  | 
 |  | +        if (!res) {
 | 
											
												
													
														|  | 
 |  | +            addserror("Impossible d'etablir la connexion TCP");
 | 
											
												
													
														|  | 
 |  | +            continue;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        //Creation d'un client et de son thread
 | 
											
												
													
														|  | 
 |  | +        cliId = add_client(s[0], s[1]);
 | 
											
												
													
														|  | 
 |  | +        if (pthread_create(&client, NULL, client_thread, &cliId) != 0) {
 | 
											
												
													
														|  | 
 |  | +            adderror("Impossible de créer le thread CLient");
 | 
											
												
													
														|  | 
 |  | +            /*ToDo Avertir Client du probleme*/
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      return NULL;
 |  |      return NULL;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  /* --- Fonctions publiques --- */
 |  |  /* --- Fonctions publiques --- */
 | 
											
												
													
														|  | -void ini_server(){
 |  | 
 | 
											
												
													
														|  | 
 |  | +void ini_server() {
 | 
											
												
													
														|  |      arraylist_ini(&get);
 |  |      arraylist_ini(&get);
 | 
											
												
													
														|  |      arraylist_ini(&post);
 |  |      arraylist_ini(&post);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -void add_handler(char* method, char* ressource, int(*handler)(Server, JsonParser*)){
 |  | 
 | 
											
												
													
														|  | -    if(strncmp(method, "POST", 5) == 0){
 |  | 
 | 
											
												
													
														|  | 
 |  | +void add_handler(char* method, char* ressource, int(*handler)(int, JsonParser*)) {
 | 
											
												
													
														|  | 
 |  | +    if (strncmp(method, "POST", 5) == 0) {
 | 
											
												
													
														|  |          arraylist_add(&post, ressource, handler);
 |  |          arraylist_add(&post, ressource, handler);
 | 
											
												
													
														|  | -    } else if(strncmp(method, "POST", 5) == 0){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    } else if (strncmp(method, "POST", 5) == 0) {
 | 
											
												
													
														|  |          arraylist_add(&get, ressource, handler);
 |  |          arraylist_add(&get, ressource, handler);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -boolean launch_udp_server(int port){
 |  | 
 | 
											
												
													
														|  | 
 |  | +boolean launch_udp_server(int port) {
 | 
											
												
													
														|  |      Server s;
 |  |      Server s;
 | 
											
												
													
														|  |      pthread_t udp;
 |  |      pthread_t udp;
 | 
											
												
													
														|  |      //Creation serveur
 |  |      //Creation serveur
 | 
											
												
													
														|  |      s = server_create_udp();
 |  |      s = server_create_udp();
 | 
											
												
													
														|  | -    if(s == NULL){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (s == NULL) {
 | 
											
												
													
														|  |          addserror("Impossible de créer le serveur UDP");
 |  |          addserror("Impossible de créer le serveur UDP");
 | 
											
												
													
														|  |          return false;
 |  |          return false;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | -    if(!s->server_bind(s, port)){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (!s->server_bind(s, port)) {
 | 
											
												
													
														|  |          addserror("Impossible de bind le serveur UDP");
 |  |          addserror("Impossible de bind le serveur UDP");
 | 
											
												
													
														|  |          return false;
 |  |          return false;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      //Lancement thread serveur udp
 |  |      //Lancement thread serveur udp
 | 
											
												
													
														|  | -    if(pthread_create(&udp, NULL, udp_thread, s) != 0){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (pthread_create(&udp, NULL, udp_thread, s) != 0) {
 | 
											
												
													
														|  |          adderror("Impossible de créer le thread UDP");
 |  |          adderror("Impossible de créer le thread UDP");
 | 
											
												
													
														|  |          server_close(s);
 |  |          server_close(s);
 | 
											
												
													
														|  |          return false;
 |  |          return false;
 | 
											
										
											
												
													
														|  | @@ -112,36 +145,86 @@ boolean launch_udp_server(int port){
 | 
											
												
													
														|  |      return true;
 |  |      return true;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -boolean launch_tcp_server(int port){
 |  | 
 | 
											
												
													
														|  | -    Server s[2];
 |  | 
 | 
											
												
													
														|  | 
 |  | +boolean launch_tcp_server(int port) {
 | 
											
												
													
														|  | 
 |  | +    Server* s;
 | 
											
												
													
														|  |      pthread_t tcp;
 |  |      pthread_t tcp;
 | 
											
												
													
														|  |      //Creation serveur
 |  |      //Creation serveur
 | 
											
												
													
														|  | 
 |  | +    s = malloc(sizeof (Server) * 2);
 | 
											
												
													
														|  |      s[0] = server_create_tcp();
 |  |      s[0] = server_create_tcp();
 | 
											
												
													
														|  |      s[1] = server_create_tcp();
 |  |      s[1] = server_create_tcp();
 | 
											
												
													
														|  | -    if(s[0] == NULL || s[1] == NULL){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (s[0] == NULL || s[1] == NULL) {
 | 
											
												
													
														|  |          addserror("Impossible de créer les serveurs TCP");
 |  |          addserror("Impossible de créer les serveurs TCP");
 | 
											
												
													
														|  |          return false;
 |  |          return false;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | -    if(!( s[0]->server_bind(s[0], port) && s[1]->server_bind(s[1], port + 1) )){
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (!(s[0]->server_bind(s[0], port) && s[1]->server_bind(s[1], port + 1))) {
 | 
											
												
													
														|  |          addserror("Impossible de bind les serveurs TCP");
 |  |          addserror("Impossible de bind les serveurs TCP");
 | 
											
												
													
														|  |          return false;
 |  |          return false;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      //Lancement Thread attente connexion TCP 
 |  |      //Lancement Thread attente connexion TCP 
 | 
											
												
													
														|  | -    if(pthread_create(&tcp, NULL, tcp_cli_thread, s[0]) != 0){
 |  | 
 | 
											
												
													
														|  | -        adderror("Impossible de créer le thread TCP Client");
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if (pthread_create(&tcp, NULL, tcp_thread, s) != 0) {
 | 
											
												
													
														|  | 
 |  | +        adderror("Impossible de créer le thread TCP");
 | 
											
												
													
														|  |          server_close(s[0]);
 |  |          server_close(s[0]);
 | 
											
												
													
														|  |          server_close(s[1]);
 |  |          server_close(s[1]);
 | 
											
												
													
														|  |          return false;
 |  |          return false;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | -    if(pthread_create(&tcp, NULL, tcp_serv_thread, s[1]) != 0){
 |  | 
 | 
											
												
													
														|  | -        adderror("Impossible de créer le thread TCP Serveur");
 |  | 
 | 
											
												
													
														|  | -        server_close(s[0]);
 |  | 
 | 
											
												
													
														|  | -        server_close(s[1]);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    return true;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +boolean receive_client(Client* cli) {
 | 
											
												
													
														|  | 
 |  | +    char buffer[BUFFER_SIZE];
 | 
											
												
													
														|  | 
 |  | +    char* reader, * ressource, * json = NULL;
 | 
											
												
													
														|  | 
 |  | +    int method, pos, compteur = 0;
 | 
											
												
													
														|  | 
 |  | +    JsonParser* jp = NULL;
 | 
											
												
													
														|  | 
 |  | +    arraylist* al = &get;
 | 
											
												
													
														|  | 
 |  | +    //Attente reception
 | 
											
												
													
														|  | 
 |  | +    printf("Ici\n");
 | 
											
												
													
														|  | 
 |  | +    if (cli->main->server_receive(cli->main, buffer, BUFFER_SIZE) == ERR) {
 | 
											
												
													
														|  | 
 |  | +        addserror("Impossible de recevoire les données du client");
 | 
											
												
													
														|  | 
 |  | +        return false;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    //Recup la methode
 | 
											
												
													
														|  | 
 |  | +    if (buffer[0] == 'P') {
 | 
											
												
													
														|  | 
 |  | +        pos = 5;
 | 
											
												
													
														|  | 
 |  | +        reader = buffer + pos;
 | 
											
												
													
														|  | 
 |  | +        method = POST;
 | 
											
												
													
														|  | 
 |  | +    } else if (buffer[0] == 'G') {
 | 
											
												
													
														|  | 
 |  | +        pos = 4;
 | 
											
												
													
														|  | 
 |  | +        reader = buffer + pos;
 | 
											
												
													
														|  | 
 |  | +        method = GET;
 | 
											
												
													
														|  | 
 |  | +    } else {
 | 
											
												
													
														|  | 
 |  | +        //Methode incorrect
 | 
											
												
													
														|  | 
 |  | +        return false;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    //Recup la ressource
 | 
											
												
													
														|  | 
 |  | +    while (buffer[pos] != '\n' && buffer[pos] != '\0') {
 | 
											
												
													
														|  | 
 |  | +        compteur++;
 | 
											
												
													
														|  | 
 |  | +        pos++;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    if (compteur == 0) {
 | 
											
												
													
														|  | 
 |  | +        return false;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    ressource = malloc(sizeof (char) * compteur);
 | 
											
												
													
														|  | 
 |  | +    strncpy(ressource, reader, compteur);
 | 
											
												
													
														|  | 
 |  | +    //Recup param JSON
 | 
											
												
													
														|  | 
 |  | +    if (method == POST) {
 | 
											
												
													
														|  | 
 |  | +        if (buffer[pos] == '\0') {
 | 
											
												
													
														|  | 
 |  | +            //Pas de parametre avec le post
 | 
											
												
													
														|  | 
 |  | +            return false;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        json = reader + compteur + 1;
 | 
											
												
													
														|  | 
 |  | +        jp = malloc(sizeof (JsonParser));
 | 
											
												
													
														|  | 
 |  | +        if (json_parse(jp, json) != JSON_OK) {
 | 
											
												
													
														|  | 
 |  | +            return false;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        //Change la liste à utiliser
 | 
											
												
													
														|  | 
 |  | +        al = &post;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    //Appel le callback
 | 
											
												
													
														|  | 
 |  | +    if (arraylist_call(al, ressource, cli->id, jp) == ERR) {
 | 
											
												
													
														|  |          return false;
 |  |          return false;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      return true;
 |  |      return true;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -boolean receive_client(Server);
 |  | 
 | 
											
												
													
														|  | -boolean send_client(Server, JsonEncoder*);
 |  | 
 | 
											
												
													
														|  | -boolean notify_client(Server, char*, char*, JsonEncoder*);
 |  | 
 | 
											
												
													
														|  | 
 |  | +boolean send_client(Client* cli, JsonEncoder* answer);
 | 
											
												
													
														|  | 
 |  | +boolean notify_client(Client* cli, char* method, char* ressource, JsonEncoder* param);
 |