void up_to_application(NL_PACKET *p, int arrived_on_link) { //debug size_t length = p->pieceNumber * (linkinfo[arrived_on_link].mtu - PACKET_HEADER_SIZE) + p->length; //length = packet_length[p->src]; //packet_length[p->src] = 0; int p_checksum = p->checksum; int checksum = CNET_ccitt((unsigned char *) (p->msg), p->src_packet_length); if (p->is_resent) { printf( "%d received a resent packet, src = %d, des = %d, seqno = %d, send_length = %d, receive_length = %d \n", nodeinfo.address, p->src, p->dest, p->seqno, p->src_packet_length, length); } else { printf( "%d received a packet, src = %d, des = %d, seqno = %d, send_length = %d, receive_length = %d \n", nodeinfo.address, p->src, p->dest, p->seqno, p->src_packet_length, length); } printf("last_piece_trans_time = %d, hopcount = %d\n", p->trans_time, p->hopcount); printf("src_checksum = %d calc_checksum = %d, ", p_checksum, checksum); if (p_checksum != checksum) { send_ack(p, arrived_on_link, 1); } else { // received a correct packet CHECK(CNET_write_application(p->msg, &length)); send_ack(p, arrived_on_link, 0); } }
static EVENT_HANDLER(physical_ready) { FRAME f; size_t len; int link, checksum; len = sizeof(FRAME); CHECK(CNET_read_physical(&link, (char *)&f, &len)); checksum = f.checksum; f.checksum = 0; if(CNET_ccitt((unsigned char *)&f, len) != checksum) { return; // bad checksum, ignore frame } switch (f.kind) { case ACK : if(f.seq == ackexpected) { CNET_stop_timer(lasttimer); ackexpected = 1-ackexpected; CNET_enable_application(ALLNODES); } break; case DATA : if(f.seq == frameexpected) { len = f.len; CHECK(CNET_write_application((char *)&f.msg, &len)); frameexpected = 1-frameexpected; } transmit_frame(NULL, ACK, 0, f.seq); break; } }
void up_to_application(NL_PACKET *p, int arrived_on_link) { size_t length = p->pieceStartPosition + p->length; if (length != p->src_packet_length) return; uint32_t p_checksum = p->checksum; uint32_t checksum = CNET_crc32((unsigned char *) (p->msg), p->src_packet_length); if (p_checksum != checksum) { send_ack(p, arrived_on_link, 1); } else { // received a correct packet CHECK(CNET_write_application(p->msg, &length)); send_ack(p, arrived_on_link, 0); } }
static void up_to_transport(char *msg, int *len, CnetAddr source) { printf("Transport Layer is getting a packet\n"); TR_PACKET *p; p = (TR_PACKET*) msg; if( p->checksum == checksum_crc32( msg + sizeof(unsigned int), TR_PACKET_SIZE_PTR(p) - sizeof(unsigned int)) ) { /* good packet */ printf("Mmmm...Good packet\n"); CHECK(CNET_write_application(p->msg,&(p->length))); } else { /* bad packet */ printf("Bad, bad packet!\n"); } }
/* Function invoked each time a message is ready from physical layer */ static EVENT_HANDLER(physical_ready) { // Determine whether the node running the code is the server node. // If so read message and write to application. if (nodeinfo.address == 200) { // Server behaviour. int link; char buffer[MAX_MESSAGE_SIZE]; size_t length; length = sizeof(buffer); // Read physical layer CHECK(CNET_read_physical(&link, buffer, &length)); // Write to the application layer. CNET_write_application(buffer, &length); printf("Server reads message of length %d\n", length); } }
/* up_to_network() IS CALLED FROM THE DATA LINK LAYER (BELOW) TO ACCEPT A PACKET FOR THIS NODE, OR TO RE-ROUTE IT TO THE INTENDED DESTINATION. */ int up_to_network(char *packet, size_t length, int arrived_on_link) { NL_PACKET *p = (NL_PACKET *) packet; if(p->src == nodeinfo.address){ printf ("drop a packet at %d, src = %d, des = %d, seqno = %d\n", nodeinfo.address, p->src, p->dest, p->seqno); return 0; } //printf("up to network at %d (from %d to %d)\n", nodeinfo.address, p->src, p->dest); ++p->hopcount; /* took 1 hop to get here */ mtu = linkinfo[arrived_on_link].mtu; p->trans_time += ((CnetTime)8000 * 1000 * mtu / linkinfo[arrived_on_link].bandwidth + linkinfo[arrived_on_link].propagationdelay)*100/mtu; ////("me = %d, dest = %d =======\n", nodeinfo.address, p->dest); /* IS THIS PACKET IS FOR ME? */ if (p->dest == nodeinfo.address) { switch (p->kind) { case NL_DATA: if (p->seqno == NL_packetexpected(p->src)) { length = p->length; memcpy(rb[p->src], (char *) p->msg, length); rb[p->src] = rb[p->src] + length; //packet_length[p->src] += length; if (p->pieceEnd) { CnetAddr tmpaddr; length = p->pieceNumber * (linkinfo[arrived_on_link].mtu - PACKET_HEADER_SIZE) + p->length; //length = packet_length[p->src]; //packet_length[p->src] = 0; int p_checksum = p->checksum; int checksum = CNET_ccitt( (unsigned char *) (receiveBuffer[p->src]), p->src_packet_length); if(p->is_resent){ printf("%d received a resent packet, src = %d, des = %d, seqno = %d, send_length = %d,receive_length = %d \n", nodeinfo.address, p->src, p->dest, p->seqno, p->src_packet_length, length); }else{ printf("%d received a packet, src = %d, des = %d, seqno = %d, send_length = %d,receive_length = %d \n", nodeinfo.address, p->src, p->dest, p->seqno, p->src_packet_length, length); } printf("last_piece_trans_time = %d, hopcount = %d\n", p->trans_time, p->hopcount); printf("src_checksum = %d calc_checksum = %d, ", p_checksum, checksum); if (p_checksum != checksum) { /***************************send back error ack**************/ printf("error packet\n\n"); NL_savehopcount(p->src, p->trans_time, arrived_on_link); tmpaddr = p->src; /* swap src and dest addresses */ p->src = p->dest; p->dest = tmpaddr; if(p->is_resent == 1) p->kind = NL_ERR_ACK_RESENT; else p->kind = NL_ERR_ACK; p->hopcount = 0; p->pieceNumber = 0; p->pieceEnd = 0; p->length = 0; p->src_packet_length = 0; p->checksum = 0; p->trans_time = 0; flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0); rb[p->src] = &receiveBuffer[p->src][0]; //printf("\n"); return 0; /***************************end******************************/ } /* if (CNET_write_application(receiveBuffer[p->src], &length) == -1) { //source node should send this msg again //printf("===\ncnet_errno = %d\n===\n", cnet_errno); //printf("error count: %d\n", ++ err_count); if (cnet_errno == ER_CORRUPTFRAME) { printf("corrupt packet\n"); //printf("\nWarning: frame corrupted\n==\n"); } else if (cnet_errno == ER_MISSINGMSG) { printf("unordered packet\n"); //printf("\nWarning: frame missed\n\n"); } else if(cnet_errno == ER_BADSIZE){ printf("loss packet\n"); } } */ CHECK(CNET_write_application(receiveBuffer[p->src], &length)); printf("correct packet\n", p->dest, p->seqno, p->src); rb[p->src] = &receiveBuffer[p->src][0]; inc_NL_packetexpected(p->src); NL_savehopcount(p->src, p->trans_time, arrived_on_link); tmpaddr = p->src; /* swap src and dest addresses */ p->src = p->dest; p->dest = tmpaddr; p->kind = NL_ACK; p->hopcount = 0; p->pieceNumber = 0; p->pieceEnd = 0; p->length = 0; p->src_packet_length = 0; p->checksum = 0; p->trans_time = 0; p->is_resent = 0; flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0); printf("\n"); } } break; case NL_ACK: if (p->seqno == NL_ackexpected(p->src)) { ////("ACK come!\n"); inc_NL_ackexpected(p->src); NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_set_has_resent(p->src, 0); CHECK(CNET_enable_application(p->src)); } break; case NL_ERR_ACK: printf("NL_ERR_ACK!\n"); if (p->seqno == NL_ackexpected(p->src)){ if(NL_get_has_resent(p->src) == 0) { NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_PACKET * packettoresend = get_last_packet(p->src); printf("src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n", packettoresend->src, packettoresend->dest, packettoresend->seqno, packettoresend->length, packettoresend->checksum); printf("resend it\n"); int len = PACKET_HEADER_SIZE + packettoresend->length; packettoresend->is_resent = 1; NL_set_has_resent(p->src, 1); NL_inc_resent_times(p->src); // for debug flood3((char *) packettoresend, len, 0, 0); } else{ printf("this packet has already been resent, dont resent it again\n"); } } else{ printf("this packet has already been correct received, dont resent it again\n"); } printf("\n"); break; case NL_ERR_ACK_RESENT: printf("NL_ERR_ACK_RESENT!\n"); if (p->seqno == NL_ackexpected(p->src)) { NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_PACKET * packettoresend = get_last_packet(p->src); printf("resend a resent packet, src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n", packettoresend->src, packettoresend->dest, packettoresend->seqno, packettoresend->length, packettoresend->checksum); printf("this packet has been resent %d times before this time\n", NL_get_resent_times(p->src)); //for debug NL_inc_resent_times(p->src); // for debug int len = PACKET_HEADER_SIZE + packettoresend->length; packettoresend->is_resent = 1; flood3((char *) packettoresend, len, 0, 0); } else{ printf("this packet has already been correct received, dont resent it again\n"); } printf("\n"); break; default: //("it's nothing!====================\n"); break; } } /* THIS PACKET IS FOR SOMEONE ELSE */ else { // //("hopcount = %d\n", p->hopcount); // //("MAXHOPS = %d\n", MAXHOPS); if (p->hopcount < MAXHOPS) { /* if not too many hops... */ ////("other's frame!\n"); //("piece for another node arrives\n"); length = p->length; memcpy(rb[p->src], (char *) p->msg, length); rb[p->src] = rb[p->src] + length; //packet_length[p->src] += length; if (p->pieceEnd) { //printf("last piece for another node arrives\n"); length = p->pieceNumber * (linkinfo[arrived_on_link].mtu - PACKET_HEADER_SIZE) + p->length; //length = packet_length[p->src]; //packet_length[p->src] = 0; NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_PACKET wholePacket; wholePacket.src = p->src; wholePacket.dest = p->dest; wholePacket.kind = p->kind; wholePacket.seqno = p->seqno; wholePacket.hopcount = p->hopcount; wholePacket.pieceNumber = 0; wholePacket.pieceEnd = 0; wholePacket.length = length; wholePacket.src_packet_length = p->src_packet_length; wholePacket.checksum = p->checksum; wholePacket.trans_time = p->trans_time; wholePacket.is_resent = p->is_resent; memcpy(wholePacket.msg, receiveBuffer[p->src], length); // //("contents of msg forwarding is \n %s\n", receiveBuffer[p->src]); flood3((char *) &wholePacket, PACKET_SIZE(wholePacket), 0, arrived_on_link); rb[p->src] = &receiveBuffer[p->src][0]; } } else { /* silently drop */; //free(&p->msg); //free(p); } } return (0); }
/* up_to_network() IS CALLED FROM THE DATA LINK LAYER (BELOW) TO ACCEPT A PACKET FOR THIS NODE, OR TO RE-ROUTE IT TO THE INTENDED DESTINATION. */ int up_to_network(char *packet, size_t length, int arrived_on_link) { NL_PACKET *p = (NL_PACKET *) packet; if (p->src == nodeinfo.address) { printf( "drop a packet at %d, src = %d, des = %d, seqno = %d, length = %d\n\n", nodeinfo.address, p->src, p->dest, p->seqno, p->length); return 0; } ++p->hopcount; /* took 1 hop to get here */ mtu = linkinfo[arrived_on_link].mtu; p->trans_time += ((CnetTime) 8000 * 1000 * mtu / linkinfo[arrived_on_link].bandwidth + linkinfo[arrived_on_link].propagationdelay) * 100 / mtu; size_t maxsize = mtu - PACKET_HEADER_SIZE; if (p->length > maxsize || p->length < (size_t) 0) { //fprintf(stdout, "p->length = %d, max size = %d\n", (int)(p->length), (int) maxsize); return 0; } CnetAddr tempaddr; /* IS THIS PACKET IS FOR ME? */ if (p->dest == nodeinfo.address) { switch (p->kind) { case NL_TEST: if (NL_gettesthascome(p->src)) break; printf("test packet come!\n"); NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_updateminmtu(p->src, p->min_mtu, arrived_on_link); NL_inctesthascome(p->src); tempaddr = p->src; p->src = p->dest; p->dest = tempaddr; p->kind = NL_TEST_ACK; p->hopcount = 0; p->length = 0; flood_test(packet, PACKET_HEADER_SIZE, arrived_on_link, 0); break; case NL_TEST_ACK: printf("test packet ack come!\n"); NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_updateminmtu(p->src, p->min_mtu, arrived_on_link); break; case NL_DATA: if (p->seqno == NL_packetexpected(p->src)) { if (RB_save_msg_link(rb, p, arrived_on_link) == 2) { /* all pieces are arrived now get the whole msg from buffer and write it in applicaiton layer */ RB_copy_whole_msg_link(rb, p, arrived_on_link); CHECK(CNET_write_application((char*) p->msg, &p->src_packet_length)); send_ack(p, arrived_on_link, 0); return 0; } else if (p->pieceEnd || p->is_resent) { /* last piece arrives, now check the missing frame position */ // check which piece is missing and require to resend this piece //TODO: check which piece is missing //TODO: and require to resend this piece } } break; case NL_ACK: if (p->seqno == NL_ackexpected(p->src)) { printf("ACK come!\n"); inc_NL_ackexpected(p->src); NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_set_has_resent(p->src, 0); NL_update_lastackexpected(p->src); CHECK(CNET_enable_application(p->src)); } else if (p->seqno < NL_ackexpected(p->src)) { printf("outdated ACK come!\n"); } break; case NL_ERR_ACK: printf("NL_ERR_ACK!\n"); if (p->seqno == NL_ackexpected(p->src)) { if (NL_get_has_resent(p->src) == 0) { NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_PACKET * packettoresend = get_last_packet(p->src); printf( "src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n", packettoresend->src, packettoresend->dest, packettoresend->seqno, packettoresend->length, packettoresend->checksum); printf("resend it\n"); int len = PACKET_HEADER_SIZE + packettoresend->length; packettoresend->is_resent = 1; NL_set_has_resent(p->src, 1); flood((char *) packettoresend, len, 0, 0); } else { printf( "this packet has already been resent, dont resent it again\n"); } } else { printf( "this packet has already been correct received, dont resent it again\n"); } break; case NL_ERR_ACK_RESENT: printf("NL_ERR_ACK_RESENT!\n"); if (p->seqno == NL_ackexpected(p->src)) { NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_PACKET * packettoresend = get_last_packet(p->src); printf( "resend a resent packet, src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n", packettoresend->src, packettoresend->dest, packettoresend->seqno, packettoresend->length, packettoresend->checksum); int len = PACKET_HEADER_SIZE + packettoresend->length; packettoresend->is_resent = 1; flood((char *) packettoresend, len, 0, 0); } else { printf( "this packet has already been correct received, dont resent it again\n"); } break; default: printf("it's nothing!====================\n"); break; } } /* THIS PACKET IS FOR SOMEONE ELSE */ else { if (p->kind == NL_TEST) { CnetAddr tmp; NL_PACKET temp_p; if (p->hopcount < MAXHOPS) { NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_updateminmtu(p->src, p->min_mtu, arrived_on_link); temp_p.src = p->src; temp_p.dest = p->dest; temp_p.min_mtu = p->min_mtu; temp_p.hopcount = p->hopcount; /* retransmit on best links *except* the one on which it arrived */ if (NL_minmtu(temp_p.dest) != 0 && NL_minmtu(temp_p.dest) != -1) { if (temp_p.min_mtu > NL_minmtu(temp_p.dest)) { temp_p.min_mtu = NL_minmtu(temp_p.dest); } //temp_p.hopcount = NL_gethopcount(temp_p.src) + NL_gethopcount( // temp_p.dest); temp_p.hopcount = NL_gethopcount(temp_p.dest); tmp = temp_p.dest; temp_p.dest = temp_p.src; temp_p.src = tmp; temp_p.kind = NL_TEST_ACK; temp_p.length = 0; printf("send query result of %d to %d, min_mtu = %d\n", temp_p.src, temp_p.dest, temp_p.min_mtu); flood_test((char *) &temp_p, PACKET_HEADER_SIZE, arrived_on_link, 0); } } } else if (p->hopcount < MAXHOPS) { /* if not too many hops... */ NL_savehopcount(p->src, p->hopcount, arrived_on_link);//TODO: pay attention for this line, shall we need it? /* retransmit on best links *except* the one on which it arrived */ flood(packet, length, 0, arrived_on_link); } } return 0; }
static void transport_up( char* data, size_t dataLength ) { // WRITE THE MESSAGE BACK TO THE APPLICATION LAYER CHECK(CNET_write_application( data, &dataLength )); }
/* up_to_network() IS CALLED FROM THE DATA LINK LAYER (BELOW) TO ACCEPT A PACKET FOR THIS NODE, OR TO RE-ROUTE IT TO THE INTENDED DESTINATION. */ int up_to_network(char *packet, size_t length, int arrived_on_link) { printf("up to network at hop %s \n", nodeinfo.nodename); NL_PACKET *p = (NL_PACKET *) packet; //if(p->traveled_hops_count < 1 || p->traveled_hops_count > MAXHOPS) //return 0; //++p->hopcount; /* took 1 hop to get here */ if(p->traveled_hops_count > 0 && p->traveled_hops_count<= MAXHOPS){ is_traveled_hop = 0; for(i=0; i<p->traveled_hops_count; ++i){ if(p->traveled_hops[i] == nodeinfo.nodenumber){ is_traveled_hop = 1; break; } } if(is_traveled_hop != 1){ printf("seqno %d pieceNumber %d src %d des %d current_hop %d\n", p->seqno, p->pieceNumber, p->src, p->dest, nodeinfo.address); printf("p->traveled_hops_count %d\n", p->traveled_hops_count); p->traveled_hops[p->traveled_hops_count++] = nodeinfo.nodenumber; mtu = linkinfo[arrived_on_link].mtu; p->trans_time += ((CnetTime)8000000 * mtu / linkinfo[arrived_on_link].bandwidth + linkinfo[arrived_on_link].propagationdelay)/mtu; //p->trans_time += linkinfo[arrived_on_link].costperframe; } else{ printf("seqno %d pieceNumber %d src %d des %d current_hop %d. This hop has been traveled\n", p->seqno, p->pieceNumber, p->src, p->dest, nodeinfo.address); printf("\n"); /*free(&p->traveled_hops); free(&p->msg); free(p); */ return 0; } } /* IS THIS PACKET IS FOR ME? */ if (p->dest == nodeinfo.address) { switch (p->kind) { case NL_DATA: if (p->seqno == NL_packetexpected(p->src)) { length = p->length; memcpy(rb[p->src], (char *) p->msg, length); rb[p->src] = rb[p->src] + length; packet_length[p->src] += length; printf("This piece traveled %d hops\n", p->traveled_hops_count); if (p->pieceEnd) { CnetAddr tmpaddr; //length = p->pieceNumber * (linkinfo[arrived_on_link].mtu // - PACKET_HEADER_SIZE) + p->length; length = packet_length[p->src]; int p_checksum = p->checksum; int checksum = CNET_ccitt( (unsigned char *) (receiveBuffer[p->src]), (int) length); if (p_checksum != checksum) { /***************************send back error ack**************/ //NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_savehopcount(p->src, p->trans_time, arrived_on_link); tmpaddr = p->src; /* swap src and dest addresses */ p->src = p->dest; p->dest = tmpaddr; p->kind = NL_ERR_ACK; //p->hopcount = 0; p->traveled_hops_count = 0; memset(p->traveled_hops, -1, MAXHOPS*sizeof(int)); p->trans_time = 0; p->length = 0; flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0); return 0; /***************************end******************************/ } if (CNET_write_application(receiveBuffer[p->src], &length) == -1) { //source node should send this msg again if (cnet_errno == ER_CORRUPTFRAME) { printf("Warning: host %d received a corrupt packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src); } else if (cnet_errno == ER_MISSINGMSG) { printf("Warning: host %d received a unordered packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src); }else if (cnet_errno == ER_BADSIZE){ printf("Warning: host %d received a loss packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src); } } else { printf("host %d received a correct packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src); } rb[p->src] = &receiveBuffer[p->src][0]; packet_length[p->src] = 0; inc_NL_packetexpected(p->src); //NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_savehopcount(p->src, p->trans_time, arrived_on_link); //send a NL_ACK back to source host tmpaddr = p->src; /* swap src and dest addresses */ p->src = p->dest; p->dest = tmpaddr; p->kind = NL_ACK; //p->hopcount = 0; p->traveled_hops_count = 0; memset(p->traveled_hops, -1, MAXHOPS*sizeof(int)); p->trans_time = 0; p->length = 0; packet_length[p->src] = 0; //printf("right frame! up to app\n"); flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0); //printf("send ack\n"); } } break; case NL_ACK: if (p->seqno == NL_ackexpected(p->src)) { //printf("ACK come!\n"); inc_NL_ackexpected(p->src); //NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_savehopcount(p->src, p->trans_time, arrived_on_link); CHECK(CNET_enable_application(p->src)); } break; case NL_ERR_ACK: printf("ERROR ACK!\n"); if (p->seqno == NL_ackexpected(p->src)) { //NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_savehopcount(p->src, p->trans_time, arrived_on_link); printf("packet %d (to %d) error!\n", p->seqno, p->src); NL_PACKET * packettoresend = get_last_packet(p->src); printf("length = %d seq = %d\n", packettoresend->length, packettoresend->seqno); int a = packettoresend->checksum; int b = CNET_ccitt((unsigned char *) (packettoresend->msg), (int) (packettoresend->length)); if (a == b) { printf("ok!\n"); } else printf("wrong!\n"); int len = PACKET_HEADER_SIZE + packettoresend->length; flood3((char *) packettoresend, len, 0, 0); } break; default: ; //printf("it's nothing!====================\n"); } } /* THIS PACKET IS FOR SOMEONE ELSE */ else { // printf("hopcount = %d\n", p->hopcount); // printf("MAXHOPS = %d\n", MAXHOPS); //if (p->hopcount < MAXHOPS) { /* if not too many hops... */ //printf("other's frame!\n"); //printf("piece for another node arrives\n"); length = p->length; memcpy(rb[p->src], (char *) p->msg, length); rb[p->src] = rb[p->src] + length; packet_length[p->src] += length; if (p->pieceEnd) { //printf("last piece for another node arrives\n"); //length = p->pieceNumber * (linkinfo[arrived_on_link].mtu // - PACKET_HEADER_SIZE) + p->length; length = packet_length[p->src]; //NL_savehopcount(p->src, p->hopcount, arrived_on_link); NL_savehopcount(p->src, p->trans_time, arrived_on_link); NL_PACKET wholePacket; wholePacket.src = p->src; wholePacket.dest = p->dest; wholePacket.kind = p->kind; wholePacket.seqno = p->seqno; //wholePacket.hopcount = p->hopcount; wholePacket.trans_time = p->trans_time; wholePacket.traveled_hops_count = p->traveled_hops_count; memcpy(wholePacket.traveled_hops,p->traveled_hops, MAXHOPS); wholePacket.pieceEnd = 0; wholePacket.pieceNumber = 0; wholePacket.length = length; packet_length[p->src] = 0; memcpy(wholePacket.msg, receiveBuffer[p->src], length); flood3((char *) &wholePacket, PACKET_SIZE(wholePacket), 0, arrived_on_link); rb[p->src] = &receiveBuffer[p->src][0]; } //} else // printf("drop\n"); /* silently drop */; } printf("\n"); return (0); }
///Worker Method ///Called when we receive data from one of our data link layers. ///Handles association with AP's and propagation of frames to other layers. static void up_from_dll(int link, const char *data, size_t length) { //fprintf(stdout, "\t%s: Received frame from dll on link\n", nodeinfo.nodename); if (length > sizeof(struct nl_packet)) { printf("\t%s: %zu is larger than a nl_packet! ignoring.\n",nodeinfo.nodename, length); return; } //Treat this frame as a network layer packet. struct nl_packet packet; memset(&packet, 0, sizeof(packet)); memcpy(&packet, data, length); fprintf(stdout, "\tPacket dest %i: \n\t %s's src: %i\n", packet.dest, nodeinfo.nodename, nodeinfo.address); fprintf(stdout, "\t%s: Received frame from dll on link %d\n\tfrom node %" PRId32 " for node %" PRId32 ".\n",nodeinfo.nodename, link, packet.src, packet.dest); uint32_t checksum = packet.checksum; packet.checksum = 0; fprintf(stdout,"\t%s has received a nl_packet of type ",nodeinfo.nodename); printFRAMEKIND(packet.type); fprintf(stdout,"\n"); if (CNET_crc32((unsigned char *)&packet, sizeof(packet)) != checksum) { fprintf(stdout, "\tChecksum failed.\n"); //return; } if (packet.dest != nodeinfo.address) { fprintf(stdout, "\tThat's not for me.\n"); fprintf(stdout, "\tPacket dest %i: \n\t %s's src: %i\n", packet.dest, nodeinfo.nodename, nodeinfo.address); fprintf(stdout, "\tPacket src %i: \n", packet.src); return; } // Check if we've seen this packet rece ntly. for (size_t i = 0; i < PACKET_MEMORY_LENGTH; ++i) { if (seen_checksums[i] == checksum) { fprintf(stdout, "\tI seem to have seen this recently.\n"); return; } } // Remember the checksum of this packet. seen_checksums[next_seen_checksum++] = checksum; next_seen_checksum %= PACKET_MEMORY_LENGTH; fprintf(stdout,"\t%s has received a nl_packet of type ",nodeinfo.nodename); printFRAMEKIND(packet.type); fprintf(stdout,"\n"); struct nl_packet assRequest; switch (packet.type) { case NL_DATA : fprintf(stdout, "\nDATA FRAME FOR %i @ %i, seq=%d \n", packet.dest, nodeinfo.address, packet.seq); if(packet.seq == frameexpected) { fprintf(stdout, "\tDATA Up to the application layer!\n"); size_t payload_length = packet.length; CHECK(CNET_write_application(packet.data, &payload_length)); frameexpected = 1 - frameexpected; } else { fprintf(stdout, "\tignored...\n"); } struct nl_packet ackPacket = (struct nl_packet){ .src = nodeinfo.address, .dest = packet.src, .length = NL_MAXDATA, .type = NL_ACK }; memcpy(ackPacket.data,nodeinfo.nodename,sizeof(nodeinfo.nodename)); ackPacket.seq = packet.seq; ackPacket.checksum = CNET_crc32((unsigned char *)&ackPacket, sizeof(ackPacket)); fprintf(stdout, "\tTransmitting an acknowledgement packet, seq = %i!*********************\n", ackPacket.seq); fprintf(stdout, "\n ackpacket src:%i dest:%i\n",ackPacket.src, ackPacket.dest); if(ackPacket.dest > 133) exit(0); transmit(&ackPacket); break; case NL_ACK : //CANCEL THE TIMEOUT FUNCTION AS WE HAVE RECEIVED THE ACKNOWLEEDGEMENT EXPECTED //If it has the expected sequence number if(packet.seq == ackexpected) { printf("\t\t\t\t**************ACK received, seq=%d\n", packet.seq); CHECK(CNET_stop_timer(data_timeout)); ackexpected = 1-ackexpected; CHECK(CNET_enable_application(ALLNODES)); } break; case NL_ASSREQ : if(timeAPset == false) { if(isAss == false) { fprintf(stdout, "\n%s is now associated with ap link %i\n", nodeinfo.nodename,packet.src); CHECK(CNET_stop_timer(probe_timer)); assRequest.type = NL_ASSREQ; assRequest.dest = packet.src; assRequest.src = nodeinfo.address; assRequest.length = NL_MAXDATA; assRequest.checksum = CNET_crc32((unsigned char *)&assRequest, sizeof(assRequest)); fprintf(stdout, "\ttoSend is of frame type "); printFRAMEKIND(toSend->type); fprintf(stdout, "\n"); fprintf(stdout, "\n%s Is ASSOCIATED!**********\n",nodeinfo.nodename); if(assRequest.dest > 133) exit(0); //DOING THINGS timeAPset = true; isAss = true; transmit(&assRequest); CHECK(CNET_enable_application(ALLNODES)); } else { fprintf(stderr, "HOLY CRAP BATMAN! I'M REASSOCIATING!\n"); //exit(EXIT_FAILURE);; isAss = true; CHECK(CNET_stop_timer(probe_timer)); } timeAPset = nodeinfo.time_of_day.sec; } break; default : fprintf(stdout, "\tFollowing default\n"); exit(0); // Send this packet to the application layer. fprintf(stdout, "\tUp to the application layer!\n"); size_t payload_length = packet.length; CHECK(CNET_write_application(packet.data, &payload_length)); break; } } ///Event Handler ///Called when this mobile node's application layer has generated a new message. ///Proceeds to transmit the generated message. static EVENT_HANDLER(application_ready) { fprintf(stdout, "\t%s's application later ready, creating new message.\n\t Max data: %i, Type: %" PRId32".\n",nodeinfo.nodename, NL_MAXDATA, NL_DATA); toSend->src = nodeinfo.address; toSend->length = NL_MAXDATA; toSend->type = NL_DATA; toSend->seq = nextframetosend; printf( " THE NEXT FRAME TO SEND IS %i\n", nextframetosend); struct nl_packet temp = (struct nl_packet){ .src = nodeinfo.address, .length = NL_MAXDATA, }; //update toSend CHECK(CNET_read_application(&temp.dest, temp.data, &temp.length)); memcpy(&(toSend->dest),&temp.dest,sizeof(temp.dest)); memcpy(&(toSend->data), &temp.data, temp.length); toSend->length = temp.length; fprintf(stdout, "\ntoSend dest:%i\n", toSend->dest); fprintf(stdout, "\tAppready: toSend is of frame type "); printFRAMEKIND(toSend->type); fprintf(stdout, "\n"); toSend->checksum = CNET_crc32((unsigned char *)&toSend, sizeof(toSend)); fprintf(stdout, "\t%s: Generated message for % " PRId32 ",\n\t attempting to transmit\n",nodeinfo.nodename, toSend->dest); CHECK(CNET_disable_application(ALLNODES)); transmit(toSend); if(toSend->type != NL_DATA) { fprintf(stderr, "\t%s toSend is not DATA!\n",nodeinfo.nodename); exit(0); } // CNET_start_timer(EV_TIMER2, 1, 0); nextframetosend = 1-nextframetosend; fprintf(stdout, "\tPacket transmitted successfully.\n"); } ///Event Handler ///Creates a new probe packet and sends it to transmit for propagation. ///This packet is used to discover access points and find an appropriate one ///for association. ///It then starts a timer to ensure that if there is no response, an additional ///probe is sent after a period of time. ///The timer is stopped once an acknowledgement is received and the mobile device ///is considered 'associated' with an access point. static EVENT_HANDLER(probe) { probe_timer = CNET_start_timer(EV_TIMER3, 5000000, 0); fprintf(stdout, "\n%s Probing...\n", nodeinfo.nodename); struct nl_packet packet = (struct nl_packet){ .src = nodeinfo.address, .length = NL_MAXDATA, }; memcpy(packet.data,nodeinfo.nodename,sizeof(nodeinfo.nodename)); packet.type = NL_PROBE; packet.checksum = CNET_crc32((unsigned char *)&packet, sizeof(packet)); //create broadcast address CnetNICaddr wifi_dest; CHECK(CNET_parse_nicaddr(wifi_dest, "ff:ff:ff:ff:ff:ff")); uint16_t packet_length = NL_PACKET_LENGTH(packet); CHECK(CNET_disable_application(ALLNODES)); dll_wifi_write(dll_states[1], wifi_dest, (char *)&packet, packet_length); } static EVENT_HANDLER(timeouts) { printf("timeout, seq=%d\n", ackexpected); transmit(toSend); }
/** Emulates a network layer for the link layer */ void network_receive(int link, char *data, size_t size) { CHECK(CNET_write_application(data, &size)); }
void process_frames(){ if(queue_nitems(receiver) == 0){ return; } size_t len = 0; FRAME *f = queue_peek(receiver, &len); int source_nodenumber = find_nodenumber(f->payload.source); if(node_buffer[source_nodenumber].busy){ free(f); return; } node_buffer[source_nodenumber].busy = true; f = queue_remove(receiver, &len); //printf("Received frames for message #%d Expecting %d\n", f->payload.mesg_seq_no, node_buffer[source_nodenumber].mesg_seq_no_to_receive); //If ack has not been received at the sender side and an old frame from an old message has been received if(f->payload.mesg_seq_no < node_buffer[source_nodenumber].mesg_seq_no_to_receive){ //printf("Message received is old, dropped :-( Message #%d\n", f->payload.mesg_seq_no); node_buffer[source_nodenumber].busy = false; free(f); process_frames(); return; } if(f->payload.mesg_seq_no > node_buffer[source_nodenumber].mesg_seq_no_to_receive){ queue_add(receiver, f, len); //printf("Message received is new, pushed back ;-) Message #%d\n", f->payload.mesg_seq_no); node_buffer[source_nodenumber].busy = false; free(f); //process_frames(); return; } int seq_no = f->payload.A; char seq_str[5]; sprintf(seq_str, "%d", seq_no); if(seq_no == node_buffer[source_nodenumber].next_seq_number_to_add){ //send ack here create_ack(f->payload); // add to the incomplete data object //printf("Frame appending %d with length %d | MSG #%d\n",seq_no, f->payload.len, f->payload.mesg_seq_no); memcpy(&node_buffer[source_nodenumber].incomplete_data[0] + node_buffer[source_nodenumber].bytes_added, &f->payload.data[0], f->payload.len); node_buffer[source_nodenumber].bytes_added += f->payload.len; node_buffer[source_nodenumber].next_seq_number_to_add++; while(true){ int next_seq = node_buffer[source_nodenumber].next_seq_number_to_add; char next_seq_str[5]; sprintf(next_seq_str, "%d", next_seq); size_t plen; PACKET *pkt = hashtable_find(node_buffer[source_nodenumber].ooo_packets, next_seq_str, &plen); if(plen == 0) break; //printf("In While loop:Next frame %d found in HT\n",next_seq); pkt = hashtable_remove(node_buffer[source_nodenumber].ooo_packets, next_seq_str, &plen); create_ack(*pkt); memcpy(&node_buffer[source_nodenumber].incomplete_data[0] + node_buffer[source_nodenumber].bytes_added, &pkt->data, pkt->len); node_buffer[source_nodenumber].bytes_added += pkt->len; node_buffer[source_nodenumber].next_seq_number_to_add++; } // check for the last packet if(f->payload.flag_offset == 1) { //printf("\t\t\t\t\t\tBytes in reconstructed message is %d and is sent by %d\n",node_buffer[source_nodenumber].bytes_added, source_nodenumber); CHECK(CNET_write_application((char*)&node_buffer[source_nodenumber].incomplete_data[0], &node_buffer[source_nodenumber].bytes_added)); node_buffer[source_nodenumber].next_seq_number_to_add = 0; memset(node_buffer[source_nodenumber].incomplete_data, '\0', MAX_MESSAGE_SIZE); hashtable_free(node_buffer[source_nodenumber].ooo_packets); // Overriding default bucket size of 1023 node_buffer[source_nodenumber].ooo_packets = hashtable_new(256); printf("\t\t\t\t\t\tSuccessfully Written to Application. Bytes in the reconstructed message #%d are %d sent by %d.\n", f->payload.mesg_seq_no, node_buffer[source_nodenumber].bytes_added, source_nodenumber); node_buffer[source_nodenumber].bytes_added = 0; node_buffer[source_nodenumber].mesg_seq_no_to_receive++; //= f->payload.mesg_seq_no; } } else { size_t plen; hashtable_find(node_buffer[source_nodenumber].ooo_packets, seq_str, &plen); if(plen == 0){ hashtable_add(node_buffer[source_nodenumber].ooo_packets, seq_str, &f->payload, len - sizeof(uint32_t)); } } node_buffer[source_nodenumber].busy = false; process_frames(); free(f); }