Пример #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) {
	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);

}
Пример #2
0
static EVENT_HANDLER(ready_app)
{  
  CnetAddr dest;
   int num_unack = next_frame - last_ack_recv;
   if(num_unack==(MAXSEQ+1)/2){
       timer_wait = CNET_start_timer(EV_TIMER1, TIMEOUT, 0);
       CNET_disable_application(ALLNODES);
       return;
   }

   if(num_unack<0){
       num_unack=MAXSEQ;
   }

   // if(trans_frame_state[next_frame%((MAXSEQ+1)/2)] == ACK_WAIT)
   // {
   //     timer_wait = CNET_start_timer(EV_TIMER1, TIMEOUT, 0);
   //     CNET_disable_application(ALLNODES);
   //     return;
   // }
   trans_frame_state[next_frame] = ACK_WAIT;
   
   size_t length = MAX_MESSAGE_SIZE;
   CHECK(CNET_read_application(&dest, (char*) last_msg, &length));
   
   frame_send(last_msg, length, next_frame);
   next_frame = (next_frame + 1) % (MAXSEQ + 1);
}
Пример #3
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);

}
Пример #4
0
static void down_to_transport(CnetEvent ev, CnetTimer timer, CnetData data) {

    /* our packet  */
    TR_PACKET p;

    /* destination address to pass to network layer */
    CnetAddr temp;


    p.length = sizeof(p.msg);
    CHECK(CNET_read_application(&temp, p.msg, &p.length));
    CNET_disable_application(temp);

    /* establish sequence number */
    unsigned long seq = getSequence(temp);
    if( seq == -1) {
        addAddress(temp,0);
        p.sequence_number = 0;
    }
    else {
        unsigned long newseq = seq + p.length;
        setSequence(temp,newseq);
        p.sequence_number = newseq;
    }


    p.checksum = checksum_crc32( ((char*)&p)+sizeof(unsigned int)
                                 , TR_PACKET_SIZE(p) - sizeof(unsigned int));

    down_to_network( (char*)&p , TR_PACKET_SIZE(p) , temp);
    /* enqueuePacket((char*)&p, TR_PACKET_SIZE(p), temp); */

    CNET_start_timer(EV_TIMER1, 1000, (CnetData)1);
}
static void push_message(MSG msg, size_t msgLength){
	if(queue_nitems(msg_queue) < MAX_MSG_QUEUE_SIZE){
		//printf("Pushing a message for %d with length %d\n", msg.dest, msgLength);
		queue_add(msg_queue, &msg, msgLength);
	}
	if(queue_nitems(msg_queue) == MAX_MSG_QUEUE_SIZE){
		CNET_disable_application(nodeinfo.address);
	}
	network_send();
}
static EVENT_HANDLER(application_ready){
	MSG msg;
	size_t len = sizeof(MSG);
	CHECK(CNET_read_application(&msg.dest, &msg.data, &len));
	queue_add(msg_queue, &msg, len + MESSAGE_HEADER_SIZE);
	if(queue_nitems(msg_queue) == MAX_MSG_QUEUE_SIZE){
		CHECK(CNET_disable_application(ALLNODES));
		app_enabled = false;
	}
}
Пример #7
0
static EVENT_HANDLER(application_ready)
{
    CnetAddr destaddr;

    lastlength  = sizeof(MSG);
    CHECK(CNET_read_application(&destaddr, (char *)lastmsg, &lastlength));
    CNET_disable_application(ALLNODES);

    transmit_frame(lastmsg, DATA, lastlength, nextframetosend);
    nextframetosend = 1-nextframetosend;
}
Пример #8
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;
	NL_PACKET test;

	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.pieceStartPosition = 0;
	p.pieceEnd = 0;
	p.src_packet_length = (int) p.length;
	p.checksum = CNET_crc32((unsigned char *) (p.msg), p.src_packet_length);
	p.piece_checksum = CNET_crc32((unsigned char *) (p.msg),
			p.src_packet_length);
	p.trans_time = 0;
	p.is_resent = 0;

	test.src = nodeinfo.address;
	test.dest = p.dest;
	test.kind = NL_TEST;
	test.hopcount = 0;
	test.seqno = 0;
	test.min_mtu = INT_MAX;
	test.length = 0;
	test.pieceStartPosition = 0;
	test.src_packet_length = PACKET_HEADER_SIZE;
	test.checksum = 0;
	test.piece_checksum = 0;
	test.trans_time = 0;
	test.is_resent = 0;

	NL_updatelastsendtest(&test);
	update_last_packet(&p);
	flood_test((char *) &test, PACKET_HEADER_SIZE, 0, 0);

	//TODO: please inform the mtu from src to dest by using pathfinder packet
	//size_t mtu_from_src_to_dest = 96;
	//piece_to_flood((char *) &p, mtu_from_src_to_dest);

}
Пример #9
0
///Worker Method
///Called to send a nl_packet to an associated access point.
///If this device is not associated, we abort and manage association instead
///as there is nowhere to transmit the packet to.
static int transmit(struct nl_packet *packet)
{  
  fprintf(stdout, "\tTransmitting.\n");
  
  // Create a 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);
  uint16_t packet_length = sizeof(*packet);
  
  if(packet->type == NULL_FRAME)
  {
    fprintf(stderr, "\t%s is attempting to send a null packet!\n",nodeinfo.nodename);
    exit(0);
  }
  if(isAss == false)
  {
    fprintf(stdout, "\tWhoops! %s is not associated!\n\t Starting Probe\n", nodeinfo.nodename);
   // CHECK(CNET_disable_application(ALLNODES));
    probe_timer = CNET_start_timer(EV_TIMER1, 100, 0);
    return 0;
  }
  else
  {
    fprintf(stdout, "\tAssociation is true, sending frame.\n");
    fprintf(stdout, "\n packet src:%i dest:%i\n",packet->src, packet->dest);
    if(packet->dest > 133) exit(0);

    dll_wifi_write(dll_states[1], wifi_dest, (char *)packet, packet_length);

    if(packet->type == NL_DATA )	
    {
      CHECK(CNET_disable_application(ALLNODES));
      printf(" DATA transmitted, seq=%d\n", packet->seq);
      data_timeout = CNET_start_timer(EV_TIMER2, CNET_rand() * 50000 + 500000, 0); /// one second wait time
    }
    
    return 1;
  }
}
Пример #10
0
static void datalink_down(FRAME frame, int inLink, int outLink)
{
    // FRAME IS BEING FORWARDED
    if ( outLink != 0 )
    {
        // MORE ROOM TO SEND SO TRANSMIT FRAME
        if (numInWindow[outLink - 1] < MAX_SEQ)
        {
            transmit_ack(inLink, frame.seq);
            inc(&frameExpected[inLink - 1]);

            frame.seq = nextFrameToSend[outLink - 1];
            // STORE FRAME IN THE OUTGOING WINDOW
            window[outLink - 1][nextFrameToSend[outLink - 1]] = frame;
            numInWindow[outLink - 1] += 1;

            // TRANSMIT THE FRAME OUT
            frame.link = outLink;
            transmit_frame(frame);
            inc(&nextFrameToSend[outLink - 1]); 
        }
        // NOT ENOUGH ROOM IN WINDOW TO SEND
        else
        {
            if (numInBuffer[outLink - 1] < MAX_SEQ + 1)
            {
                transmit_ack(inLink, frame.seq);
                inc(&frameExpected[inLink - 1]);

                // STORE FRAME IN THE BUFFER
                buffer[outLink - 1][bufferBounds[outLink - 1][1]] = frame;
                numInBuffer[outLink - 1] += 1;
                inc(&bufferBounds[outLink - 1][1]);
                printf("\t\t\t\t\tADDED TO BUFFER\n");
            }
            else
            {
                // IF WINDOW AND BUFFER BOTH FULL, CAN'T DO ANYTHING. DROP
                printf("\t\t\t\t\tBUFFER FULL, FRAME DROPPED\n");
            }
        }

        // IF THE WINDOW IS CURRENTLY FULL
        if (numInWindow[outLink - 1] >= MAX_SEQ)
        {
            // DISABLE GENERATION OF NEW MESSAGES WHILE WINDOW IS FULL

            for ( int ii = 0; ii < NUM_NODES; ii++ )
            { 

                // ONLY DISABLE MESSAGES FOR DESTINATION ROUTED THROUGH outLink
                if ( routingTable[nodeinfo.nodenumber][ii] == outLink )
                {    
                    CNET_disable_application( ii );
                    printf("\t\t\t\t\tDISABLED APPLICATION\n");
                    CNET_set_LED( outLink-1, "red" );
                }
            }
        }
    }
    else
    {
        // MORE ROOM TO SEND SO TRANSMIT FRAME
        if (numInWindow[inLink - 1] < MAX_SEQ)
        {
            // GET SEQUENCE NUMBER, STORE FRAME IN WINDOW, INC WINDOW NUMBER
            frame.seq = nextFrameToSend[inLink - 1];
            window[inLink - 1][nextFrameToSend[inLink - 1]] = frame;
            numInWindow[inLink - 1] += 1;
            // CALL DLL TO TRANSMIT FRAME
            frame.link = inLink;
            transmit_frame(frame);
            inc(&nextFrameToSend[inLink - 1]);
        }
        // NOT ENOUGH ROOM IN WINDOW TO SEND
        else
        {
            // ADD FRAME TO THE BUFFER WAITING TO SEND OUT
            buffer[inLink - 1][bufferBounds[inLink - 1][1]] = frame;
            numInBuffer[inLink - 1] += 1;
            inc(&bufferBounds[inLink - 1][1]);

            // PRINT DESTINATION OF MESSAGE, LINK, INDEX IN BUFFER
            printf("\nADDED TO BUFFER\n");
            printf("DEST:\t%s\n", nodenames[frame.destNode]);
            printf("LINK:\t%d\n", inLink);
            printf("INDEX:\t%d\n", bufferBounds[inLink - 1][1] - 1);
        }

        // IF THE WINDOW IS CURRENTLY FULL
        if (numInWindow[inLink - 1] >= MAX_SEQ)
        {
            // ONLY DISABLE MESSAGES FOR DESTINATION ROUTED THROUGH outLink                       
            for ( int ii = 0; ii < NUM_NODES; ii++ )
            { 
                if ( routingTable[nodeinfo.nodenumber][ii] == inLink )
                {    
                    CNET_disable_application( ii );
                    printf("DISABLE APPLICATION FOR %s\n", nodenames[ii] );
                    CNET_set_LED( inLink-1 , "red" );
                }
            }        
        }

    }
}
Пример #11
0
///Worker Method
///Called when we receive data from one of our data link layers.
///Handles association with AP's and propagation of frames to other layers.
static void up_from_dll(int link, const char *data, size_t length)
{
  //fprintf(stdout, "\t%s: Received frame from dll on link\n", nodeinfo.nodename);

  if (length > sizeof(struct nl_packet)) {
    printf("\t%s: %zu is larger than a nl_packet! ignoring.\n",nodeinfo.nodename, length);
    return;
  }
  
  //Treat this frame as a network layer packet.
  struct nl_packet packet;
  memset(&packet, 0, sizeof(packet));
  memcpy(&packet, data, length);
  fprintf(stdout, "\tPacket dest %i: \n\t %s's src: %i\n", packet.dest, nodeinfo.nodename, nodeinfo.address);

  fprintf(stdout, "\t%s: Received frame from dll on link %d\n\tfrom node %" PRId32
	" for node %" PRId32 ".\n",nodeinfo.nodename, link, packet.src, packet.dest);
  
  uint32_t checksum = packet.checksum;
  packet.checksum = 0;
  
  fprintf(stdout,"\t%s has received a nl_packet of type ",nodeinfo.nodename);
  printFRAMEKIND(packet.type);
  fprintf(stdout,"\n");
  
  if (CNET_crc32((unsigned char *)&packet, sizeof(packet)) != checksum) {
    fprintf(stdout, "\tChecksum failed.\n");
    //return;
  }
  
  if (packet.dest != nodeinfo.address) {
    fprintf(stdout, "\tThat's not for me.\n");
    fprintf(stdout, "\tPacket dest %i: \n\t %s's src: %i\n", packet.dest, nodeinfo.nodename, nodeinfo.address);
    fprintf(stdout, "\tPacket src %i: \n", packet.src);
    return;
  }
  
  // Check if we've seen this packet rece  ntly.
  for (size_t i = 0; i < PACKET_MEMORY_LENGTH; ++i) {
    if (seen_checksums[i] == checksum) {
      fprintf(stdout, "\tI seem to have seen this recently.\n");
      return;
    }
  }
  
  // Remember the checksum of this packet.
  seen_checksums[next_seen_checksum++] = checksum;
  next_seen_checksum %= PACKET_MEMORY_LENGTH;
  fprintf(stdout,"\t%s has received a nl_packet of type ",nodeinfo.nodename);
  printFRAMEKIND(packet.type);
  fprintf(stdout,"\n");
  
  struct nl_packet assRequest;

  switch (packet.type)	
  {  
    case NL_DATA :
      
      fprintf(stdout, "\nDATA FRAME FOR %i @ %i, seq=%d \n", packet.dest, nodeinfo.address, packet.seq);

      if(packet.seq == frameexpected) 
      {
	fprintf(stdout, "\tDATA Up to the application layer!\n");
	size_t payload_length = packet.length;
	CHECK(CNET_write_application(packet.data, &payload_length));
	frameexpected = 1 - frameexpected;


	
      } else {
	fprintf(stdout, "\tignored...\n");
      }
      
      
      	struct nl_packet ackPacket = (struct nl_packet){
	  .src = nodeinfo.address,
	  .dest = packet.src,
	  .length = NL_MAXDATA,
	  .type = NL_ACK
	  };
	  
	memcpy(ackPacket.data,nodeinfo.nodename,sizeof(nodeinfo.nodename));   
	ackPacket.seq = packet.seq;
	ackPacket.checksum = CNET_crc32((unsigned char *)&ackPacket, sizeof(ackPacket));
	fprintf(stdout, "\tTransmitting an acknowledgement packet, seq = %i!*********************\n", ackPacket.seq);
	fprintf(stdout, "\n ackpacket src:%i dest:%i\n",ackPacket.src, ackPacket.dest);
	if(ackPacket.dest > 133) exit(0);
	transmit(&ackPacket);
	 
	break;

  
    case NL_ACK :
    //CANCEL THE TIMEOUT FUNCTION AS WE HAVE RECEIVED THE ACKNOWLEEDGEMENT EXPECTED
    //If it has the expected sequence number  
      if(packet.seq == ackexpected) {
	    printf("\t\t\t\t**************ACK received, seq=%d\n", packet.seq);
	    CHECK(CNET_stop_timer(data_timeout));
	    ackexpected = 1-ackexpected;
	    CHECK(CNET_enable_application(ALLNODES));
	}
    break;

    case NL_ASSREQ :
      if(timeAPset == false)
      {
	if(isAss == false)
	{
	  fprintf(stdout, "\n%s is now associated with ap link %i\n",
		  nodeinfo.nodename,packet.src);
	  
	  CHECK(CNET_stop_timer(probe_timer));
	  assRequest.type = NL_ASSREQ;
	  assRequest.dest = packet.src;
	  assRequest.src = nodeinfo.address;
	  assRequest.length = NL_MAXDATA;
	  assRequest.checksum = CNET_crc32((unsigned char *)&assRequest, sizeof(assRequest));

	  fprintf(stdout, "\ttoSend is of frame type ");
	    printFRAMEKIND(toSend->type);
	    fprintf(stdout, "\n");

	  fprintf(stdout, "\n%s Is ASSOCIATED!**********\n",nodeinfo.nodename);
	  if(assRequest.dest > 133) exit(0);
	  
	  //DOING THINGS
	  timeAPset = true;
	  isAss = true;
	  transmit(&assRequest);
	  CHECK(CNET_enable_application(ALLNODES));
	}
	else
	{
	  fprintf(stderr, "HOLY CRAP BATMAN! I'M REASSOCIATING!\n");
	  //exit(EXIT_FAILURE);;
	  isAss = true;
	  CHECK(CNET_stop_timer(probe_timer));
	}
	timeAPset = nodeinfo.time_of_day.sec;
      }
      break;
      
    default :
      fprintf(stdout, "\tFollowing default\n");
      exit(0);
      // Send this packet to the application layer.
      fprintf(stdout, "\tUp to the application layer!\n");
      
      size_t payload_length = packet.length;
      CHECK(CNET_write_application(packet.data, &payload_length));
      
      break;
  }
}

