예제 #1
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) {

	//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);

}
예제 #2
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);

}
예제 #3
0
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));
}
예제 #4
0
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);
	}
}
예제 #5
0
파일: mobile4.c 프로젝트: jcairo/313L2
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!");	
}
예제 #7
0
파일: mobile4.c 프로젝트: jcairo/313L2
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));
}
예제 #8
0
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);
}
예제 #11
0
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);
	}
}
예제 #13
0
//-----------------------------------------------------------------------------
// 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);
}
예제 #14
0
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));
}
예제 #15
0
//-----------------------------------------------------------------------------
// 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);
    }
}
예제 #16
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) {
	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);
}
예제 #17
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);
}
예제 #19
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);
}