#include "lowreceiver.h" #include "messagecell_ab.h" LowReceiver::LowReceiver(short port_low, short port_high, Group &grp, Clock &clk) : _port_low(port_low), _port_high(port_high), _group(grp), _clock(clk) { printf("LowReceiver::LowReceiver --\n"); _socket_desc = socket(AF_INET, SOCK_DGRAM, 0); /* et l'autre variante : AF_UNIX */ if (_socket_desc < 0){ /* error */ perror("Creation de la socket impossible\n"); fprintf(stderr,"BOUM at %s:%d\n",__FILE__,__LINE__); // FIXME: throw something exit(-1); } _socket_addr = new sockaddr_in; // port_low = externe // port_high = interne bzero(_socket_addr,sizeof(sockaddr_in)); _socket_addr->sin_family = AF_INET; _socket_addr->sin_port = htons(_port_low); _socket_addr->sin_addr.s_addr = htonl(INADDR_ANY); // chopper une socket if (bind(_socket_desc, (struct sockaddr *)_socket_addr, sizeof(sockaddr_in)) < 0) { //FIXME : throw something perror("Attachement de la socket impossible\n"); fprintf(stderr,"BOUM at %s:%d\n",__FILE__,__LINE__); exit(-1); } } LowReceiver::~LowReceiver() { delete _socket_addr; } void LowReceiver::run(){ int buffer_len = 1500; char * buffer = new char[buffer_len]; struct sockaddr_in repaddr; socklen_t sockaddr_len = sizeof(struct sockaddr_in); Message * mesg = NULL; while(1){ // recevoir les données memset(buffer, '\0', buffer_len); bzero(&repaddr,sizeof(struct sockaddr_in)); int read_buffer_len = recvfrom( _socket_desc, buffer, buffer_len, 0, (struct sockaddr*)&repaddr, &sockaddr_len); mesg = new Message(buffer, read_buffer_len); printf("LowReceiver::run -- READ\n"); char * str = new char[mesg->getDataSize() + 1]; strncpy(str, mesg->getData(), mesg->getDataSize()); str[mesg->getDataSize()] = '\0'; printf("LowReceiver::run -- READ '%s'\n", str); this->manage(mesg); delete(mesg); mesg = NULL; // on dispatche les données en fonction du protocole... } } void LowReceiver::manage(Message * mesg){ switch(mesg->getType()){ case Protocol::TYPE_TEST : { printf("LowReceiver::manage -- NOT IMPLEMENTED\n"); } break; case Protocol::TYPE_ABCAST : { this->manage_abcast(mesg); } break; case Protocol::TYPE_CBCAST : { this->manage_cbcast(mesg); } break; default: printf("LowReceiver::manage -- ERROR\n"); break; } } void LowReceiver::manage_abcast(Message * mesg) { static std::list fifo; std::list::iterator iter; printf("LowReceiver::manage_abcast -- init\n"); // FIXME: on suppose ne pas etre l'emetteur // identifiant = horloge + id_site_emeteur bool firstSeenMessage = true; for (iter = fifo.begin(); iter != fifo.end(); iter++){ MessageCellAb * cur = *iter; if (cur->message == mesg) { printf("LowReceiver::manage_abcast -- message seen\n"); firstSeenMessage = false; break; } } if (firstSeenMessage){ // si le message est vu pour la premiere fois: // - on l'ajoute dans la liste d'attente MessageCellAb * cell = new MessageCellAb(); cell->message = new Message(*mesg); //FIXME: make a copy; cell->type = MessageCellAb::TYPE_TEMPORARY; // - on retourne une estampille(reception) a l'emeteur } else { // sinon // - l'estampille du message est mise a jour // - le message est marqué comme final // - on défile les estampille finale la } } void LowReceiver::manage_cbcast(Message * mesg) { printf("LowReceiver::manage_cbcast -- init\n"); }