///Event Handler
///Called when this mobile node's application layer has generated a new message.
///Proceeds to transmit the generated message.
static EVENT_HANDLER(application_ready)
{
  fprintf(stdout, "\t%s's application later ready, creating new message.\n\t Max data: %i, Type: %" PRId32".\n",nodeinfo.nodename, NL_MAXDATA, NL_DATA);
  
  toSend->src = nodeinfo.address;
  toSend->length = NL_MAXDATA;
  toSend->type = NL_DATA;
  toSend->seq = nextframetosend;
  
  printf( " THE NEXT FRAME TO SEND IS %i\n", nextframetosend); 
  
  struct nl_packet temp = (struct nl_packet){
    .src = nodeinfo.address,
    .length = NL_MAXDATA,
  };
  
  //update toSend
  CHECK(CNET_read_application(&temp.dest, temp.data, &temp.length));
  memcpy(&(toSend->dest),&temp.dest,sizeof(temp.dest));
  memcpy(&(toSend->data), &temp.data, temp.length);
  toSend->length = temp.length;
  fprintf(stdout, "\ntoSend dest:%i\n", toSend->dest);
  fprintf(stdout, "\tAppready: toSend is of frame type ");
	    printFRAMEKIND(toSend->type);
	    fprintf(stdout, "\n");

  toSend->checksum = CNET_crc32((unsigned char *)&toSend, sizeof(toSend));
  
  fprintf(stdout, "\t%s: Generated message for % " PRId32
	",\n\t attempting to transmit\n",nodeinfo.nodename,
	toSend->dest);    
	
	
	  CHECK(CNET_disable_application(ALLNODES));
	transmit(toSend);
	


  if(toSend->type != NL_DATA)
  {
    fprintf(stderr, "\t%s toSend is not DATA!\n",nodeinfo.nodename);
    exit(0);
  }
  
 // CNET_start_timer(EV_TIMER2, 1, 0);

  nextframetosend = 1-nextframetosend; 
  fprintf(stdout, "\tPacket transmitted successfully.\n");
}

