/* down_to_network() RECEIVES NEW MESSAGES FROM THE APPLICATION LAYER AND PREPARES THEM FOR TRANSMISSION TO OTHER NODES. */ static EVENT_HANDLER(down_to_network) { //printf("down_to_network\n"); NL_PACKET p; p.length = sizeof(p.msg); //printf("p.length = %d, MAX_MESSAGE_SIZE = %d", p.length, MAX_MESSAGE_SIZE); CHECK(CNET_read_application(&p.dest, p.msg, &p.length)); CNET_disable_application(p.dest); p.src = nodeinfo.address; p.kind = NL_DATA; //p.hopcount = 0; memset(p.traveled_hops, -1, MAXHOPS*sizeof(int)); p.traveled_hops[0] = nodeinfo.nodenumber; p.traveled_hops_count = 1; p.trans_time = 0; p.seqno = NL_nextpackettosend(p.dest); p.pieceNumber = 0; p.pieceEnd = 0; p.checksum = CNET_ccitt((unsigned char *) (p.msg), p.length); lastPacket = &p; update_last_packet(&p); printf("Packet generated at host %d, des %d\n\n", nodeinfo.address, p.dest); flood3((char *) &p, PACKET_SIZE(p), 0, 0); }
/* down_to_network() RECEIVES NEW MESSAGES FROM THE APPLICATION LAYER AND PREPARES THEM FOR TRANSMISSION TO OTHER NODES. */ static EVENT_HANDLER( down_to_network) { NL_PACKET p; p.length = sizeof(p.msg); CHECK(CNET_read_application(&p.dest, p.msg, &p.length)); CNET_disable_application(p.dest); p.src = nodeinfo.address; p.kind = NL_DATA; p.seqno = NL_nextpackettosend(p.dest); p.hopcount = 0; p.pieceNumber = 0; p.pieceEnd = 0; p.src_packet_length = (int) p.length; p.checksum = CNET_ccitt((unsigned char *) (p.msg), p.src_packet_length); p.trans_time = 0; p.is_resent = 0; //lastPacket = &p; printf( "packet generated, src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n\n", nodeinfo.address, p.dest, p.seqno, p.length, p.checksum); flood((char *) &p, PACKET_SIZE(p), 0, 0); update_last_packet(&p); }
static void transmit_frame(FRAME frame) { size_t frameLength; if (frame.kind == DL_DATA) // DATA FRAME { // SET THE TIMER PRIOR TO SENDING printf("DATA TRANSMITTED\nTO:\t%s\n", nodenames[frame.destNode]); set_timer(frame); } else // ACK FRAME { // NO TIMER, SIMPLY SEND THE FRAME OUT printf("\nACK TRANSMITTED\n"); } printf("VIA LINK:\t%d\nSEQ NO:\t%d\n\n", frame.link, frame.seq); // CALCULATE THE CHECKSUM AND ADD TO THE FRAME frame.checksum = 0; frameLength = FRAME_SIZE(frame); frame.checksum = CNET_ccitt((unsigned char *)&frame, frameLength); // SEND FRAME VIA PHYSICAL LAYER CHECK(CNET_write_physical(frame.link, (char *)&frame, &frameLength)); }
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; } }
static EVENT_HANDLER(physical_ready){ //printf("PR called!\n"); int link; FRAME f; size_t length = sizeof(FRAME); CHECK(CNET_read_physical(&link, (char*)&f, &length)); printf("Packet received from %d, via %d\n", f.payload.source, f.payload.dest); //DATA LINK LAYER - check if checksum matches int cs = f.checksum; f.checksum = 0; if(CNET_ccitt((unsigned char*)&f, (int)length) != cs){ printf("Bad Checksum - ignoring frame!\n"); return; } switch(f.payload.kind){ case RT_DATA : update_table(link, f, length); break; case DL_DATA : handle_data(link, f, length); break; case DL_ACK : handle_ack(link, f.payload); break; default : printf("The world is not enough!\n"); break; } //printf("Packet successfully processed!"); }
static void transmit_frame(MSG *msg, FRAMEKIND kind, size_t length, int seqno) { FRAME f; int link = 1; f.kind = kind; f.seq = seqno; f.checksum = 0; f.len = length; switch (kind) { case ACK : CHECK(CNET_set_wlancolour(link, "blue")); break; case DATA: { CnetTime timeout; CHECK(CNET_set_wlancolour(link, "red")); memcpy(&f.msg, (char *)msg, length); timeout = (FRAME_SIZE(f)*(CnetTime)8000000 / linkinfo[link].bandwidth + linkinfo[link].propagationdelay); timeout = 300000; lasttimer = CNET_start_timer(EV_TIMER1, 3 * timeout, 0); break; } } length = FRAME_SIZE(f); f.checksum = CNET_ccitt((unsigned char *)&f, length); CHECK(CNET_write_physical_reliable(link, (char *)&f, &length)); }
static void datalink_up(CnetEvent ev, CnetTimerID timer, CnetData data) { FRAME frame; int link, checksum; // READ PHYSICAL LAYER FRAME size_t frameLength = sizeof(FRAME); CHECK(CNET_read_physical(&link, (char *)&frame, &frameLength)); // ENSURE CHECKSUM WAS OKAY checksum = frame.checksum; frame.checksum = 0; if (CNET_ccitt((unsigned char *)&frame, (int)frameLength) != checksum) { // CHECKSUM IS BAD SO DROP THE PACKET. SENDER WILL TIMEOUT + RESEND printf("\t\t\t\t\tFRAME RECEIVED\n\t\t\t\t\tBAD CHECKSUM - IGNORE\n"); return; } if (frame.kind == DL_DATA) { // PRINT FULL INFO OF ALL DATA WITHIN THE FRAME printf("\n\t\t\t\t\tDATA RECEIVED\n"); printf("\t\t\t\t\tSOURCE:\t%s\n", nodenames[frame.srcNode]); printf("\t\t\t\t\tDEST:\t%s\n", nodenames[frame.destNode]); printf("\t\t\t\t\tIN LINK:\t%d\n", link); printf("\t\t\t\t\tSEQ NO:\t%d\n", frame.seq); printf("\t\t\t\t\tDATA:\t%s\n", frame.data); printf("\t\t\t\t\tLENGTH:\t%d\n", frame.len); // CHECK IF SEQUENCE NUMBER OF FRAME IS THE ONE WE EXPECT if (frame.seq == frameExpected[link - 1]) { // ACCEPT IT, THROW FRAME UP TO THE NETWORK LAYER network_up(frame, link); } // CHECK IF FRAME IS A DUPLICATE // MATHS CHECKS IF SEQ == FRAMEEXPECTED - 1, ACCOUNTING FOR WRAPAROUND else if (frame.seq == (frameExpected[link - 1] + MAX_SEQ) % (MAX_SEQ + 1)) { printf("\t\t\t\t\tDUPLICATE FRAME\n"); printf("\t\t\t\t\tEXPECTED: %d\n", frameExpected[ link - 1]); // DUPLICATE MUST BE BECAUSE ACK LOST, RESEND THE ACK transmit_ack(link, frame.seq); } } // IF NOT DATA, MUST BE AN ACK FRAME else { // DEAL WITH ACK VIA GO-BACK-N ack_received(frame, link); } }
void handle_ack(int link, FRAME f){ //printf("handle ack called for mesg #%d\n", p.mesg_seq_no); if(f.payload.dest == nodeinfo.address && f.payload.mesg_seq_no == links[link].msg_in_sender_Q) links[link].ack_received[f.payload.A] = true; if(f.payload.dest != nodeinfo.address){ int forwarding_link = find_link(f.payload.dest); f.checksum = 0; f.checksum = CNET_ccitt((unsigned char *)&f, FRAME_HEADER_SIZE); queue_add(links[forwarding_link].ack_sender, &f, FRAME_HEADER_SIZE); schedule_and_send(forwarding_link); } }
void create_ack(PACKET p){ FRAME ack; ack.payload.kind = DL_ACK; ack.payload.dest = p.source; ack.payload.source = nodeinfo.address; ack.payload.A = p.A; ack.payload.len = FRAME_HEADER_SIZE; ack.payload.mesg_seq_no = p.mesg_seq_no; ack.checksum = 0; ack.checksum = CNET_ccitt((unsigned char *)&ack, (int)FRAME_HEADER_SIZE); int link = find_link(p.source); queue_add(links[link].ack_sender, &ack, FRAME_HEADER_SIZE); schedule_and_send(link); }
static void ack_send(int sequence, int type) { ACK_FRAME f; f.check = 0; if(type == SREJ) f.sequence = -sequence; else f.sequence = sequence; size_t size = sizeof(ACK_FRAME); f.check = CNET_ccitt((unsigned char *) &f, size); printf("ACK transmitted\n"); CHECK(CNET_write_physical(1, (char *) &f, &size)); }
void handle_data(int link, FRAME f, size_t len){ // If packet is sent to this node, accept it, reconstruct the whole message and send it to the application layer //printf("handle data called for message #%d\n", f.payload.mesg_seq_no); if(f.payload.dest == nodeinfo.address){ queue_add(receiver, &f, len); process_frames(); } // Else forward it according to the routing information that we have, this node will act as a router else{ //printf("Processing forward to %d from %d via %d\n", f.payload.dest, f.payload.source, nodeinfo.address); int forwarding_link = find_link(f.payload.dest); f.checksum = 0; f.checksum = CNET_ccitt((unsigned char *)&f, (int)(f.payload.len) + FRAME_HEADER_SIZE); queue_add(links[forwarding_link].forwarding_queue, &f, len); //will have to schedule with sender queue schedule_and_send(forwarding_link); } }
//----------------------------------------------------------------------------- // read a frame from physical layer void read_datalink(CnetEvent event, CnetTimerID timer, CnetData data) { int link; DL_FRAME frame; size_t len = PACKET_HEADER_SIZE+DATAGRAM_HEADER_SIZE + DL_FRAME_HEADER_SIZE + MAX_MESSAGE_SIZE; CHECK(CNET_read_physical(&link, (char *)&frame, &len)); // compare the checksum size_t dtg_len = len - DL_FRAME_HEADER_SIZE; uint16_t checksum = frame.checksum; uint16_t checksum_to_compare = CNET_ccitt((unsigned char *)&frame.data, dtg_len); if (checksum_to_compare != checksum) { return; } //read a datagram to network layer read_network(link, dtg_len, (char*) frame.data); }
static void frame_send(MESSAGE *message, int length, int sequence) { if(length > DATA_SIZE_MAX) length = DATA_SIZE_MAX; FRAME_DATA f; f.sequence = sequence; f.length = length; f.checksum = 0; memcpy(&f.message, message, length); f.checksum = CNET_ccitt((unsigned char *) &f, CHECK_BYTES); printf("DATA transmitted, frame sequence = %d\n", sequence); t_window[sequence] = f; size_t size = DATA_FRAME_SIZE(f); CHECK(CNET_write_physical(1, (char *) &f, &size)); }
//----------------------------------------------------------------------------- // write a frame to the link void write_datalink(int link, char *datagram, uint32_t length) { DTG_CONTAINER container; container.len = length; container.link = link; container.checksum = CNET_ccitt((unsigned char *) datagram, (size_t)length); size_t datagram_length = length; memcpy(&container.data, datagram, datagram_length); // check if timer is null to avoid polling if (datalink_timers[link] == NULLTIMER) { CnetTime timeout_flush = 1; datalink_timers[link] = CNET_start_timer(EV_DATALINK_FLUSH, timeout_flush, link); } output_max[link] = max(output_max[link], queue_nitems(output_queues[link])); // add to the link queue if(queue_nitems(output_queues[link]) < 5000) { size_t container_length = DTG_CONTAINER_SIZE(container); queue_add(output_queues[link], &container, container_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) { 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); }
static EVENT_HANDLER(ready_physical) { if(nodetype != RECEIVER) { ACK_FRAME f; int link; size_t length; length = sizeof(ACK_FRAME); CHECK(CNET_read_physical(&link, (char*) &f, &length)); uint16_t check = f.check; f.check = 0; if(CNET_ccitt((unsigned char*) &f, sizeof(ACK_FRAME)) != check) return; if(f.sequence <= 0) { // SREJ FRAME printf("\t\t\t\tSREJ received, sequence=%d\n", -f.sequence); f.sequence = -f.sequence; CNET_stop_timer(timer); trans_frame_state[f.sequence] = ACK_WAIT; frame_send(&(t_window[f.sequence].message), t_window[f.sequence].length, f.sequence); } else { // RECVREADY FRAME printf("\t\t\t\tACK received, sequence=%d\n", f.sequence); int i; for(i = (last_ack_recv + 1)%(MAXSEQ + 1); i != f.sequence - 1; i = (i + 1) % (MAXSEQ + 1)) trans_frame_state[i] = ACK_RECEIVED; last_ack_recv = f.sequence - 1; trans_frame_state[f.sequence-1] = ACK_RECEIVED; CNET_stop_timer(timer_wait); if(packets_sent >= 10000) { if(time_end == 0) time_end = nodeinfo.time_of_day.sec; } else { packets_sent++; CNET_enable_application(ALLNODES); } } } else { FRAME_DATA f; size_t length; int link; int checksum; length = sizeof(FRAME_DATA); CHECK(CNET_read_physical(&link, (char*) &f, &length)); checksum = f.checksum; f.checksum = 0; if(CNET_ccitt((unsigned char*) &f, CHECK_BYTES) != checksum) { // bad checksum, ignore frame printf("\t\t\t\tBAD checksum - frame ignored\n"); ack_send(last_ack_sent + 1, SREJ); printf("Requesting to send frame %d\n",last_ack_sent+1); return; } recv_frame_status[f.sequence] = RECEIVED; printf("\t\t\t\tDATA received, sequence=%d\n", f.sequence); int i; for(i = (last_ack_sent + 1) % (MAXSEQ + 1); i != f.sequence; i = (i + 1) % (MAXSEQ + 1)) { if(recv_frame_status[i] != RECEIVED) break; } if(i == f.sequence) ack_send(f.sequence + 1, RECVREADY); } }
void network_send(){ if(queue_nitems(msg_queue) == 0){ CNET_start_timer(EV_TIMER0, 100000, 0); return; // do nothing } //Fragment each message into a small unit and send along the link designated by the routing table size_t len = 0; next = queue_peek(msg_queue, &len); CnetAddr dest = next->dest; int dest_number = find_nodenumber(dest); //get link to send from the routing table int currLink = find_link(dest); //printf("Link to send is : %d\n", currLink); if(queue_nitems(links[currLink].sender) > 0){ //free(next); //printf("Some items in SENDER queue!\n"); CNET_start_timer(EV_TIMER0, 100000, 0); return; // do nothing } //Remove the topmost message from the queue next = queue_remove(msg_queue, &len); links[currLink].msg_in_sender_Q = node_buffer[dest_number].mesg_seq_no_to_generate; //printf("Message is to be processed! To be sent to %d from %d and size %d and message number is %d\n", dest, nodeinfo.address, len, mesg_seq_no); //printf("Creating frames for message #%d\n", mesg_seq_no); int int_len = len - MESSAGE_HEADER_SIZE; char *data_ptr; data_ptr = &next->data[0]; //printf("Message is to be processed! To be sent to %d from %d and size %d and message is %s.\n", dest, nodeinfo.address, len, data); //Enable application is message queue grows too small if(queue_nitems(msg_queue) < MAX_MSG_QUEUE_SIZE/2){ application_enabled = true; CNET_enable_application(ALLNODES); } size_t frame_len = table[dest_number].min_mtu - FRAME_HEADER_SIZE; // removing the length occupied by the destination address in the MESSAGE //printf("Min mtu - FRAME_HEADER_SIZE is : %d Initial message size was %d, after removing dest part it is %d\n", frame_len, len, int_len); //queue packets up int seqno; for(seqno = 0; int_len > 0; seqno++){ FRAME f; memset(&f.payload.data[0], '\0', MAX_MESSAGE_SIZE); f.payload.kind = DL_DATA; f.payload.source = nodeinfo.address; f.payload.dest = dest; f.payload.mesg_seq_no = node_buffer[dest_number].mesg_seq_no_to_generate; f.payload.len = (int_len < frame_len) ? int_len : frame_len; f.payload.flag_offset = (int_len <= frame_len) ? 1 : 0; getcurrtime(&f.payload.timestamp); f.payload.A = seqno; memcpy(&f.payload.data[0], data_ptr, f.payload.len); //printf("Length of frame to send is : %d and the payload is %s (before adding to queue)\n", strlen(f.payload.data) + FRAME_HEADER_SIZE, f.payload.data); f.checksum = 0; f.checksum = CNET_ccitt((unsigned char *)&f, (int)(f.payload.len) + FRAME_HEADER_SIZE); len = f.payload.len + FRAME_HEADER_SIZE; queue_add(links[currLink].sender, &f, len); int_len = int_len - frame_len; data_ptr = data_ptr + frame_len; } printf("Message read from application layer destined for address %d | size %d | msg #%d | # frames %d \n", dest, len - MESSAGE_HEADER_SIZE, node_buffer[dest_number].mesg_seq_no_to_generate, seqno); //printf("Created %d frames\n", seqno); node_buffer[dest_number].mesg_seq_no_to_generate++; for(int i = 0; i < seqno; i++) links[currLink].ack_received[i] = false; schedule_and_send(currLink); CNET_start_timer(EV_TIMER0, 100000, 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\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); }