Exemple #1
0
int mote_main(void) {
   board_init();
   scheduler_init();
   openstack_init();
   if (idmanager_getMyID(ADDR_64B)->addr_64b[7]==0xbb) {
      idmanager_setIsDAGroot(TRUE);
   }
   scheduler_start();
   return 0; // this line should never be reached
}
Exemple #2
0
owerror_t openserial_printStatus(uint8_t statusElement,uint8_t* buffer, uint8_t length) {
   uint8_t i;
   INTERRUPT_DECLARATION();
   
   DISABLE_INTERRUPTS();
   openserial_vars.outputBufFilled  = TRUE;
   outputHdlcOpen();
   outputHdlcWrite(SERFRAME_MOTE2PC_STATUS);
   outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]);
   outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]);
   outputHdlcWrite(statusElement);
   for (i=0;i<length;i++){
      outputHdlcWrite(buffer[i]);
   }
   outputHdlcClose();
   ENABLE_INTERRUPTS();
   
   return E_SUCCESS;
}
Exemple #3
0
void construct_demo(demo_t* data) {
    data->start  = COMPONENT_BBK;
        data->id = idmanager_getMyID(ADDR_16B)->addr_16b[1];
        data->seq[0] = (uint8_t)((bbk_vars.sequence & 0xff000000)>>24);
        data->seq[1] = (uint8_t)((bbk_vars.sequence & 0x00ff0000)>>16);
        data->seq[2] = (uint8_t)((bbk_vars.sequence & 0x0000ff00)>>8);
        data->seq[3] = (uint8_t)(bbk_vars.sequence & 0x00000000ff);
        
        data->channel = 0xab;
        data->retry = 0xcd;
    data->end    = 0x99;
}
Exemple #4
0
owerror_t openserial_printStatus(
    uint8_t             statusElement,
    uint8_t*            buffer,
    uint8_t             length
) {
    uint8_t i;

    outputHdlcOpen();
    outputHdlcWrite(SERFRAME_MOTE2PC_STATUS);
    outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]);
    outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]);
    outputHdlcWrite(statusElement);
    for (i=0;i<length;i++){
        outputHdlcWrite(buffer[i]);
    }
    outputHdlcClose();

    // start TX'ing
    openserial_flush();

    return E_SUCCESS;
}
Exemple #5
0
error_t openserial_printStatus(uint8_t statusElement,uint8_t* buffer, uint16_t length) {
    uint8_t counter;
    INTERRUPT_DECLARATION();
    DISABLE_INTERRUPTS();

    openserial_vars.somethingInOutputBuffer=TRUE;
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)'^';                  //preamble
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)'^';
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)'^';
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)'S';                  //this is an status update
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)((idmanager_getMyID(ADDR_16B))->addr_16b[1]);
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)((idmanager_getMyID(ADDR_16B))->addr_16b[0]);
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)statusElement;        //type of element
    for (counter=0; counter<length; counter++) {
        openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)buffer[counter];
    }
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)'$';                  //postamble
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)'$';
    openserial_vars.output_buffer[output_buffer_index_write_increment()]=(uint8_t)'$';
    ENABLE_INTERRUPTS();

    return E_SUCCESS;
}
Exemple #6
0
/**
\brief Receive a frame at the openbridge, which sends it out over serial.
*/
void openbridge_receive(OpenQueueEntry_t* msg) {
   
   // prepend previous hop
   packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b);
   memcpy(msg->payload,msg->l2_nextORpreviousHop.addr_64b,LENGTH_ADDR64b);
   
   // prepend next hop (me)
   packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b);
   memcpy(msg->payload,idmanager_getMyID(ADDR_64B)->addr_64b,LENGTH_ADDR64b);
   
   // send packet over serial (will be memcopied into serial buffer)
   openserial_printData((uint8_t*)(msg->payload),msg->length);
   
   // free packet
   openqueue_freePacketBuffer(msg);
}
Exemple #7
0
/**
\brief Timer handlers which triggers MAC management task.

This function is called in task context by the scheduler after the RES timer
has fired. This timer is set to fire every second, on average.

The body of this function executes one of the MAC management task.
*/
void timers_res_fired() {
   res_vars.MacMgtTaskCounter = (res_vars.MacMgtTaskCounter+1)%2;
   if (idmanager_getMyID(ADDR_16B)->addr_16b[1]==DEBUG_MOTEID_MASTER) {
      if (res_vars.MacMgtTaskCounter==0) {
         sendAdv();
      } else {
         // don't send KAs if you're the master
      }
   } else {
      if (res_vars.MacMgtTaskCounter==0) {
          sendAdv();
         // don't send ADVs if you're not the master
      } else {
         sendKa();
      }
   }
}
bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) {
#ifdef FORCETOPOLOGY
	bool returnVal;
	returnVal=FALSE;
	uint16_t my_addr = idmanager_getMyID(ADDR_64B)->addr_64b[7] | (idmanager_getMyID(ADDR_64B)->addr_64b[6] << 8);
	uint16_t src_addr = ieee802514_header->src.addr_64b[7] | (ieee802514_header->src.addr_64b[6] << 8);
	switch (my_addr) {
		case 0x0001:
			if (
				src_addr==0x0002||
				src_addr==0x0003||
				src_addr==0x0004||
				src_addr==0x0005||
				src_addr==0x0006||
				src_addr==0x0007||
				src_addr==0x0008||
				src_addr==0x0009||
				src_addr==0x000a||
				src_addr==0x000b||
				src_addr==0x000c||
				src_addr==0x000d||
				src_addr==0x000e||
				src_addr==0x000f||
				src_addr==0x0011||
				src_addr==0x0013||
				src_addr==0x001d||
				src_addr==0x001f||
				src_addr==0x0020
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0002:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0003:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0004:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0005:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0006:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0007:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0008:
			if (
				src_addr==0x0001||
				src_addr==0x0016||
				src_addr==0x0018||
				src_addr==0x001a
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0009:
			if (
				src_addr==0x0001||
				src_addr==0x001b||
				src_addr==0x001c
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000a:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000b:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000c:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000d:
			if (
				src_addr==0x0001||
				src_addr==0x0017
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000e:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000f:
			if (
				src_addr==0x0001||
				src_addr==0x0015||
				src_addr==0x002b||
				src_addr==0x002d
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0010:
			if (
				src_addr==0x0020
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0011:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0012:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0013:
			if (
				src_addr==0x0001||
				src_addr==0x0014||
				src_addr==0x0019
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0014:
			if (
				src_addr==0x0013
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0015:
			if (
				src_addr==0x000f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0016:
			if (
				src_addr==0x0008
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0017:
			if (
				src_addr==0x000d
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0018:
			if (
				src_addr==0x0008
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0019:
			if (
				src_addr==0x0013
			) {
			returnVal=TRUE;
		}
		break;
		case 0x001a:
			if (
				src_addr==0x0008
			) {
			returnVal=TRUE;
		}
		break;
		case 0x001b:
			if (
				src_addr==0x0009
			) {
			returnVal=TRUE;
		}
		break;
		case 0x001c:
			if (
				src_addr==0x0009
			) {
			returnVal=TRUE;
		}
		break;
		case 0x001d:
			if (
				src_addr==0x0001||
				src_addr==0x002a
			) {
			returnVal=TRUE;
		}
		break;
		case 0x001e:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x001f:
			if (
				src_addr==0x0001||
				src_addr==0x0012||
				src_addr==0x001e||
				src_addr==0x0023||
				src_addr==0x0024||
				src_addr==0x0025||
				src_addr==0x0026||
				src_addr==0x0027||
				src_addr==0x0028||
				src_addr==0x0029
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0020:
			if (
				src_addr==0x0001||
				src_addr==0x0010||
				src_addr==0x0021||
				src_addr==0x0022
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0021:
			if (
				src_addr==0x0020
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0022:
			if (
				src_addr==0x0020
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0023:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0024:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0025:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0026:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0027:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0028:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0029:
			if (
				src_addr==0x001f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x002a:
			if (
				src_addr==0x001d
			) {
			returnVal=TRUE;
		}
		break;
		case 0x002b:
			if (
				src_addr==0x000f||
				src_addr==0x002c
			) {
			returnVal=TRUE;
		}
		break;
		case 0x002c:
			if (
				src_addr==0x002b
			) {
			returnVal=TRUE;
		}
		break;
		case 0x002d:
			if (
				src_addr==0x000f
			) {
			returnVal=TRUE;
		}
		break;
	}
	return returnVal;
#else
	return TRUE;
#endif
}
Exemple #9
0
void ieee802154_prependHeader(OpenQueueEntry_t* msg,
                              uint8_t           frameType,
                              bool              securityEnabled,
                              uint8_t           sequenceNumber,
                              open_addr_t*      nextHop) {
   uint8_t temp_8b;
   //previousHop address (always 64-bit)
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),LITTLE_ENDIAN);
   // poipoi: using 16-bit source address
   //packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_16B),LITTLE_ENDIAN);
   //nextHop address
   if (packetfunctions_isBroadcastMulticast(nextHop)) { //broadcast address is always 16-bit
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
   } else {
      // poipoi: using 16-bit destination address
//      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
//      *((uint8_t*)(msg->payload)) = nextHop->addr_64b[6];
//      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
//      *((uint8_t*)(msg->payload)) = nextHop->addr_64b[7];
//      
      switch (nextHop->type) {
         case ADDR_16B:
         case ADDR_64B:
            packetfunctions_writeAddress(msg,nextHop,LITTLE_ENDIAN);
            break;
         default:
            openserial_printError(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE,
                                  (errorparameter_t)nextHop->type,
                                  (errorparameter_t)1);
      }
      
   }
   //destpan
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),LITTLE_ENDIAN);
   //dsn
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = sequenceNumber;
   //fcf (2nd byte)
   temp_8b              = 0;
   // poipoi: 16-bit source/dest addresses
  // temp_8b             |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   //temp_8b             |= IEEE154_ADDR_SHORT              << IEEE154_FCF_SRC_ADDR_MODE;
   
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
            temp_8b    |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         case ADDR_64B:
            temp_8b    |= IEEE154_ADDR_EXT                << IEEE154_FCF_DEST_ADDR_MODE;
            break;
      }
   }
   temp_8b             |= IEEE154_ADDR_EXT                << IEEE154_FCF_SRC_ADDR_MODE;
   
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = temp_8b;
   //fcf (1st byte)
   temp_8b              = 0;
   temp_8b             |= frameType                       << IEEE154_FCF_FRAME_TYPE;
   temp_8b             |= securityEnabled                 << IEEE154_FCF_SECURITY_ENABLED;
   temp_8b             |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING;
   if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ACK_NO_ACK_REQ          << IEEE154_FCF_ACK_REQ;
   } else {
      temp_8b          |= IEEE154_ACK_YES_ACK_REQ         << IEEE154_FCF_ACK_REQ;
   }
   temp_8b             |= IEEE154_PANID_COMPRESSED        << IEEE154_FCF_INTRAPAN;
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = temp_8b;
}
Exemple #10
0
void openrandom_init() {
   // seed the random number generator with the last 2 bytes of the MAC address
   random_vars.shift_reg  = 0;
   random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[0]*256;
   random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[1];
}
Exemple #11
0
void security_incomingFrame(OpenQueueEntry_t*      msg){
	uint8_t match;

	//open_addr_t* panid;
	uint32_t tempfr;
	tempfr = m_macFrameCounter;

	//panid = &tempheader->panid;

	m_deviceDescriptor			*devpoint;
	m_keyDescriptor 			*keypoint;
	m_securityLevelDescriptor	*secLevel;

	//check that Security Level is not zero, impossible for me
	/*if(msg->securityLevel == ASH_SLF_TYPE_NOSEC){
		return;
	}*/

	//f key descriptor lookup

	match = keyDescriptorLookup(msg->l2_keyIdMode,
								&msg->l2_keySource,
								msg->l2_keyIndex,
								&msg->l2_nextORpreviousHop,
								//panid,
								msg->l2_frameType);

	keypoint = &MacKeyTable.KeyDescriptorElement[match];

	if(match == 25){
		msg->l2_toDiscard = TRUE;
		return;
	}

	//g device descriptor lookup

	open_addr_t Address;
	Address = msg->l2_nextORpreviousHop;
	if(msg->l2_keyIdMode == 0){
	  	if(neighbors_haveSomeChild() == TRUE){
	  		Address = *(idmanager_getMyID(ADDR_64B));
	  		}
	  }

	match = deviceDescriptorLookup(&Address,
						   	       //idmanager_getMyID(ADDR_PANID);
						   	   	   keypoint);


	devpoint = &MacDeviceTable.DeviceDescriptorEntry[match];

	//h Security Level lookup

	secLevel = securityLevelDescriptorLookup(msg->l2_frameType,
								  	  	  	 0,//msg->commandFrameIdentifier,
								  	  	  	 secLevel);


	//i+j+k

	if(incomingSecurityLevelChecking(secLevel,msg->l2_securityLevel,devpoint->Exempt)==FALSE){
		//return;
	}

	//l+m Anti-Replay



	if(msg->l2_frameCounter < devpoint->FrameCounter){
		msg->l2_toDiscard = TRUE;
	}

	//n Control of key used
	if(incomingKeyUsagePolicyChecking(keypoint,
									  msg->l2_frameType,
									  0
									  )  ==FALSE){
		//return; // improper key used
	}

	uint8_t i;
	for(i=0; i<8; i++){
		 nonce[i] = msg->l2_keySource.addr_64b[i];
	}

	uint32_t temp;
	temp = msg->l2_frameCounter;

	nonce[8] = temp;
	nonce[9] = temp << 8;
	nonce[10] = temp <<16;
	nonce[11] = temp <<24;
	nonce[12] = msg->l2_securityLevel;

	//CCMstarInverse(msg,keypoint->key);

	//q increment frame counter and save
	msg->l2_frameCounter +=1;

	//showing MACkeyTable content
	/*if(idmanager_getIsDAGroot() == TRUE){
		for(i=0;i<10;i++){
			openserial_printError(COMPONENT_RES,ERR_OK,
									(errorparameter_t)MacKeyTable.KeyDescriptorElement[i].key,
									(errorparameter_t)i);
		}
	}*/

	devpoint->FrameCounter = msg->l2_frameCounter;
	m_macFrameCounter = tempfr;

}
Exemple #12
0
//update neighbors_vars.myDAGrank and neighbor preference
void neighbors_updateMyDAGrankAndNeighborPreference() {
   uint8_t   i;
   uint8_t   temp_linkCost;
   uint32_t  temp_myTentativeDAGrank; //has to be 16bit so that the sum can be larger than 255 "CHANGED BY Ahmad to be 32 bits since the DAGrank is 16 bits now", so the sum will be >(0xFFFF)
   uint8_t   temp_preferredParentRow=0;
   bool      temp_preferredParentExists=FALSE;
   if ((idmanager_getIsDAGroot())==FALSE) {
      neighbors_vars.myDAGrank=0xffff;
      i=0;
      while(i<MAXNUMNEIGHBORS) {
         neighbors_vars.neighbors[i].parentPreference=0;
         //poipoi xv
         if (neighbors_vars.neighbors[i].used==TRUE /*&& neighbors_vars.neighbors[i].stableNeighbor==TRUE*/) {
            if (neighbors_vars.neighbors[i].numTxACK==0) {
               temp_linkCost=15; //TODO: evaluate using RSSI?
            } else {
               temp_linkCost=(uint8_t)((((float)neighbors_vars.neighbors[i].numTx)/((float)neighbors_vars.neighbors[i].numTxACK))*10.0);
            }
            temp_myTentativeDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
           //poipoi xv -- avoiding dynamic routing...
            if (idmanager_getIsDAGroot()==FALSE && temp_myTentativeDAGrank<neighbors_vars.myDAGrank && temp_myTentativeDAGrank<0xffff) {
               
              neighbors_vars.myDAGrank=temp_myTentativeDAGrank;
              temp_preferredParentExists=TRUE;
              temp_preferredParentRow=i;
            }
               //the following is equivalent to manual routing 
#ifdef FORCE_MULTIHOP   
#ifdef GINA_FORCE_MULTIHOP   
            
               //   below to enforce the routing 
               switch ((idmanager_getMyID(ADDR_64B))->addr_64b[7]) {
               case 0x9B:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xDC) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               case 0xDC:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xD8) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               case 0xC9:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xED) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               case 0xD8:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xC9) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               default:
               break;
               }
          
#endif
#ifdef TELOSB_FORCE_MULTIHOP   
            
               //   below to enforce the routing 
               switch ((idmanager_getMyID(ADDR_64B))->addr_64b[7]) {
               case 0x51:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xB9) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               case 0x41:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0x51) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               case 0x80:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0x41) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               case 0xE1:
               if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0x80) {
               neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost;
               temp_preferredParentExists=TRUE;
               temp_preferredParentRow=i;
               }
               break;
               default:
               break;
               }
          
#endif            
#endif
            
         }
         i++;
      }
      if (temp_preferredParentExists) {
         neighbors_vars.neighbors[temp_preferredParentRow].parentPreference=MAXPREFERENCE;
         neighbors_vars.neighbors[temp_preferredParentRow].stableNeighbor=TRUE;
         neighbors_vars.neighbors[temp_preferredParentRow].switchStabilityCounter = 0;
         
      }
   } else {
      neighbors_vars.myDAGrank=0;
   }
}
Exemple #13
0
/* piggy902: addr-specific schedule */ 
void schedule_init() {
   uint8_t     i;
   open_addr_t temp_neighbor;

   // reset local variables
   memset(&schedule_vars,0,sizeof(schedule_vars_t));
   memset(&schedule_dbg, 0,sizeof(schedule_dbg_t));
   for (i=0;i<MAXACTIVESLOTS;i++){
      schedule_resetEntry(&schedule_vars.scheduleBuf[i]);
   }

   // set frame length
   schedule_setFrameLength(11);

   // slot 0 is advertisement slot
   i = 0;
   memset(&temp_neighbor,0,sizeof(temp_neighbor));
   schedule_addActiveSlot(i,
         CELLTYPE_ADV,
         FALSE,
         0,
         &temp_neighbor);
   
    switch(idmanager_getMyID(ADDR_16B)->addr_16b[1]){
    case DEBUG_MOTEID_MASTER:
       // slot 1 is shared TXRX, but with specific neighbour rather than anycast
       i = 1;
       memset(&temp_neighbor,0,sizeof(temp_neighbor));
       temp_neighbor.type             = ADDR_64B;
       temp_neighbor.addr_64b[6]    = 0xED;
       temp_neighbor.addr_64b[7]    = DEBUG_MOTEID_2;
       schedule_addActiveSlot(i,
             CELLTYPE_TXRX,
             FALSE,
             0,
             &temp_neighbor);
       
       // slot 2 is shared TXRX, but with specific neighbour rather than anycast
       i = 2;
       memset(&temp_neighbor,0,sizeof(temp_neighbor));
       schedule_addActiveSlot(i,
             CELLTYPE_MORESERIALRX,
             FALSE,
             0,
             &temp_neighbor); 
       
       i = 3;
       memset(&temp_neighbor,0,sizeof(temp_neighbor));
       schedule_addActiveSlot(i,
             CELLTYPE_MORESERIALRX,
             FALSE,
             0,
             &temp_neighbor);
        break;
        
    case DEBUG_MOTEID_2:
       // slot 1 is shared TXRX, but with specific neighbour rather than anycast
       i = 1;
       memset(&temp_neighbor,0,sizeof(temp_neighbor));
       temp_neighbor.type             = ADDR_64B;
       temp_neighbor.addr_64b[6]    = 0xED;
       temp_neighbor.addr_64b[7]    = DEBUG_MOTEID_MASTER;
       schedule_addActiveSlot(i,
             CELLTYPE_TXRX,
             FALSE,
             0,
             &temp_neighbor);
     
       i = 2;
       memset(&temp_neighbor,0,sizeof(temp_neighbor));
       schedule_addActiveSlot(i,
             CELLTYPE_MORESERIALRX,
             FALSE,
             0,
             &temp_neighbor);
    
       i = 3;
       memset(&temp_neighbor,0,sizeof(temp_neighbor));
       schedule_addActiveSlot(i,
             CELLTYPE_MORESERIALRX,
             FALSE,
             0,
             &temp_neighbor); 
        break;
        
    default:
        break;
   }
   
   // slot 4 is SERIALRX
   i = 4;
   memset(&temp_neighbor,0,sizeof(temp_neighbor));
   schedule_addActiveSlot(i,
         CELLTYPE_SERIALRX,
         FALSE,
         0,
         &temp_neighbor);

   // slot 5 is MORESERIALRX
   i = 5;
   memset(&temp_neighbor,0,sizeof(temp_neighbor));
   schedule_addActiveSlot(i,
         CELLTYPE_MORESERIALRX,
         FALSE,
         0,
         &temp_neighbor);
   
   // Noise Floor Probe
   i = 6; 
   memset(&temp_neighbor,0,sizeof(temp_neighbor));
   schedule_addActiveSlot(i,
         CELLTYPE_NF,
         FALSE,
         0,
         &temp_neighbor);
   
   i = 7; 
   memset(&temp_neighbor,0,sizeof(temp_neighbor));
   schedule_addActiveSlot(i,
         CELLTYPE_NF,
         FALSE,
         0,
         &temp_neighbor);
   
   //for RPL DIOs?
   i = 8;
   memset(&temp_neighbor,0,sizeof(temp_neighbor));
   temp_neighbor.type             = ADDR_64B;
   temp_neighbor.addr_64b[0]          = 0xff;
   temp_neighbor.addr_64b[1]          = 0xff;
   temp_neighbor.addr_64b[2]          = 0xff;
   temp_neighbor.addr_64b[3]          = 0xff;
   temp_neighbor.addr_64b[4]          = 0xff;
   temp_neighbor.addr_64b[5]          = 0xff;
   temp_neighbor.addr_64b[6]          = 0xff;
   temp_neighbor.addr_64b[7]          = 0xff;
   schedule_addActiveSlot(i,
         CELLTYPE_TXRX,
         FALSE,
         0,
         &temp_neighbor);
}
Exemple #14
0
/**
\brief Send a packet using the source rout to find the next hop.

\note This is always called for packets being forwarded.

How to process the routing header is detailed in
http://tools.ietf.org/html/rfc6554#page-9.

\param[in,out] msg             The packet to send.
\param[in]     ipv6_header     The packet's IPv6 header.
*/
owerror_t forwarding_send_internal_SourceRouting(OpenMote* self, 
    OpenQueueEntry_t* msg,
    ipv6_header_iht*  ipv6_outer_header,
    ipv6_header_iht*  ipv6_inner_header,
    rpl_option_ht*    rpl_option
    ) {
    uint8_t              temp_8b;
    uint8_t              type;
    uint8_t              next_type;
    uint8_t              size;
    uint8_t              next_size;
    uint8_t              hlen;
    open_addr_t          firstAddr;
    open_addr_t          nextAddr;
    open_addr_t          temp_prefix;
    open_addr_t          temp_addr64;
    
    uint8_t              rpi_length;
    uint8_t              flags;
    uint16_t             senderRank;
    
    uint8_t              RH3_copy[127];
    uint8_t              RH3_length;
    
    memset(&RH3_copy[0],0,127);
    RH3_length = 0;
    memcpy(&msg->l3_destinationAdd,&ipv6_inner_header->dest,sizeof(open_addr_t));
    memcpy(&msg->l3_sourceAdd,&ipv6_inner_header->src,sizeof(open_addr_t));
    
    // initial first Address by compression reference
    firstAddr.type = ADDR_128B;
    if (ipv6_outer_header->src.type != ADDR_NONE){
        if (rpl_option->rplInstanceID == 0){
 icmpv6rpl_getRPLDODAGid(self, &firstAddr.addr_128b[0]);
        }
    } else {
        memcpy(&firstAddr,&ipv6_inner_header->src,sizeof(open_addr_t));
    }
    
    hlen = 0;
    
    temp_8b = *((uint8_t*)(msg->payload)+hlen);
    type    = *((uint8_t*)(msg->payload)+hlen+1);
    
    hlen += 2;
    // get the first address
    switch(type){
    case RH3_6LOTH_TYPE_0:
        memcpy(&firstAddr.addr_128b[15],msg->payload+hlen,1);
        hlen += 1;
        break;
    case RH3_6LOTH_TYPE_1:
        memcpy(&firstAddr.addr_128b[14],msg->payload+hlen,2);
        hlen += 2;
        break;
    case RH3_6LOTH_TYPE_2:
        memcpy(&firstAddr.addr_128b[12],msg->payload+hlen,4);
        hlen += 4;
        break;
    case RH3_6LOTH_TYPE_3:
        memcpy(&firstAddr.addr_128b[8],msg->payload+hlen,8);
        hlen += 8;
        break;
    case RH3_6LOTH_TYPE_4:
        memcpy(&firstAddr.addr_128b[0],msg->payload+hlen,16);
        hlen += 16;
        break;
    }
    
 packetfunctions_ip128bToMac64b(self, &firstAddr,&temp_prefix,&temp_addr64);
    if (
 packetfunctions_sameAddress(self, &temp_prefix, idmanager_getMyID(self, ADDR_PREFIX)) &&
 packetfunctions_sameAddress(self, &temp_addr64, idmanager_getMyID(self, ADDR_64B))
    ){
        size = temp_8b & RH3_6LOTH_SIZE_MASK;
        if (size > 0){
            // there are at least 2 entries in the header, 
            // the router removes the first entry and decrements the Size (by 1) 
            size -= 1;
 packetfunctions_tossHeader(self, msg,hlen);
 packetfunctions_reserveHeaderSize(self, msg,2);
            msg->payload[0] = CRITICAL_6LORH | size;
            msg->payload[1] = type;
            // get next hop
            memcpy(&nextAddr,&firstAddr,sizeof(open_addr_t));
            switch(type){
            case RH3_6LOTH_TYPE_0:
                memcpy(&nextAddr.addr_128b[15],msg->payload+2,1);
                break;
            case RH3_6LOTH_TYPE_1:
                memcpy(&nextAddr.addr_128b[14],msg->payload+2,2);
                break;
            case RH3_6LOTH_TYPE_2:
                memcpy(&nextAddr.addr_128b[12],msg->payload+2,4);
                break;
            case RH3_6LOTH_TYPE_3:
                memcpy(&nextAddr.addr_128b[8],msg->payload+2,8);
                break;
            case RH3_6LOTH_TYPE_4:
                memcpy(&nextAddr.addr_128b[0],msg->payload+2,16);
                break;
            }
 packetfunctions_ip128bToMac64b(self, 
                &nextAddr,
                &temp_prefix,
                &msg->l2_nextORpreviousHop
            );
        } else {
            temp_8b   = *((uint8_t*)(msg->payload)+hlen);
            next_type = *((uint8_t*)(msg->payload)+hlen+1);
            if (
                (temp_8b & FORMAT_6LORH_MASK) == CRITICAL_6LORH &&
                next_type<=RH3_6LOTH_TYPE_4
            ) {
                // there is another RH3-6LoRH following, check the type
                if (next_type >= type){
 packetfunctions_tossHeader(self, msg,hlen);
                    // get next hop
                    memcpy(&nextAddr,&firstAddr,sizeof(open_addr_t));
                    switch(next_type){
                    case RH3_6LOTH_TYPE_0:
                        memcpy(&nextAddr.addr_128b[15],msg->payload+2,1);
                        break;
                    case RH3_6LOTH_TYPE_1:
                        memcpy(&nextAddr.addr_128b[14],msg->payload+2,2);
                        break;
                    case RH3_6LOTH_TYPE_2:
                        memcpy(&nextAddr.addr_128b[12],msg->payload+2,4);
                        break;
                    case RH3_6LOTH_TYPE_3:
                        memcpy(&nextAddr.addr_128b[8],msg->payload+2,8);
                        break;
                    case RH3_6LOTH_TYPE_4:
                        memcpy(&nextAddr.addr_128b[0],msg->payload+2,16);
                        break;
                    }
 packetfunctions_ip128bToMac64b(self, 
                        &nextAddr,
                        &temp_prefix,
                        &msg->l2_nextORpreviousHop
                    );
                } else {
                    hlen += 2;
                    switch(next_type){
                    case RH3_6LOTH_TYPE_0:
                        memcpy(&firstAddr.addr_128b[15],msg->payload+hlen,1);
                        hlen += 1;
                        break;
                    case RH3_6LOTH_TYPE_1:
                        memcpy(&firstAddr.addr_128b[14],msg->payload+hlen,2);
                        hlen += 2;
                        break;
                    case RH3_6LOTH_TYPE_2:
                        memcpy(&firstAddr.addr_128b[12],msg->payload+hlen,4);
                        hlen += 4;
                        break;
                    case RH3_6LOTH_TYPE_3:
                        memcpy(&firstAddr.addr_128b[8],msg->payload+hlen,8);
                        hlen += 8;
                        break;
                    }
                    next_size = temp_8b & RH3_6LOTH_SIZE_MASK;
 packetfunctions_tossHeader(self, msg,hlen);
                    if (next_size>0){
                        next_size -= 1;
 packetfunctions_reserveHeaderSize(self, msg,2);
                        msg->payload[0] = CRITICAL_6LORH | next_size;
                        msg->payload[1] = next_type;
                    }
                    // add first address
                    switch(type){
                    case RH3_6LOTH_TYPE_0:
 packetfunctions_reserveHeaderSize(self, msg,1);
                        msg->payload[0] = firstAddr.addr_128b[15];
                        break;
                    case RH3_6LOTH_TYPE_1:
 packetfunctions_reserveHeaderSize(self, msg,2);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[14],2);
                        break;
                    case RH3_6LOTH_TYPE_2:
 packetfunctions_reserveHeaderSize(self, msg,4);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[12],4);
                        break;
                    case RH3_6LOTH_TYPE_3:
 packetfunctions_reserveHeaderSize(self, msg,8);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[8],8);
                        break;
                    case RH3_6LOTH_TYPE_4:
 packetfunctions_reserveHeaderSize(self, msg,16);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[0],16);
                        break;
                    }
 packetfunctions_reserveHeaderSize(self, msg,2);
                    msg->payload[0] = CRITICAL_6LORH | 0;
                    msg->payload[1] = type;
 packetfunctions_ip128bToMac64b(self, 
                        &firstAddr,
                        &temp_prefix,
                        &msg->l2_nextORpreviousHop
                    );
                }
            } else {
                // there is no next RH3-6loRH, remove current one
 packetfunctions_tossHeader(self, msg,hlen);
 packetfunctions_ip128bToMac64b(self, 
                    &msg->l3_destinationAdd,
                    &temp_prefix,
                    &msg->l2_nextORpreviousHop
                );
            }
        }
    } else {
        // log error
 openserial_printError(self, 
            COMPONENT_IPHC,
            ERR_6LOWPAN_UNSUPPORTED,
            (errorparameter_t)16,
            (errorparameter_t)(temp_addr64.addr_64b[7])
        );
    }
    // copy RH3s before toss them
    if (
        ipv6_outer_header->src.type != ADDR_NONE &&
        ipv6_outer_header->hopByhop_option != NULL
    ){
        // check the length of RH3s
        RH3_length = ipv6_outer_header->hopByhop_option-msg->payload;
        memcpy(&RH3_copy[0],msg->payload,RH3_length);
 packetfunctions_tossHeader(self, msg,RH3_length);
        
        // retrieve hop-by-hop header (includes RPL option)
        rpi_length = iphc_retrieveIPv6HopByHopHeader(self, 
                          msg,
                          rpl_option
                     );
     
        // toss the headers
 packetfunctions_tossHeader(self, 
            msg,
            rpi_length
        );
      
        flags = rpl_option->flags;
        senderRank = rpl_option->senderRank;
        if ((flags & O_FLAG)!=O_FLAG){
            // wrong direction
            // log error
 openserial_printError(self, 
                COMPONENT_FORWARDING,
                ERR_WRONG_DIRECTION,
                (errorparameter_t)flags,
                (errorparameter_t)senderRank
            );
        }
        if (senderRank > neighbors_getMyDAGrank(self)){
            // loop detected
            // set flag
            rpl_option->flags |= R_FLAG;
            // log error
 openserial_printError(self, 
                COMPONENT_FORWARDING,
                ERR_LOOP_DETECTED,
                (errorparameter_t) senderRank,
                (errorparameter_t) neighbors_getMyDAGrank(self)
            );
        }
 forwarding_createRplOption(self, rpl_option, rpl_option->flags);
        // toss the IP in IP 6LoRH
 packetfunctions_tossHeader(self, msg, ipv6_outer_header->header_length);
    } else {
        RH3_length = 0;
    }
    
    // send to next lower layer
    return iphc_sendFromForwarding(self, 
        msg,
        ipv6_outer_header,
        ipv6_inner_header,
        rpl_option,
        &ipv6_outer_header->flow_label,
        &RH3_copy[0],
        RH3_length,
        PCKTFORWARD
    );
}
Exemple #15
0
/**
\brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet.

Note that we are writing the field from the end of the header to the beginning.

\param[in,out] msg              The message to append the header to.
\param[in]     frameType        Type of IEEE802.15.4 frame.
\param[in]     ielistpresent    Is the IE list present¿
\param[in]     frameVersion     IEEE802.15.4 frame version.
\param[in]     securityEnabled  Is security enabled on this frame?
\param[in]     sequenceNumber   Sequence number of this frame.
\param[in]     nextHop          Address of the next hop
*/
void ieee802154_prependHeader(OpenQueueEntry_t* msg,
                              uint8_t           frameType,
                              uint8_t           ielistpresent,
                              uint8_t           frameVersion,
                              bool              securityEnabled,
                              uint8_t           sequenceNumber,
                              open_addr_t*      nextHop) {
   uint8_t temp_8b;
   
   //General IEs here (those that are carried in all packets) -- None by now.
   
   // previousHop address (always 64-bit)
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),OW_LITTLE_ENDIAN);
   // nextHop address
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      //broadcast address is always 16-bit
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
         case ADDR_64B:
            packetfunctions_writeAddress(msg,nextHop,OW_LITTLE_ENDIAN);
            break;
         default:
            openserial_printCritical(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE,
                                  (errorparameter_t)nextHop->type,
                                  (errorparameter_t)1);
      }
      
   }
   // destpan
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),OW_LITTLE_ENDIAN);
   //dsn
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = sequenceNumber;
   //fcf (2nd byte)
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   temp_8b              = 0;
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
            temp_8b    |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         case ADDR_64B:
            temp_8b    |= IEEE154_ADDR_EXT                << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         // no need for a default, since it would have been caught above.
      }
   }
   temp_8b             |= IEEE154_ADDR_EXT                << IEEE154_FCF_SRC_ADDR_MODE;
   //poipoi xv IE list present
   temp_8b             |= ielistpresent                   << IEEE154_FCF_IELIST_PRESENT;
   temp_8b             |= frameVersion                    << IEEE154_FCF_FRAME_VERSION;
     
   *((uint8_t*)(msg->payload)) = temp_8b;
   //fcf (1st byte)
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   temp_8b              = 0;
   temp_8b             |= frameType                       << IEEE154_FCF_FRAME_TYPE;
   temp_8b             |= securityEnabled                 << IEEE154_FCF_SECURITY_ENABLED;
   temp_8b             |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING;
   if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ACK_NO_ACK_REQ          << IEEE154_FCF_ACK_REQ;
   } else {
      temp_8b          |= IEEE154_ACK_YES_ACK_REQ         << IEEE154_FCF_ACK_REQ;
   }
   temp_8b             |= IEEE154_PANID_COMPRESSED        << IEEE154_FCF_INTRAPAN;
   *((uint8_t*)(msg->payload)) = temp_8b;
}
bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) {
#ifdef FORCETOPOLOGY
	bool returnVal;
	returnVal=FALSE;
	uint16_t my_addr = idmanager_getMyID(ADDR_64B)->addr_64b[7] | (idmanager_getMyID(ADDR_64B)->addr_64b[6] << 8);
	uint16_t src_addr = ieee802514_header->src.addr_64b[7] | (ieee802514_header->src.addr_64b[6] << 8);
	switch (my_addr) {
		case 0x0001:
			if (
				src_addr==0x0002||
				src_addr==0x0003||
				src_addr==0x0004||
				src_addr==0x0005||
				src_addr==0x0006||
				src_addr==0x0007||
				src_addr==0x0008||
				src_addr==0x0009||
				src_addr==0x000a||
				src_addr==0x000b||
				src_addr==0x000c||
				src_addr==0x000d||
				src_addr==0x000e||
				src_addr==0x000f
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0002:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0003:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0004:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0005:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0006:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0007:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0008:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x0009:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000a:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000b:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000c:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000d:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000e:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
		case 0x000f:
			if (
				src_addr==0x0001
			) {
			returnVal=TRUE;
		}
		break;
	}
	return returnVal;
#else
	return TRUE;
#endif
}
Exemple #17
0
/**
\brief Initialize this module.
*/
void icmpv6rpl_init() {
   uint8_t         dodagid[16];
   uint32_t        dioPeriod;
   uint32_t        daoPeriod;
   
   // retrieve my prefix and EUI64
   memcpy(&dodagid[0],idmanager_getMyID(ADDR_PREFIX)->prefix,8); // prefix
   memcpy(&dodagid[8],idmanager_getMyID(ADDR_64B)->addr_64b,8);  // eui64
   
   //===== reset local variables
   memset(&icmpv6rpl_vars,0,sizeof(icmpv6rpl_vars_t));
   
   //=== admin
   
   icmpv6rpl_vars.busySending               = FALSE;
   icmpv6rpl_vars.fDodagidWritten           = 0;
   
   //=== DIO
   
   icmpv6rpl_vars.dio.rplinstanceId         = 0x00;        ///< TODO: put correct value
   icmpv6rpl_vars.dio.verNumb               = 0x00;        ///< TODO: put correct value
   // rank: to be populated upon TX
   icmpv6rpl_vars.dio.rplOptions            = MOP_DIO_A | \
                                              MOP_DIO_B | \
                                              MOP_DIO_C | \
                                              PRF_DIO_A | \
                                              PRF_DIO_B | \
                                              PRF_DIO_C | \
                                              G_DIO ;
   icmpv6rpl_vars.dio.DTSN                  = 0x33;        ///< TODO: put correct value
   icmpv6rpl_vars.dio.flags                 = 0x00;
   icmpv6rpl_vars.dio.reserved              = 0x00;
   memcpy(
      &(icmpv6rpl_vars.dio.DODAGID[0]),
      dodagid,
      sizeof(icmpv6rpl_vars.dio.DODAGID)
   ); // can be replaced later
   
   icmpv6rpl_vars.dioDestination.type = ADDR_128B;
   memcpy(&icmpv6rpl_vars.dioDestination.addr_128b[0],all_routers_multicast,sizeof(all_routers_multicast));
   
   icmpv6rpl_vars.dioPeriod                 = TIMER_DIO_TIMEOUT;
   dioPeriod                                = icmpv6rpl_vars.dioPeriod - 0x80 + (openrandom_get16b()&0xff);
   icmpv6rpl_vars.timerIdDIO                = opentimers_start(
                                                dioPeriod,
                                                TIMER_PERIODIC,
                                                TIME_MS,
                                                icmpv6rpl_timer_DIO_cb
                                             );
   
   //=== DAO
   
   icmpv6rpl_vars.dao.rplinstanceId         = 0x00;        ///< TODO: put correct value
   icmpv6rpl_vars.dao.K_D_flags             = FLAG_DAO_A   | \
                                              FLAG_DAO_B   | \
                                              FLAG_DAO_C   | \
                                              FLAG_DAO_D   | \
                                              FLAG_DAO_E   | \
                                              PRF_DIO_C    | \
                                              FLAG_DAO_F   | \
                                              D_DAO        |
                                              K_DAO;
   icmpv6rpl_vars.dao.reserved              = 0x00;
   icmpv6rpl_vars.dao.DAOSequence           = 0x00;
   memcpy(
      &(icmpv6rpl_vars.dao.DODAGID[0]),
      dodagid,
      sizeof(icmpv6rpl_vars.dao.DODAGID)
   );  // can be replaced later
   
   icmpv6rpl_vars.dao_transit.type          = OPTION_TRANSIT_INFORMATION_TYPE;
   // optionLength: to be populated upon TX
   icmpv6rpl_vars.dao_transit.E_flags       = E_DAO_Transit_Info;
   icmpv6rpl_vars.dao_transit.PathControl   = PC1_A_DAO_Transit_Info | \
                                              PC1_B_DAO_Transit_Info | \
                                              PC2_A_DAO_Transit_Info | \
                                              PC2_B_DAO_Transit_Info | \
                                              PC3_A_DAO_Transit_Info | \
                                              PC3_B_DAO_Transit_Info | \
                                              PC4_A_DAO_Transit_Info | \
                                              PC4_B_DAO_Transit_Info;  
   icmpv6rpl_vars.dao_transit.PathSequence  = 0x00; // to be incremented at each TX
   icmpv6rpl_vars.dao_transit.PathLifetime  = 0xAA;
   //target information
   icmpv6rpl_vars.dao_target.type  = OPTION_TARGET_INFORMATION_TYPE;
   icmpv6rpl_vars.dao_target.optionLength  = 0;
   icmpv6rpl_vars.dao_target.flags  = 0;
   icmpv6rpl_vars.dao_target.prefixLength = 0;
   
   icmpv6rpl_vars.daoPeriod                 = TIMER_DAO_TIMEOUT;
   daoPeriod                                = icmpv6rpl_vars.daoPeriod - 0x80 + (openrandom_get16b()&0xff);
   icmpv6rpl_vars.timerIdDAO                = opentimers_start(
                                                daoPeriod,
                                                TIMER_PERIODIC,
                                                TIME_MS,
                                                icmpv6rpl_timer_DAO_cb
                                             );
   
}
Exemple #18
0
error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) {
  // It has to be forwarded to dest. so, next hop should be extracted from the message.
  uint8_t local_CmprE;
  uint8_t local_CmprI,numAddr,hlen;
  uint8_t addressposition;
  uint8_t* runningPointer;
  uint8_t octetsAddressSize;
  ipv6_Source_Routing_Header_t * ipv6_Source_Routing_Header;
  
  open_addr_t* prefix=idmanager_getMyID(ADDR_PREFIX);
 
  ipv6_Source_Routing_Header=(ipv6_Source_Routing_Header_t*)(msg->payload);
  
  
  runningPointer=(msg->payload) + sizeof(ipv6_Source_Routing_Header_t);
  
  // getting local_CmprE and CmprI;
  local_CmprE=ipv6_Source_Routing_Header->CmprICmprE & 0xf;
  local_CmprI= ipv6_Source_Routing_Header->CmprICmprE & 0xf0;
  //local_CmprI>>4; // shifting it by 4.
  local_CmprI=local_CmprI>>4; // shifting it by 4.
  
//  foundFlag=0;

    //see processing header algorithm in RFC6554 page 9
    
    numAddr=(((ipv6_Source_Routing_Header->HdrExtLen*8)-ipv6_Source_Routing_Header->PadRes -(16-local_CmprE))/(16-local_CmprI))+1;
  
  if(ipv6_Source_Routing_Header->SegmentsLeft==0){
    //we are there!..
    //process the next header in the pkt.. i.e push stack up..
    msg->l4_protocol=ipv6_Source_Routing_Header->nextHeader;
    hlen=ipv6_Source_Routing_Header->HdrExtLen;
        
    //toss header
    packetfunctions_tossHeader(msg,sizeof(ipv6_Source_Routing_Header_t));
    
    //toss list of addresses.
    if(local_CmprE==0)
    {
      octetsAddressSize=2;
      //remove 
      packetfunctions_tossHeader(msg,octetsAddressSize*hlen);   
    }
    else if(local_CmprE==8)
    {
      octetsAddressSize=8;
      packetfunctions_tossHeader(msg,octetsAddressSize*hlen);
    }
    else if(local_CmprE==2)
    {
      octetsAddressSize=16;
      packetfunctions_tossHeader(msg,octetsAddressSize*hlen);
    }
    else
    {
      msg->l2_nextORpreviousHop.type = ADDR_NONE;
      //error!
      while(1);
    }
    
    switch(msg->l4_protocol) {
    case IANA_TCP:
      opentcp_receive(msg);
      break;
    case IANA_UDP:
      openudp_receive(msg);
      break;
    case IANA_ICMPv6:
      icmpv6_receive(msg);
      break;
    default:
      openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL,
                            (errorparameter_t)msg->l4_protocol,
                            (errorparameter_t)1);
    }
    
    return E_SUCCESS;
  }else{    
    if(ipv6_Source_Routing_Header->SegmentsLeft>numAddr){
      //not good.. error.
      //send and ICMPv6 parameter problem, code 0, to the src address 
      //then discard the packet.
      //TODO
      while (1);
    }else{
      //still hops remaining 
      ipv6_Source_Routing_Header->SegmentsLeft--;
      //find the address in the vector.
      addressposition=numAddr-(ipv6_Source_Routing_Header->SegmentsLeft);
      
      if(local_CmprE==0)
      {
        msg->l2_nextORpreviousHop.type = ADDR_16B;
        msg->l3_destinationAdd.type = ADDR_16B;
        octetsAddressSize=2;
        memcpy(&(msg->l2_nextORpreviousHop.addr_16b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
        memcpy(&(msg->l3_destinationAdd.addr_16b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
      }
      else if(local_CmprE==8)
      {
        msg->l2_nextORpreviousHop.type = ADDR_64B;
        msg->l3_destinationAdd.type = ADDR_128B;
        octetsAddressSize=8;
        memcpy(&(msg->l2_nextORpreviousHop.addr_64b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
     
        memcpy(&(msg->l3_destinationAdd.addr_128b[0]),prefix->prefix,8);
        memcpy(&(msg->l3_destinationAdd.addr_128b[8]),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
      }
      else if(local_CmprE==2)
      {
        msg->l2_nextORpreviousHop.type = ADDR_128B;
        msg->l3_destinationAdd.type = ADDR_128B;
        
        octetsAddressSize=16;
        memcpy(&(msg->l2_nextORpreviousHop.addr_128b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
        memcpy(&(msg->l3_destinationAdd.addr_128b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
      }
      else
      {
        msg->l2_nextORpreviousHop.type = ADDR_NONE;
        //error!
        while(1);
      }
    }
  }
  
  if (msg->l2_nextORpreviousHop.type==ADDR_NONE) {
    openserial_printError(COMPONENT_FORWARDING,ERR_NO_NEXTHOP,
                          (errorparameter_t)0,
                          (errorparameter_t)0);
    return E_FAIL;
  }
  return iphc_sendFromForwarding(msg, ipv6_header,PCKTFORWARD);
}
Exemple #19
0
/**
\brief Send a packet originating at this mote.

This function is called by an upper layer, and only concerns packets originated
at this mote.

\param[in,out] msg Packet to send.
*/
owerror_t forwarding_send(OpenMote* self, OpenQueueEntry_t* msg) {
    ipv6_header_iht      ipv6_outer_header;
    ipv6_header_iht      ipv6_inner_header;
    rpl_option_ht        rpl_option;
    open_addr_t*         myprefix;
    open_addr_t*         myadd64;
    uint32_t             flow_label = 0;

    open_addr_t          temp_dest_prefix;
    open_addr_t          temp_dest_mac64b;
    open_addr_t*         p_dest;
    open_addr_t*         p_src;  
    open_addr_t          temp_src_prefix;
    open_addr_t          temp_src_mac64b; 
    uint8_t              sam;
    uint8_t              m;
    uint8_t              dam;

    // take ownership over the packet
    msg->owner                = COMPONENT_FORWARDING;

    m   = IPHC_M_NO;

    // retrieve my prefix and EUI64
    myprefix                  = idmanager_getMyID(self, ADDR_PREFIX);
    myadd64                   = idmanager_getMyID(self, ADDR_64B);

    // set source address (me)
    msg->l3_sourceAdd.type=ADDR_128B;
    memcpy(&(msg->l3_sourceAdd.addr_128b[0]),myprefix->prefix,8);
    memcpy(&(msg->l3_sourceAdd.addr_128b[8]),myadd64->addr_64b,8);

    // initialize IPv6 header
    memset(&ipv6_outer_header,0,sizeof(ipv6_header_iht));
    memset(&ipv6_inner_header,0,sizeof(ipv6_header_iht));

    // Set hop limit to the default in-network value as this packet is being
    // sent from upper layer. This is done here as send_internal() is used by
    // forwarding of packets as well which carry a hlim. This value is required
    // to be set to a value as the following function can decrement it.
    ipv6_inner_header.hop_limit     = IPHC_DEFAULT_HOP_LIMIT;

    // create the RPL hop-by-hop option

 forwarding_createRplOption(self, 
      &rpl_option,      // rpl_option to fill in
      0x00              // flags
    );

 packetfunctions_ip128bToMac64b(self, &(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b);
    //xv poipoi -- get the src prefix as well
 packetfunctions_ip128bToMac64b(self, &(msg->l3_sourceAdd),&temp_src_prefix,&temp_src_mac64b);
    //XV -poipoi we want to check if the source address prefix is the same as destination prefix
    if ( packetfunctions_sameAddress(self, &temp_dest_prefix,&temp_src_prefix)) {
         // same prefix use 64B address
         sam = IPHC_SAM_64B;
         dam = IPHC_DAM_64B;
         p_dest = &temp_dest_mac64b;      
         p_src  = &temp_src_mac64b; 
    } else {
        //not the same prefix. so the packet travels to another network
        //check if this is a source routing pkt. in case it is then the DAM is elided as it is in the SrcRouting header.
        if ( packetfunctions_isBroadcastMulticast(self, &(msg->l3_destinationAdd))==FALSE){
            sam = IPHC_SAM_128B;
            dam = IPHC_DAM_128B;
            p_dest = &(msg->l3_destinationAdd);
            p_src = &(msg->l3_sourceAdd);
            
            ipv6_outer_header.src.type = ADDR_128B;
            memcpy(&ipv6_outer_header.src,p_src,sizeof(open_addr_t));
            ipv6_outer_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT;
        } else {
           // this is DIO, source address elided, multicast bit is set
            sam = IPHC_SAM_ELIDED;
            m   = IPHC_M_YES;
            dam = IPHC_DAM_ELIDED;
            p_dest = &(msg->l3_destinationAdd);
            p_src = &(msg->l3_sourceAdd);
        }
    }
    //IPHC inner header and NHC IPv6 header will be added at here
 iphc_prependIPv6Header(self, msg,
                IPHC_TF_ELIDED,
                flow_label, // value_flowlabel
                IPHC_NH_INLINE,
                msg->l4_protocol, 
                IPHC_HLIM_64,
                ipv6_outer_header.hop_limit,
                IPHC_CID_NO,
                IPHC_SAC_STATELESS,
                sam,
                m,
                IPHC_DAC_STATELESS,
                dam,
                p_dest,
                p_src,            
                PCKTSEND  
                );
    // both of them are compressed
    ipv6_outer_header.next_header_compressed = TRUE;

    return forwarding_send_internal_RoutingTable(self, 
        msg,
        &ipv6_outer_header,
        &ipv6_inner_header,
        &rpl_option,
        &flow_label,
        PCKTSEND
    );
}
Exemple #20
0
void rreg_timer() {
   OpenQueueEntry_t* pkt;
   uint8_t           temp8b;
   error_t           outcome;
   uint8_t           numOptions;
   

   // create a CoAP RD packet
   pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG);
   if (pkt==NULL) {
      openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER,
                            (errorparameter_t)0,
                            (errorparameter_t)0);
      openqueue_freePacketBuffer(pkt);
      return;
   }
   // take ownership over that packet
   pkt->creator    = COMPONENT_RREG;
   pkt->owner      = COMPONENT_RREG;
   // CoAP payload
   opencoap_writeLinks(pkt);
   numOptions = 0;
   // URI-query
   packetfunctions_reserveHeaderSize(pkt,sizeof(rreg_uriquery)-1+2);
   memcpy(&pkt->payload[0],&rreg_uriquery,sizeof(rreg_uriquery)-1);
   temp8b = idmanager_getMyID(ADDR_16B)->addr_16b[1];
   pkt->payload[sizeof(rreg_uriquery)-1] = hexToAscii((temp8b>>4) & 0x0f);
   pkt->payload[sizeof(rreg_uriquery)-0] = hexToAscii((temp8b>>0) & 0x0f);
   packetfunctions_reserveHeaderSize(pkt,1);
   pkt->payload[0] = (COAP_OPTION_URIQUERY-COAP_OPTION_URIPATH) << 4 |
      sizeof(rreg_uriquery)-1+2;
   numOptions++;
   // URI-path
   packetfunctions_reserveHeaderSize(pkt,2);
   pkt->payload[0] = 'r';
   pkt->payload[1] = 'd';
   packetfunctions_reserveHeaderSize(pkt,1);
   pkt->payload[0] = (COAP_OPTION_URIPATH-COAP_OPTION_CONTENTTYPE) << 4 |
      2;
   numOptions++;
   // add content-type option
   packetfunctions_reserveHeaderSize(pkt,2);
   pkt->payload[0]                  = COAP_OPTION_CONTENTTYPE << 4 |
      1;
   pkt->payload[1]                  = COAP_MEDTYPE_APPLINKFORMAT;
   numOptions++;
   // metadata
   pkt->l4_destination_port         = WKP_UDP_COAP;
   pkt->l3_destinationORsource.type = ADDR_128B;
   memcpy(&pkt->l3_destinationORsource.addr_128b[0],&ipAddr_ipsoRD,16);
   // send
   outcome = opencoap_send(pkt,
                           COAP_TYPE_CON,
                           COAP_CODE_REQ_POST,
                           numOptions,
                           &rreg_vars.desc);
   // avoid overflowing the queue if fails
   if (outcome==E_FAIL) {
      openqueue_freePacketBuffer(pkt);
   }
   
   return;
}
Exemple #21
0
void table_update_task_cb() {
   OpenQueueEntry_t*    pkt;
   owerror_t            outcome;

   
   // don't run if not synch
   if (ieee154e_isSynch() == FALSE ) return;
   
   // don't run on dagroot
   if (idmanager_getIsDAGroot()) {
      opentimers_stop(table_update_vars.timerId);
      return;
   }
   
   // create a CoAP RD packet
   pkt = openqueue_getFreePacketBuffer(COMPONENT_TABLE_UPDATE);
   if (pkt==NULL) {
      openserial_printError(
         COMPONENT_TABLE_UPDATE,
         ERR_NO_FREE_PACKET_BUFFER,
         (errorparameter_t)0,
         (errorparameter_t)0
      );
      openqueue_freePacketBuffer(pkt);
      return;
   }
   // take ownership over that packet
   pkt->creator                   = COMPONENT_TABLE_UPDATE;
   pkt->owner                     = COMPONENT_TABLE_UPDATE;
   // CoAP payload
   packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN);

   //construct packet

   int index = 0;
   pkt->payload[index++] = 255;//1
   pkt->payload[index++] = action;//2
   //pkt->payload[index++] = count++;
   pkt->payload[index++] = i;//3
   //used
   pkt->payload[index++] = tableEntry->neighborEntry.used;//4	
   //parentRef
   pkt->payload[index++] = tableEntry->neighborEntry.parentPreference;//5
   //stableNeighbor
   pkt->payload[index++] = tableEntry->neighborEntry.stableNeighbor;//6
   //switchStability
   pkt->payload[index++] = tableEntry->neighborEntry.switchStabilityCounter;//7
   //address type
   pkt->payload[index++] = tableEntry->neighborEntry.addr_64b.type;//8
       // the address itself
open_addr_t addr =tableEntry->neighborEntry.addr_64b;//16
memcpy(&pkt->payload[index],&addr.addr_64b,8);
index = index+8;
   //dagrank
   pkt->payload[index++] = tableEntry->neighborEntry.DAGrank;//17
   //rssi
   pkt->payload[index] = tableEntry->neighborEntry.rssi;//19
   index = index+2;
   //numRx
   pkt->payload[index++] = tableEntry->neighborEntry.numRx;//20
   //numTx
   pkt->payload[index++] = tableEntry->neighborEntry.numTx;//21
   //numTxACK
   pkt->payload[index++] = tableEntry->neighborEntry.numTxACK;//22
   //numWraps
   pkt->payload[index++] = tableEntry->neighborEntry.numWraps;//23
   //asn
   pkt->payload[index++] = tableEntry->neighborEntry.asn.byte4;//24
   pkt->payload[index] = tableEntry->neighborEntry.asn.bytes2and3;//26
   index = index+2;
   pkt->payload[index] = tableEntry->neighborEntry.asn.bytes0and1;//28
   index = index+2;
   //joinPrio
   pkt->payload[index] = tableEntry->neighborEntry.joinPrio;//29
	

   // metadata
   pkt->l4_destination_port       = WKP_UDP_COAP;
   pkt->l3_destinationAdd.type    = ADDR_128B;


   //uint8_t*  DODAGID = get_icmpv6rpl_vars()->dio.DODAGID;
	uint8_t         manager_full_address[16];
	   
	   // retrieve my prefix and EUI64
	memcpy(&manager_full_address[0],idmanager_getMyID(ADDR_PREFIX)->prefix,8); // prefix
	memcpy(&manager_full_address[8],&manager_address,8);  // manager address
   memcpy(&pkt->l3_destinationAdd.addr_128b[0],&manager_full_address,16);

	//free some memory
	free(tableEntry);
   // send
   outcome = opencoap_send(
      pkt,
      COAP_TYPE_NON,
      COAP_CODE_RESP_CONTENT,
      1,
      &table_update_vars.desc
   );
   
   // avoid overflowing the queue if fails
   if (outcome==E_FAIL) {
      openqueue_freePacketBuffer(pkt);
   }
   
   return;
}
Exemple #22
0
/**
\brief Prepare and a send a RPL DAO.
*/
void sendDAO() {
   OpenQueueEntry_t*    msg;                // pointer to DAO messages
   uint8_t              nbrIdx;             // running neighbor index
   uint8_t              numTransitParents,numTargetParents;  // the number of parents indicated in transit option
   open_addr_t         address;
   open_addr_t*        prefix;
   
   if (ieee154e_isSynch()==FALSE) {
      // I'm not sync'ed 
      
      // delete packets genereted by this module (DIO and DAO) from openqueue
      openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL);
      
      // I'm not busy sending a DIO/DAO
      icmpv6rpl_vars.busySending = FALSE;
      
      // stop here
      return;
   }
   
   // dont' send a DAO if you're in bridge mode
   if (idmanager_getIsBridge()==TRUE) {
      return;
   }
   
   // dont' send a DAO if you did not acquire a DAGrank
   if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) {
       return;
   }
   
   // dont' send a DAO if you're still busy sending the previous one
   if (icmpv6rpl_vars.busySending==TRUE) {
      return;
   }
   
   // if you get here, you start construct DAO
   
   // reserve a free packet buffer for DAO
   msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL);
   if (msg==NULL) {
      openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER,
                            (errorparameter_t)0,
                            (errorparameter_t)0);
      return;
   }
   
   // take ownership
   msg->creator                             = COMPONENT_ICMPv6RPL;
   msg->owner                               = COMPONENT_ICMPv6RPL;
   
   // set transport information
   msg->l4_protocol                         = IANA_ICMPv6;
   msg->l4_sourcePortORicmpv6Type           = IANA_ICMPv6_RPL;
   
   // set DAO destination
   msg->l3_destinationAdd.type=ADDR_128B;
   memcpy(msg->l3_destinationAdd.addr_128b,icmpv6rpl_vars.dio.DODAGID,sizeof(icmpv6rpl_vars.dio.DODAGID));
   
   //===== fill in packet
   
   //NOTE: limit to preferrred parent only the number of DAO transit addresses to send
   
   //=== transit option -- from RFC 6550, page 55 - 1 transit information header per parent is required. 
   //getting only preferred parent as transit
   numTransitParents=0;
   neighbors_getPreferredParentEui64(&address);
   packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN);
   prefix=idmanager_getMyID(ADDR_PREFIX);
   packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN);
   // update transit info fields
   // from rfc6550 p.55 -- Variable, depending on whether or not the DODAG ParentAddress subfield is present.
   // poipoi xv: it is not very clear if this includes all fields in the header. or as target info 2 bytes are removed.
   // using the same pattern as in target information.
   icmpv6rpl_vars.dao_transit.optionLength  = LENGTH_ADDR128b + sizeof(icmpv6rpl_dao_transit_ht)-2;
   icmpv6rpl_vars.dao_transit.PathControl=0; //todo. this is to set the preference of this parent.      
   icmpv6rpl_vars.dao_transit.type=OPTION_TRANSIT_INFORMATION_TYPE;
           
   // write transit info in packet
   packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_transit_ht));
   memcpy(
          ((icmpv6rpl_dao_transit_ht*)(msg->payload)),
          &(icmpv6rpl_vars.dao_transit),
          sizeof(icmpv6rpl_dao_transit_ht)
   );
   numTransitParents++;
   
   //target information is required. RFC 6550 page 55.
   /*
   One or more Transit Information options MUST be preceded by one or
   more RPL Target options.   
   */
    numTargetParents                        = 0;
    for (nbrIdx=0;nbrIdx<MAXNUMNEIGHBORS;nbrIdx++) {
      if ((neighbors_isNeighborWithHigherDAGrank(nbrIdx))==TRUE) {
         // this neighbor is of higher DAGrank as I am. so it is my child
         
         // write it's address in DAO RFC6550 page 80 check point 1.
         neighbors_getNeighbor(&address,ADDR_64B,nbrIdx); 
         packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN);
         prefix=idmanager_getMyID(ADDR_PREFIX);
         packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN);
        
         // update target info fields 
         // from rfc6550 p.55 -- Variable, length of the option in octets excluding the Type and Length fields.
         // poipoi xv: assuming that type and length fields refer to the 2 first bytes of the header
         icmpv6rpl_vars.dao_target.optionLength  = LENGTH_ADDR128b +sizeof(icmpv6rpl_dao_target_ht) - 2; //no header type and length
         icmpv6rpl_vars.dao_target.type  = OPTION_TARGET_INFORMATION_TYPE;
         icmpv6rpl_vars.dao_target.flags  = 0;       //must be 0
         icmpv6rpl_vars.dao_target.prefixLength = 128; //128 leading bits  -- full address.
         
         // write transit info in packet
         packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_target_ht));
         memcpy(
               ((icmpv6rpl_dao_target_ht*)(msg->payload)),
               &(icmpv6rpl_vars.dao_target),
               sizeof(icmpv6rpl_dao_target_ht)
         );
         
         // remember I found it
         numTargetParents++;
      }  
      //limit to MAX_TARGET_PARENTS the number of DAO target addresses to send
      //section 8.2.1 pag 67 RFC6550 -- using a subset
      // poipoi TODO base selection on ETX rather than first X.
      if (numTargetParents>=MAX_TARGET_PARENTS) break;
   }
   
   
   // stop here if no parents found
   if (numTransitParents==0) {
      openqueue_freePacketBuffer(msg);
      return;
   }
   
   icmpv6rpl_vars.dao_transit.PathSequence++; //increment path sequence.
   // if you get here, you will send a DAO
   
   
   //=== DAO header
   packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_ht));
   memcpy(
      ((icmpv6rpl_dao_ht*)(msg->payload)),
      &(icmpv6rpl_vars.dao),
      sizeof(icmpv6rpl_dao_ht)
   );
   
   //=== ICMPv6 header
   packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht));
   ((ICMPv6_ht*)(msg->payload))->type       = msg->l4_sourcePortORicmpv6Type;
   ((ICMPv6_ht*)(msg->payload))->code       = IANA_ICMPv6_RPL_DAO;
   packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum)); //call last
   
   //===== send
   if (icmpv6_send(msg)==E_SUCCESS) {
      icmpv6rpl_vars.busySending = TRUE;
   } else {
      openqueue_freePacketBuffer(msg);
   }
}
Exemple #23
0
/**
\brief Force a topology.

This function is used to force a certain topology, by hard-coding the list of
acceptable neighbors for a given mote. This function is invoked each time a
packet is received. If it returns FALSE, the packet is silently dropped, as if
it were never received. If it returns TRUE, the packet is accepted.

Typically, filtering packets is done by analyzing the IEEE802.15.4 header. An
example body for this function which forces a topology is:

   switch (idmanager_getMyID(ADDR_64B)->addr_64b[7]) {
      case TOPOLOGY_MOTE1:
         if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2) {
            returnVal=TRUE;
         } else {
            returnVal=FALSE;
         }
         break;
      case TOPOLOGY_MOTE2:
         if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE1 ||
             ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE3) {
            returnVal=TRUE;
         } else {
            returnVal=FALSE;
         }
         break;
      default:
         returnVal=TRUE;
   }
   return returnVal;

By default, however, the function should return TRUE to *not* force any
topology.

\param[in] ieee802514_header The parsed IEEE802.15.4 MAC header.

\return TRUE if the packet can be received.
\return FALSE if the packet should be silently dropped.
*/
bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) {
#ifdef PLUGFEST
   bool returnVal;
   
   returnVal=FALSE;
   switch (idmanager_getMyID(ADDR_64B)->addr_64b[7]) {
      case 0x4c:
         if (
               ieee802514_header->src.addr_64b[7]==0x00 ||
               ieee802514_header->src.addr_64b[7]==0x60
            ) {
            returnVal=TRUE;
         }
         break;
      case 0x60:
         if (
               ieee802514_header->src.addr_64b[7]==0x4c ||
               ieee802514_header->src.addr_64b[7]==0x97 ||
               ieee802514_header->src.addr_64b[7]==0xc8
            ) {
            returnVal=TRUE;
         }
         break;
      case 0xc8:
         if (
               ieee802514_header->src.addr_64b[7]==0x60 ||
               ieee802514_header->src.addr_64b[7]==0x6f ||
               ieee802514_header->src.addr_64b[7]==0x50
            ) {
            returnVal=TRUE;
         }
         break;
      case 0x50:
         if (
               ieee802514_header->src.addr_64b[7]==0xc8
            ) {
            returnVal=TRUE;
         }
         break;
      case 0x6f:
         if (
               ieee802514_header->src.addr_64b[7]==0x85 ||
               ieee802514_header->src.addr_64b[7]==0x97 ||
               ieee802514_header->src.addr_64b[7]==0xc8
            ) {
            returnVal=TRUE;
         }
         break;
      case 0x85:
         if (
               ieee802514_header->src.addr_64b[7]==0x5c ||
               ieee802514_header->src.addr_64b[7]==0x97 ||
               ieee802514_header->src.addr_64b[7]==0x6f
            ) {
            returnVal=TRUE;
         }
         break;
      case 0xa8:
         if (
               ieee802514_header->src.addr_64b[7]==0x5c ||
               ieee802514_header->src.addr_64b[7]==0x97 ||
               ieee802514_header->src.addr_64b[7]==0x00
            ) {
            returnVal=TRUE;
         }
         break;
      case 0x00:
         if (
               ieee802514_header->src.addr_64b[7]==0x4c ||
               ieee802514_header->src.addr_64b[7]==0xa8
            ) {
            returnVal=TRUE;
         }
         break;
      case 0x97:
         if (
               ieee802514_header->src.addr_64b[7]==0xa8 ||
               ieee802514_header->src.addr_64b[7]==0x85 ||
               ieee802514_header->src.addr_64b[7]==0x6f ||
               ieee802514_header->src.addr_64b[7]==0x60
            ) {
            returnVal=TRUE;
         }
         break;
      case 0x5c:
         if (
               ieee802514_header->src.addr_64b[7]==0x85 ||
               ieee802514_header->src.addr_64b[7]==0xa8
            ) {
            returnVal=TRUE;
         }
         break;
   }
   return returnVal;
#else
   return TRUE;
#endif
}