///Event Handler
///Creates a new probe packet and sends it to transmit for propagation.
///This packet is used to discover access points and find an appropriate one
///for association.
///It then starts a timer to ensure that if there is no response, an additional
///probe is sent after a period of time.
///The timer is stopped once an acknowledgement is received and the mobile device
///is considered 'associated' with an access point.
static EVENT_HANDLER(probe)
{
  probe_timer = CNET_start_timer(EV_TIMER3, 5000000, 0);
  fprintf(stdout, "\n%s Probing...\n", nodeinfo.nodename);
  
  struct nl_packet packet = (struct nl_packet){
    .src = nodeinfo.address,
    .length = NL_MAXDATA,
  };
  memcpy(packet.data,nodeinfo.nodename,sizeof(nodeinfo.nodename));   
  packet.type = NL_PROBE;
  packet.checksum = CNET_crc32((unsigned char *)&packet, sizeof(packet));
  
  //create broadcast address
  CnetNICaddr wifi_dest;
  CHECK(CNET_parse_nicaddr(wifi_dest, "ff:ff:ff:ff:ff:ff"));
  uint16_t packet_length = NL_PACKET_LENGTH(packet);

  CHECK(CNET_disable_application(ALLNODES));
  dll_wifi_write(dll_states[1], wifi_dest, (char *)&packet, packet_length);

}


static EVENT_HANDLER(timeouts)
{
    printf("timeout, seq=%d\n", ackexpected);
    transmit(toSend); 
}