listener.c 6.18 KB
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stropts.h>

#include <pthread.h>
#include <signal.h>

#define MAX_SENSORS 10

int sig_received = 0;

struct sigaction action;
struct termios tty, old;

typedef struct{
	char sensor[30];
	char port[30];

} SensorAndPort;

void sig_handler(int sig)
{
	if (sig == SIGTERM){
		printf("\nSignal SIGINT received\n");
		sig_received = 1;
	}
}

void create_error_file(char *str, char *msg){
 	FILE * file;
	char base[30] ="res/result_exp_";
	strcat(base,str);
	strcat(base,".txt");
	file = fopen(base,"w");
	if(file==NULL){
		perror("create_error_file(...) - fopen");
		exit(-1);
	}
	fprintf(file, "%s",msg);
	fclose(file);
}

void save_data(int pt, char* sensor){
	FILE * file;
	char base[26] ="res/result_exp_";
	strcat(base, sensor);
	strcat(base, ".txt");
	file = fopen(base,"w");
	//printf("base = %s\n",base);
	if(file==NULL){
		perror("fopen");
		exit(-1);
	}

	int count = 0;
	char line[2];
	memset(line,0,sizeof(line));
	while(1){
		int r = read(pt ,line,1);
		if(r>=0){
			//printf("sensor : %s - c = %c (characters read : %d)\n\n", sensor, line[0], r);
			r = fprintf(file, "%c",line[0]);
		}
		fflush(file);
		memset(line,0,sizeof(line));
		count++;
		if(sig_received == 1){
			break;
		}
	}
	fclose(file);
	//printf("end save_data\n");
}

void reset_serial(int pt){
	tcsetattr(pt, TCSANOW, &old);
	close(pt);
	//printf("end reset_serial\n");
}

int set_serial(SensorAndPort* sensorAndPort){
	char *device = sensorAndPort->port;
	//printf("device : %s\n",device);
	int pt = open(device, O_RDWR | O_NOCTTY | O_SYNC); // retourne une erreur si le terminal n'est connecté à rien (pas de STM32 ni de Arduino dans notre cas)
	if(pt == -1){
		create_error_file(sensorAndPort->sensor, "impossible de se connecter au port série, veuillez vérifier le microprocesseur et la raspberry");
		perror("in set_serial(...) - open");
		pthread_exit(NULL);
	}
	//ioctl(pt, I_SRDOPT, RMSGD);
	tcgetattr(pt, &old);
	tcgetattr(pt, &tty);
	////////////////////////////////////////////////////////////////////////////////////////
	// Sur les Raspberry le code du read() est bien bloquant comme prévu mais par sur linux Ubuntun. 
	// Donc sur les Raspberry, il est nécessaire de mettre un VTIME et de mettre VMIN = 0 
	// car le timer commence lorsque le premier caractère est détécté :
	// Si aucun caractère n'arrive le timer ne commence jamais et le read bloque à l'infini
	////////////////////////////////////////////////////////////////////////////////////////
	cfsetispeed(&tty,B9600); 
	cfsetospeed(&tty,B9600);

	tty.c_cc[VMIN] = 1; 
	tty.c_cc[VTIME] = 10;

	tty.c_cflag |= CLOCAL;
	tty.c_cflag |= CREAD;
	cfmakeraw(&tty);

	sleep(1); // nécessaire pour que le flush soit fait
	if(tcflush(pt, TCIFLUSH)==-1){
		perror("in set_serial(...) - tcflush");
		pthread_exit(NULL);
	}
	if(tcsetattr(pt, TCSANOW, &tty)==-1){
		perror("in set_serial(...) - tcsetattr");
		pthread_exit(NULL);
	}
	if(cfgetispeed(&tty)!=B9600)
	{
		perror("in set_serial(...) - cfgetispeed");
		pthread_exit(NULL);
	}
	return pt;
}

void * start(void * sensorAndPort){
	int pt = set_serial((SensorAndPort *) sensorAndPort);
	save_data(pt, ((SensorAndPort *)sensorAndPort)->sensor);
	reset_serial(pt);
	pthread_exit(NULL);
}

int read_file_by_line(char list_lines[MAX_SENSORS][30], char * file_name){
	int count_line=0, i=0;
	char str[30];
	FILE * conf = fopen(file_name,"r");
	while(fgets(str, 30, conf) != NULL){
		str[strcspn(str,"\r\n")] = 0; // strcspn parcours la chaine str jusqu'à trouvé l'un des charactères indiqués et renvoie l'indice du charactère.
		//printf("line : %s\n",str);
		strcpy(list_lines[i],str);
		i++;
		count_line++;
	}
	return count_line;
}

void get_ports_to_read(char list_sensors[MAX_SENSORS][30], char list_serial_port[MAX_SENSORS][30], int count_sensors, int count_serial_port, char sensors_ports[MAX_SENSORS][30]){
	int i=0, j=0, is_equal=-1;
	char * port,* sensor;
	char *s="=";
	for(i=0; i<count_sensors; i++){
		while(is_equal!=0 && j<count_serial_port){ //on parcours la liste des ports series : tant que le nom du capteur de list_sensors[][] n'est pas trouvé on continue
		 	sensor = strtok(list_serial_port[j], s);
		 	//printf("sensor = %s\n",sensor);
		 	is_equal=strcmp(list_sensors[i],sensor);
		 	j++;
		}
		if(j==count_serial_port){
		 	//printf("Il n'y a pas de capteurs avec ce nom : %s\n",list_sensors[i]);
		 	create_error_file(list_sensors[i],"Il n'y a pas de capteurs avec ce nom");
		}
		j=0;
		is_equal=-1;
		port = strtok(NULL,s);
		//printf("port = %s\n",port);
		strcpy(sensors_ports[i], port);
	}
}


int main(int argc, char *argv[]){
	char * config_experimentation = "config_experimentation.txt";
	char * config_raspberry = "config_raspberry.txt";
	if(argc>1){
		//printf("fichier contenant la liste des capteurs de l'experimentation : %s\n",argv[1]);
		char * config_experimentation = argv[1];
	}
	if(argc>2){
		//printf("fichier contenant la correspondance de tous les capteurs avec leur liaison série : %s\n",argv[2]);
		char * config_raspberry = argv[2];
	}
	SensorAndPort sensorAndPort[MAX_SENSORS];

	char device[MAX_SENSORS][12];
	pthread_t threads[MAX_SENSORS];

	char list_sensors[MAX_SENSORS][30], list_serial_port[MAX_SENSORS][30], sensors_ports[MAX_SENSORS][30];
	int i=0, count_sensors=0, count_serial_port=0;
	count_sensors = read_file_by_line(list_sensors, config_experimentation);
	printf("numbers of sensors = %d\n",count_sensors);
	count_serial_port = read_file_by_line(list_serial_port, config_raspberry);
	get_ports_to_read(list_sensors,list_serial_port,count_sensors, count_serial_port, sensors_ports);

	//action.sa_handler=sig_handler;
	//sigaction(SIGTERM, &action, NULL);

	for(i=0;i<count_sensors;i++){
		strcpy(sensorAndPort[i].sensor,list_sensors[i]);
		strcpy(sensorAndPort[i].port,sensors_ports[i]);
		pthread_create(&(threads[i]), NULL, start, (void *)(&(sensorAndPort[i])));
	}
	for(i=0;i<count_sensors;i++){
		pthread_join(threads[i],NULL);
	}
	return 0;
}

//169.254.24.80

//169.254.25.26