コード例 #1
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);
	}
}
コード例 #2
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;
    }
}
コード例 #3
0
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);
	}
}
コード例 #4
0
ファイル: flooding3.c プロジェクト: sumdog/assignments
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");
    }
}
コード例 #5
0
ファイル: lab1.c プロジェクト: jcairo/C313A1
/* 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);  
    }
     


}
コード例 #6
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);
}
コード例 #7
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;
}
コード例 #8
0
ファイル: assignment.c プロジェクト: cbeardsmore/slidwin
static void transport_up( char* data, size_t dataLength )
{
    // WRITE THE MESSAGE BACK TO THE APPLICATION LAYER
    CHECK(CNET_write_application( data, &dataLength ));
}
コード例 #9
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);
}
コード例 #10
0
ファイル: mobile.c プロジェクト: vanbujm/CITS3230
///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); 
}
コード例 #11
0
/** Emulates a network layer for the link layer */
void network_receive(int link, char *data, size_t size)
{
	CHECK(CNET_write_application(data, &size));
}
コード例 #12
0
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);
}