|
|
@@ -1,555 +0,0 @@ |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <string.h> |
|
|
|
#include <time.h> |
|
|
|
#include <unistd.h> |
|
|
|
#include <pthread.h> |
|
|
|
#include <signal.h> |
|
|
|
#include <errno.h> |
|
|
|
#include <sys/types.h> |
|
|
|
#include <sys/socket.h> |
|
|
|
#include <netinet/in.h> |
|
|
|
#include <arpa/inet.h> |
|
|
|
#include <inttypes.h> |
|
|
|
|
|
|
|
#define UDP_LISTEN_PORT 4242 |
|
|
|
#define UDP_DEFAULT_CONNECT_ADDR "127.0.0.1" |
|
|
|
#define UDP_DEFAULT_CONNECT_PORT 4242 |
|
|
|
|
|
|
|
#define MY_ADDR 0xabcd0123 |
|
|
|
#define TRAME_MAX_LENGTH 65503 /* la taille totale de la trame est sur 16 bits, on ne peut pas dépasser 65507 octets à cause d'udp */ |
|
|
|
|
|
|
|
#define DEFAULT_TIME_BEFORE_DISCOVERY 1 |
|
|
|
#define NB_TURN_BEFORE_DISCOVERY 5 |
|
|
|
|
|
|
|
/* |
|
|
|
trame |
|
|
|
|00|01|02|03|04|05|06|07||08|09|10|11|12|13|14|15||16|17|18|19|20|21|22|23||24|25|26|27|28|29|30|31| |
|
|
|
| 0 || 1 || 2 || 3 | |
|
|
|
| type || taille totale || données… |
|
|
|
|
|
|
|
paquet |
|
|
|
|00|01|02|03|04|05|06|07||08|09|10|11|12|13|14|15||16|17|18|19|20|21|22|23||24|25|26|27|28|29|30|31| |
|
|
|
| 0 || 1 || 2 || 3 | |
|
|
|
| adresse destination | |
|
|
|
| adresse source | |
|
|
|
| taille du paquet entete comprise || taille du message | |
|
|
|
| numéro du paquet || type || somme de controle sur les données | |
|
|
|
| données_ | |
|
|
|
|
|
|
|
*/ |
|
|
|
enum boolean {false, true}; |
|
|
|
|
|
|
|
struct watch_stat_t { |
|
|
|
enum boolean received_trame; |
|
|
|
unsigned int time_before_discovery; |
|
|
|
}; |
|
|
|
|
|
|
|
enum trame_type_t { |
|
|
|
TRAME_TOKEN, |
|
|
|
TRAME_DISCOVERY |
|
|
|
}; |
|
|
|
|
|
|
|
struct trame_t { |
|
|
|
enum trame_type_t type; |
|
|
|
u_int16_t length; |
|
|
|
void *data; |
|
|
|
}; |
|
|
|
|
|
|
|
enum packet_type_t { |
|
|
|
PACKET_DATA, |
|
|
|
PACKET_DISCOVERY, /* paquet d'une trame discovery */ |
|
|
|
PACKET_JOIN, /* paquet qui demande le branchement d'un cable */ |
|
|
|
PACKET_LEAVE /* paquet qui demande le débranchement d'un cable */ |
|
|
|
}; |
|
|
|
|
|
|
|
struct packet_t { |
|
|
|
u_int32_t addr_dest; |
|
|
|
u_int32_t addr_src; |
|
|
|
u_int16_t packet_length; |
|
|
|
u_int16_t message_length; |
|
|
|
u_int8_t fragment; |
|
|
|
enum packet_type_t type; |
|
|
|
u_int16_t checksum; |
|
|
|
void *data; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/* variables globales */ |
|
|
|
pthread_mutex_t mutex_in, mutex_out, mutex_stat; |
|
|
|
enum boolean quit; |
|
|
|
int fd_sock; |
|
|
|
struct sockaddr_in sock_listen, sock_in, sock_out; |
|
|
|
|
|
|
|
struct watch_stat_t watch_stat; |
|
|
|
char buffer_in[TRAME_MAX_LENGTH], buffer_out[TRAME_MAX_LENGTH]; |
|
|
|
|
|
|
|
/* prototype */ |
|
|
|
void quit_signal_handler(int sig); |
|
|
|
void* watchdog_discovery(void *argv); |
|
|
|
int send_trame(const struct trame_t *const trame_p); |
|
|
|
int recv_trame(struct trame_t *const trame_p, enum boolean extract_data); |
|
|
|
int add_packet(struct trame_t *const trame_p, const struct packet_t *const packet_p); |
|
|
|
int retr_packet(struct trame_t *trame_p, struct packet_t **packet_pp, enum boolean extract_data); |
|
|
|
u_int16_t checksum(const struct packet_t *const packet); |
|
|
|
|
|
|
|
/* couches : |
|
|
|
1 : niveau physique : gestion de l'anneau par sockets udp |
|
|
|
2 : circulation de la trame |
|
|
|
3 : encapsulation de paquets dans la trame |
|
|
|
*/ |
|
|
|
|
|
|
|
void quit_signal_handler(int sig) { |
|
|
|
sig = 0; /* pour compiler sans warning en pedantic */ |
|
|
|
quit = true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void* watchdog_discovery(void *argv) { |
|
|
|
unsigned int time_to_sleep; |
|
|
|
enum boolean send_discovery; |
|
|
|
struct trame_t trame_discovery; |
|
|
|
struct packet_t packet_discovery; |
|
|
|
argv=NULL; /* pour compiler sans warning en pedantic */ |
|
|
|
|
|
|
|
/* on prépare la trame */ |
|
|
|
trame_discovery.type = TRAME_DISCOVERY; |
|
|
|
trame_discovery.length = 3; |
|
|
|
trame_discovery.data = NULL; |
|
|
|
|
|
|
|
/* on prépare le paquet qu'on met dans la trame */ |
|
|
|
packet_discovery.addr_dest = MY_ADDR; |
|
|
|
packet_discovery.addr_src = MY_ADDR; |
|
|
|
packet_discovery.packet_length = 16; |
|
|
|
packet_discovery.message_length = 0; |
|
|
|
packet_discovery.fragment = 0; |
|
|
|
packet_discovery.type = PACKET_DISCOVERY; |
|
|
|
packet_discovery.checksum = checksum(&packet_discovery); |
|
|
|
packet_discovery.data = NULL; |
|
|
|
|
|
|
|
/* on insère le paquet dans la trame */ |
|
|
|
if(add_packet(&trame_discovery, &packet_discovery) == -1) { |
|
|
|
#ifdef debug |
|
|
|
fputs("impossible d'ajouter le paquet de discovery dans la trame\n", stderr); |
|
|
|
#endif |
|
|
|
quit = 1; |
|
|
|
pthread_exit(NULL); /* il faudrait peut etre retourner une erreur */ |
|
|
|
} |
|
|
|
|
|
|
|
do { |
|
|
|
pthread_mutex_lock(&mutex_stat); |
|
|
|
time_to_sleep = watch_stat.time_before_discovery; |
|
|
|
watch_stat.received_trame = false; |
|
|
|
pthread_mutex_unlock(&mutex_stat); |
|
|
|
sleep(time_to_sleep); |
|
|
|
pthread_mutex_lock(&mutex_stat); |
|
|
|
send_discovery = !watch_stat.received_trame; |
|
|
|
pthread_mutex_unlock(&mutex_stat); |
|
|
|
if(send_discovery) { |
|
|
|
#ifdef debug |
|
|
|
fputs("envoie d'une trame de discovery\n", stderr); |
|
|
|
#endif |
|
|
|
send_trame(&trame_discovery); |
|
|
|
} |
|
|
|
} while(!quit); |
|
|
|
pthread_exit(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int send_trame(const struct trame_t *const trame_p) { |
|
|
|
int res; |
|
|
|
u_int16_t length; |
|
|
|
pthread_mutex_lock(&mutex_out); |
|
|
|
/* on remplit le buffer */ |
|
|
|
length = htons(trame_p->length); |
|
|
|
memcpy(buffer_out, &(trame_p->type), 1); |
|
|
|
memcpy(buffer_out+1, &(length), 2); |
|
|
|
memcpy(buffer_out+3, trame_p->data, (size_t) ((trame_p->length)-3)); /* on enlève les 3 octets d'entete */ |
|
|
|
/* on envoie la trame */ |
|
|
|
if(( res = sendto(fd_sock, buffer_out, trame_p->length, 0, (struct sockaddr*)&sock_out, sizeof(struct sockaddr_in))) == -1) { |
|
|
|
#ifdef debug |
|
|
|
perror("sendto()"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
pthread_mutex_unlock(&mutex_out); |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int recv_trame(struct trame_t *const trame_p, enum boolean extract_data) { |
|
|
|
static time_t previous_time = 0; |
|
|
|
socklen_t sock_length; |
|
|
|
ssize_t recvfrom_length; |
|
|
|
pthread_mutex_lock(&mutex_in); |
|
|
|
/* on reçoit la trame */ |
|
|
|
if((recvfrom_length = recvfrom(fd_sock, buffer_in, sizeof(buffer_in)-1, 0, (struct sockaddr*)&sock_in, &sock_length)) == -1) { |
|
|
|
#ifdef debug |
|
|
|
perror("recvfrom()"); |
|
|
|
#endif |
|
|
|
pthread_mutex_unlock(&mutex_in); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
/* on retient qu'on a reçu une trame et on adapte le temps d'attente du watchdog */ |
|
|
|
pthread_mutex_lock(&mutex_stat); |
|
|
|
watch_stat.received_trame = true; |
|
|
|
/* adaptation du temps d'attente */ |
|
|
|
if(previous_time) |
|
|
|
watch_stat.time_before_discovery = NB_TURN_BEFORE_DISCOVERY*( (watch_stat.time_before_discovery+(time(NULL)-previous_time))/2 ); |
|
|
|
previous_time = time(NULL); |
|
|
|
pthread_mutex_unlock(&mutex_stat); |
|
|
|
|
|
|
|
/* on initialise la trame */ |
|
|
|
memset(trame_p, 0, sizeof(struct trame_t)); |
|
|
|
/* on lit les champs de l'entete */ |
|
|
|
memcpy(&(trame_p->type), buffer_in, 1); |
|
|
|
memcpy(&(trame_p->length), buffer_in+1, 2); |
|
|
|
trame_p->length = ntohs(trame_p->length); |
|
|
|
/* on vérifie la taille */ |
|
|
|
if(recvfrom_length != trame_p->length ) { |
|
|
|
#ifdef debug |
|
|
|
fputs("taille de trame invalide\n", stderr); |
|
|
|
#endif |
|
|
|
pthread_mutex_unlock(&mutex_in); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
/* s'il y a des donées, on les récupère */ |
|
|
|
if(extract_data && trame_p->length > 3) { /* taille de l'entete de la trame*/ |
|
|
|
if((trame_p->data = realloc(trame_p->data,(trame_p->length)-3)) == NULL) { |
|
|
|
#ifdef debug |
|
|
|
fputs("bad alloc\n", stderr); |
|
|
|
#endif |
|
|
|
pthread_mutex_unlock(&mutex_in); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
memcpy(trame_p->data, buffer_in+3, (size_t) ((trame_p->length)-3)); |
|
|
|
} else |
|
|
|
trame_p->data = NULL; |
|
|
|
pthread_mutex_unlock(&mutex_in); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
int add_packet(struct trame_t *const trame_p, const struct packet_t *const packet_p) { |
|
|
|
char *new_data; |
|
|
|
u_int16_t size; |
|
|
|
|
|
|
|
u_int32_t addr_dest; |
|
|
|
u_int32_t addr_src; |
|
|
|
u_int16_t packet_length; |
|
|
|
u_int16_t message_length; |
|
|
|
u_int16_t checksum; |
|
|
|
|
|
|
|
size = (trame_p->length-3) + packet_p->packet_length; |
|
|
|
if(size > TRAME_MAX_LENGTH-3) { |
|
|
|
#ifdef debug |
|
|
|
fputs("trame too long\n", stderr); |
|
|
|
#endif |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if( (new_data = realloc(trame_p->data, size)) == NULL) { |
|
|
|
#ifdef debug |
|
|
|
fputs("bad alloc\n", stderr); |
|
|
|
#endif |
|
|
|
return -1; |
|
|
|
} |
|
|
|
trame_p->data = new_data; |
|
|
|
new_data = ((char*)trame_p->data)+trame_p->length-3; |
|
|
|
trame_p->length += packet_p->packet_length; |
|
|
|
|
|
|
|
addr_dest = htonl(packet_p->addr_dest); |
|
|
|
addr_src = htonl(packet_p->addr_src); |
|
|
|
packet_length = htons(packet_p->packet_length); |
|
|
|
message_length = htons(packet_p->message_length); |
|
|
|
checksum = htons(packet_p->checksum); |
|
|
|
|
|
|
|
memcpy(new_data, &(addr_dest), 4); |
|
|
|
new_data += 4; |
|
|
|
memcpy(new_data, &(addr_src), 4); |
|
|
|
new_data += 4; |
|
|
|
memcpy(new_data, &(packet_length), 2); |
|
|
|
new_data += 2; |
|
|
|
memcpy(new_data, &(message_length), 2); |
|
|
|
new_data += 2; |
|
|
|
memcpy(new_data, &(packet_p->fragment), 1); |
|
|
|
new_data += 1; |
|
|
|
memcpy(new_data, &(packet_p->type), 1); |
|
|
|
new_data += 1; |
|
|
|
memcpy(new_data, &(checksum), 2); |
|
|
|
new_data += 2; |
|
|
|
|
|
|
|
memcpy((char*)new_data, packet_p->data, packet_p->packet_length-16); |
|
|
|
|
|
|
|
return 1; |
|
|
|
} |
|
|
|
int retr_packet(struct trame_t *trame_p, struct packet_t **packet_pp, enum boolean extract_data) { |
|
|
|
int nb_packet, i; |
|
|
|
char *ptr, *ptr_move, *limit; |
|
|
|
struct trame_t tmp_trame; |
|
|
|
struct packet_t tmp_packet, *new_packet_p; |
|
|
|
|
|
|
|
nb_packet = 0; |
|
|
|
*packet_pp = NULL; |
|
|
|
if(!trame_p->data || trame_p->length <= 3) |
|
|
|
return 0; |
|
|
|
|
|
|
|
/* on copie la trame, en cas d'erreur, on ne se retrouvera pas dans un état incohérent */ |
|
|
|
tmp_trame = *trame_p; |
|
|
|
if( (tmp_trame.data = malloc(tmp_trame.length-3)) == NULL) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
memcpy(tmp_trame.data, trame_p->data, tmp_trame.length-3); |
|
|
|
|
|
|
|
/* on regarde l'adresse de dest de chaque paquet, si le paquet n'est pas pour moi, on décale dans la trame, sinon on recopie dans un struct packet_t */ |
|
|
|
|
|
|
|
limit = (void*) (((char*) tmp_trame.data) + tmp_trame.length - 3); |
|
|
|
ptr_move = ptr = tmp_trame.data; |
|
|
|
while(ptr < limit) { |
|
|
|
/* on extrait l'entete destination */ |
|
|
|
memset(&tmp_packet, 0, sizeof(struct packet_t)); |
|
|
|
|
|
|
|
memcpy(&(tmp_packet.addr_dest), ptr, 4); |
|
|
|
ptr += 4; |
|
|
|
tmp_packet.addr_dest = ntohl(tmp_packet.addr_dest); |
|
|
|
|
|
|
|
memcpy(&(tmp_packet.addr_src), ptr, 4); |
|
|
|
ptr += 4; |
|
|
|
tmp_packet.addr_src = ntohl(tmp_packet.addr_src); |
|
|
|
|
|
|
|
memcpy(&(tmp_packet.packet_length), ptr, 2); |
|
|
|
ptr += 2; |
|
|
|
tmp_packet.packet_length = ntohs(tmp_packet.packet_length); |
|
|
|
|
|
|
|
memcpy(&(tmp_packet.message_length), ptr, 2); |
|
|
|
ptr += 2; |
|
|
|
tmp_packet.message_length = ntohs(tmp_packet.message_length); |
|
|
|
|
|
|
|
memcpy(&(tmp_packet.fragment), ptr++, 1); |
|
|
|
memcpy(&(tmp_packet.type), ptr++, 1); |
|
|
|
|
|
|
|
memcpy(&(tmp_packet.checksum), ptr, 2); |
|
|
|
ptr += 2; |
|
|
|
tmp_packet.checksum = ntohs(tmp_packet.checksum); |
|
|
|
|
|
|
|
|
|
|
|
if(tmp_packet.addr_dest == MY_ADDR) { |
|
|
|
/* on retire le paquet de la trame */ |
|
|
|
if((new_packet_p = realloc(*packet_pp, ((size_t) (nb_packet+1))*sizeof(struct packet_t))) == NULL) { |
|
|
|
#ifdef debug |
|
|
|
fputs("bad alloc\n", stderr); |
|
|
|
#endif |
|
|
|
/* on désalloue tout */ |
|
|
|
for(i = 0 ; i<nb_packet ; i++) { |
|
|
|
if(packet_pp[i]->data) |
|
|
|
free(packet_pp[i]->data); |
|
|
|
} |
|
|
|
free(*packet_pp); |
|
|
|
*packet_pp = NULL; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
*packet_pp = new_packet_p; |
|
|
|
/* on recopie le paquet temporaire dans le tableau et on réaffecte la taille de la trame */ |
|
|
|
*(packet_pp[nb_packet]) = tmp_packet; |
|
|
|
if(extract_data && tmp_packet.packet_length > 16) |
|
|
|
memcpy(&(packet_pp[nb_packet]->data), ptr, tmp_packet.packet_length-16); |
|
|
|
nb_packet++; |
|
|
|
tmp_trame.length -= tmp_packet.packet_length; |
|
|
|
} else { |
|
|
|
/* on décale le paquet */ |
|
|
|
if(ptr-16 != ptr_move) { |
|
|
|
memmove(ptr_move, ptr-16, tmp_packet.packet_length); |
|
|
|
ptr = ptr_move+16; |
|
|
|
} |
|
|
|
ptr_move += tmp_packet.packet_length; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* on se place sur le paquet suivant */ |
|
|
|
ptr += (tmp_packet.packet_length-16); |
|
|
|
} |
|
|
|
|
|
|
|
free(trame_p->data); |
|
|
|
*trame_p = tmp_trame; |
|
|
|
|
|
|
|
return nb_packet; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
u_int16_t checksum(const struct packet_t *const packet) { |
|
|
|
u_int16_t res, res1; |
|
|
|
res = 0; |
|
|
|
res += (u_int16_t) (htonl(packet->addr_dest) >> 16); |
|
|
|
res += (u_int16_t) htonl(packet->addr_dest); |
|
|
|
res += (u_int16_t) (htonl(packet->addr_src) >> 16); |
|
|
|
res += (u_int16_t) htonl(packet->addr_src); |
|
|
|
res += htons(packet->packet_length); |
|
|
|
res += htons(packet->message_length); |
|
|
|
res1 = (packet->fragment << 8); |
|
|
|
res1 += packet->type; |
|
|
|
res += res1; |
|
|
|
return (res^0xffff); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv) { |
|
|
|
pthread_t watchdog_discovery_thread; |
|
|
|
socklen_t sock_length; |
|
|
|
int trame_max_length, nb_packet; |
|
|
|
struct trame_t trame; |
|
|
|
struct packet_t *packet_p; |
|
|
|
|
|
|
|
|
|
|
|
trame_max_length = TRAME_MAX_LENGTH; |
|
|
|
sock_length = sizeof(struct sockaddr_in); |
|
|
|
|
|
|
|
/* on initialise le mutex */ |
|
|
|
if(pthread_mutex_init(&mutex_in, NULL) || pthread_mutex_init(&mutex_out, NULL) || pthread_mutex_init(&mutex_stat, NULL)) { |
|
|
|
#ifdef debug |
|
|
|
fputs("erreur lors de l'initialisation des mutex\n", stderr); |
|
|
|
#endif |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
/* on paramètre à qui on va envoyer nos trames */ |
|
|
|
sock_out.sin_family = AF_INET; |
|
|
|
switch(argc) { |
|
|
|
case 1: |
|
|
|
#ifdef debug |
|
|
|
fprintf(stderr, "les trames seront envoyées à %s sur le port %d\n", UDP_DEFAULT_CONNECT_ADDR, UDP_DEFAULT_CONNECT_PORT); |
|
|
|
#endif |
|
|
|
sock_out.sin_addr.s_addr = inet_addr(UDP_DEFAULT_CONNECT_ADDR); |
|
|
|
sock_out.sin_port = htons(UDP_DEFAULT_CONNECT_PORT); |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
#ifdef debug |
|
|
|
fprintf(stderr, "les trames seront envoyées à %s sur le port %d\n", argv[1], atoi(argv[2])); |
|
|
|
#endif |
|
|
|
sock_out.sin_addr.s_addr = inet_addr(argv[1]); |
|
|
|
sock_out.sin_port = htons(atoi(argv[2])); |
|
|
|
break; |
|
|
|
default: |
|
|
|
fprintf(stderr, "usage: %s [ip port]\n", argv[0]); |
|
|
|
exit(2); |
|
|
|
} |
|
|
|
|
|
|
|
/* on ouvre le socket */ |
|
|
|
if((fd_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { |
|
|
|
#ifdef debug |
|
|
|
perror("socket()"); |
|
|
|
#endif |
|
|
|
exit(errno); |
|
|
|
} |
|
|
|
|
|
|
|
/* on agrandit le buffer d'udp pour pouvoir envoyer et recevoir de grandes trames (sinon on est bloqué à 9216 octets) */ |
|
|
|
if(setsockopt(fd_sock, SOL_SOCKET, SO_SNDBUF, &trame_max_length, sock_length) == -1 || setsockopt(fd_sock, SOL_SOCKET, SO_RCVBUF, &trame_max_length, sock_length) == -1) { |
|
|
|
#ifdef debug |
|
|
|
perror("setsockopt()"); |
|
|
|
#endif |
|
|
|
close(fd_sock); |
|
|
|
exit(errno); |
|
|
|
} |
|
|
|
|
|
|
|
/* on se met en écoute */ |
|
|
|
memset(&sock_listen, 0, sizeof(struct sockaddr_in)); |
|
|
|
sock_listen.sin_addr.s_addr = htonl(INADDR_ANY); |
|
|
|
sock_listen.sin_family = AF_INET; |
|
|
|
sock_listen.sin_port = htons(UDP_LISTEN_PORT); |
|
|
|
if(bind(fd_sock, (struct sockaddr*) &sock_listen, sizeof(sock_listen)) == -1) { |
|
|
|
#ifdef debug |
|
|
|
perror("bind()"); |
|
|
|
#endif |
|
|
|
close(fd_sock); |
|
|
|
exit(errno); |
|
|
|
} |
|
|
|
|
|
|
|
/* on initialise la valeur de quit et on paramètre un signal pour quitter */ |
|
|
|
quit = false; |
|
|
|
signal(SIGINT, quit_signal_handler); |
|
|
|
|
|
|
|
/* on démarre le watchdog */ |
|
|
|
watch_stat.received_trame = false; |
|
|
|
watch_stat.time_before_discovery = DEFAULT_TIME_BEFORE_DISCOVERY; |
|
|
|
if(pthread_create(&watchdog_discovery_thread, NULL, watchdog_discovery, NULL)) { |
|
|
|
#ifdef debug |
|
|
|
fputs("erreur lors de la création du thread\n", stderr); |
|
|
|
#endif |
|
|
|
close(fd_sock); |
|
|
|
exit(3); |
|
|
|
} |
|
|
|
|
|
|
|
/* boucle de traitement */ |
|
|
|
do { |
|
|
|
wait_trame: |
|
|
|
/* on attend de recevoir une trame */ |
|
|
|
if(recv_trame(&trame, true) == -1) { |
|
|
|
#ifdef debug |
|
|
|
fputs("erreur lors de la réception de la trame\n", stderr); |
|
|
|
#endif |
|
|
|
goto wait_trame; |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef debug |
|
|
|
fprintf(stderr, "trame reçue : type:%d taille:%d\n", trame.type, trame.length); |
|
|
|
#endif |
|
|
|
|
|
|
|
if( (nb_packet = retr_packet(&trame, &packet_p, true)) == -1) { |
|
|
|
/* on a une erreur donc on renvoie la trame telle quelle */ |
|
|
|
#ifdef debug |
|
|
|
fputs("erreur lors de l'analyse des paquets de la trame\n", stderr); |
|
|
|
#endif |
|
|
|
goto send_trame; |
|
|
|
} |
|
|
|
|
|
|
|
switch(trame.type) { |
|
|
|
case TRAME_TOKEN: |
|
|
|
|
|
|
|
break; |
|
|
|
case TRAME_DISCOVERY: |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
/* on free les paquets reçus */ |
|
|
|
while(nb_packet > 0) { |
|
|
|
if(packet_p[--nb_packet].data) |
|
|
|
free(packet_p[nb_packet].data); |
|
|
|
} |
|
|
|
if(packet_p) |
|
|
|
free(packet_p); |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
printf("dest : %"PRIx32"\n", packet_p[0].addr_dest); |
|
|
|
printf("src : %"PRIx32"\n", packet_p[0].addr_src); |
|
|
|
printf("packet length : %"PRIu16"\n", packet_p[0].packet_length); |
|
|
|
printf("message length : %"PRIu16"\n", packet_p[0].message_length); |
|
|
|
printf("fragment : %"PRIu8"\n", packet_p[0].fragment); |
|
|
|
printf("type : %"PRIu8"\n", packet_p[0].type); |
|
|
|
printf("checksum : %"PRIx16"\n", packet_p[0].checksum); |
|
|
|
*/ |
|
|
|
send_trame: |
|
|
|
/* on renvoie la trame */ |
|
|
|
if(send_trame(&trame) == -1) { |
|
|
|
#ifdef debug |
|
|
|
fputs("erreur lors de l'émission de la trame\n", stderr); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
} while(!quit); |
|
|
|
|
|
|
|
if(trame.data) |
|
|
|
free(trame.data); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_join(watchdog_discovery_thread, NULL); |
|
|
|
pthread_mutex_destroy(&mutex_in); |
|
|
|
pthread_mutex_destroy(&mutex_out); |
|
|
|
pthread_mutex_destroy(&mutex_stat); |
|
|
|
close(fd_sock); |
|
|
|
|
|
|
|
#ifdef debug |
|
|
|
fputs("exited\n", stderr); |
|
|
|
#endif |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |