threadSocket.c 5.02 KB
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "http.h"
#include "libnet.h"
#include "libthrd.h"


void vider_interfaces(Arg_Thread* argument)
{
	pthread_mutex_lock(&(argument->requete_mutex)); // Section critique

	for(int i=0; i<20; i++)
	{
		if(argument->interfaces[i]!=NULL)
		{
			free(argument->interfaces[i]);
			argument->interfaces[i]=NULL;
		}
	}

	pthread_mutex_unlock(&(argument->requete_mutex)); // Libération de la section critique

}


int httpReponse(FILE* sockdial_stream, Arg_Thread* argument)
{	
	char message[]={0x00,0x00};

	sendUDPBroadcast(message, 2020);

	struct PageWeb* page; 

	sleep(1); // Temps d'attente avant de recevoir les informations

	pthread_mutex_lock(&(argument->requete_mutex)); // Section critique

	createPage(&page, argument->interfaces); // Permet de creer la pageweb (http.c)
	
	pthread_mutex_unlock(&(argument->requete_mutex)); // Libération de la section critique

	char buffer[BUFF_SIZE];	// Le buffer de message pour l'emission
	// char buff_rec[BUFF_SIZE]; // Le buffer de message à la reception

	strcat(buffer,"HTTP/1.1 200 OK\r\nServer: Serveur Sioux\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: Keep-alive\r\n\r\n"); // Header HTTP

	fprintf(sockdial_stream, "%s", buffer);

	strcpy(buffer, page->html_contents);

	fprintf(sockdial_stream, "%s", buffer);

	freePage(&page);

	return 0;
}




int interfaceReponse(FILE* sockdial_stream, char packet[BUFF_SIZE], Arg_Thread* argument, char adresse[20])
{
	printf("Interface : %x %x - Adresse : %s - Taille : %ld\n", packet[0], packet[1], adresse, strlen(packet));
	
	char buffer[BUFF_SIZE];	

	// On lock le mutex car on rentre dans la section critique (modification de la structure interfaces)

	pthread_mutex_lock(&(argument->requete_mutex));

	int i=0;
	while(argument->interfaces[i]!=NULL && strcmp(adresse, argument->interfaces[i]->adresse)!=0)
	{
		i++;	
	}
	
	if(argument->interfaces[0]!=NULL)
		printf("Il y a %d associations\n", i+1);
	else
		printf("Il n'y aucune association\n");


	if(argument->interfaces[i]!=NULL)
		argument->interfaces[i]->status=-1;


	if(packet[0]==0x20 && (packet[1]==0x01 || packet[1]==0x00) )
	{		
		//L'interface a correctement répondu, on la rajoute à la liste des interfaces
		printf("L'interface a correctement répondu\n");

		if(argument->interfaces[i]==NULL)
		{
			argument->interfaces[i]=malloc(sizeof(struct interface_info));
			strcpy(argument->interfaces[i]->adresse, adresse);
		}

		if(packet[1]==0x01)
			argument->interfaces[i]->status=1;
		else
			argument->interfaces[i]->status=0;		

	}
	else
	{	// L'interface n a pas correctement répondu
		
		pthread_mutex_unlock(&(argument->requete_mutex)); // Libération de la section critique
		printf("L'interface n'a pas correctement répondu\n");

		return -1;
	}

	strcpy(buffer, "\x60\x00"); // Demande la commande en mémoire

	fprintf(sockdial_stream, "%s", buffer); // Transmission du message 

	fgets(packet, BUFF_SIZE, sockdial_stream); // Attente de reception du message
	
	if( strlen(packet)>=2 && (packet[0]&0xE0)==0x10 )
		argument->interfaces[i]->commande = (packet[0]&0x1F)*256+packet[1];
	else
	{
		argument->interfaces[i]->commande = -1;
		//return -1; // Si le message n'est pas reçu correctement
	}
	
	strcpy(buffer, "\xE0\x00"); // Signale la fin de l'interrogation

	fprintf(sockdial_stream, "%s", buffer); // Transmission du message

	pthread_mutex_unlock(&(argument->requete_mutex)); // Libération de la section critique

	return 0;
}



void* reponseConnexion(void* arg_sock_interf)
{	
	Arg_Thread *argument=(Arg_Thread*)(arg_sock_interf);
	int sock=argument->socket;

	printf("Connected\n"); // Affiche le fait que qqn soit connecté

	FILE* sockdial_stream = fdopen(sock, "a+"); 

	char buff_rec[BUFF_SIZE]; // Le buffer de message à la reception
	// char buffer[BUFF_SIZE];	// Le buffer de message pour l'emission

	printf("FGETS\n");
	fgets(buff_rec, BUFF_SIZE, sockdial_stream);
	
	printf("Le message reçu : %s\n", buff_rec);

	


	//Distingue la requête HTTP...
	if(strstr(buff_rec, "GET")!=NULL && strstr(buff_rec, "HTTP")!=NULL)
	{
		vider_interfaces(argument);	
		httpReponse(sockdial_stream, argument);
	}
	else //.. d'une requête interface
	{
		struct sockaddr_storage tmp_addr;
		socklen_t addr_len=sizeof(tmp_addr);
		if(getpeername(sock, (struct sockaddr*)&tmp_addr, &addr_len)==0)
		{
			char adresse[20];
			sprintf(adresse, "%s", inet_ntoa(((struct sockaddr_in*)&tmp_addr)->sin_addr));		
			interfaceReponse(sockdial_stream, buff_rec, argument, adresse); 
		}
	}


	printf("Sock : %d // Stream : %p \n", sock, sockdial_stream);

	printf("Fin de la connexion\n");

	fclose(sockdial_stream);

	pthread_exit(NULL);
}



int lanceThread(void(* fonction) (void *), void* arg, int size)
{
	pthread_t thr_id;
	printf("%d \n",size);	
	if(pthread_create(&thr_id, NULL, (void*)fonction, arg )!=0) { fprintf(stderr, "Le thread n'a pas pu être créé.\n"); return -1; }
	
	pthread_detach(thr_id);

	return 0;
}