diff --git a/drivers/common/openserial.c b/drivers/common/openserial.c index 8363e04e7e..2380949988 100644 --- a/drivers/common/openserial.c +++ b/drivers/common/openserial.c @@ -450,7 +450,7 @@ void openserial_stop() { } void openserial_goldenImageCommands(void){ - uint8_t input_buffer[7]; + uint8_t input_buffer[10]; uint8_t numDataBytes; uint8_t version; #ifndef GOLDEN_IMAGE_NONE @@ -460,6 +460,13 @@ void openserial_goldenImageCommands(void){ uint8_t commandLen; uint8_t comandParam_8; uint16_t comandParam_16; + cellInfo_ht cellList[SCHEDULEIEMAXNUMCELLS]; + uint8_t i; + + open_addr_t neighbor; + bool foundNeighbor; + + memset(cellList,0,sizeof(cellList)); numDataBytes = openserial_getNumDataBytes(); //copying the buffer @@ -489,7 +496,7 @@ void openserial_goldenImageCommands(void){ commandId = openserial_vars.inputBuf[3]; commandLen = openserial_vars.inputBuf[4]; - if (commandLen>2 || commandLen == 0) { + if (commandLen>3) { // the max command Len is 2, except ping commands return; } else { @@ -525,9 +532,6 @@ void openserial_goldenImageCommands(void){ case COMMAND_SET_DAOPERIOD: // two bytes, in mili-seconds icmpv6rpl_setDAOPeriod(comandParam_16); break; - case COMMAND_PING_MOTE: - // this should not happen - break; case COMMAND_SET_DAGRANK: // two bytes neighbors_setMyDAGrank(comandParam_16); break; @@ -558,6 +562,57 @@ void openserial_goldenImageCommands(void){ } } break; + case COMMAND_SET_6P_ADD: + case COMMAND_SET_6P_DELETE: + case COMMAND_SET_6P_COUNT: + case COMMAND_SET_6P_LIST: + case COMMAND_SET_6P_CLEAR: + // get preferred parent + foundNeighbor = neighbors_getPreferredParentEui64(&neighbor); + if (foundNeighbor==FALSE) { + break; + } + + sixtop_setHandler(SIX_HANDLER_OTF); + if ( + ( + commandId != COMMAND_SET_6P_ADD && + commandId != COMMAND_SET_6P_DELETE + ) || + ( + ( + commandId == COMMAND_SET_6P_ADD || + commandId == COMMAND_SET_6P_DELETE + ) && + commandLen == 0 + ) + ){ + // randommly select cell + sixtop_request(commandId-8,&neighbor,1); + } else { + for (i=0;ipayload)+ptr)); ptr = ptr + 1; + if (ieee154e_vars.tsTemplateId != TIMESLOT_TEMPLATE_ID){ + ieee154e_vars.slotDuration = *((uint8_t*)(pkt->payload)+ptr); + ptr = ptr + 1; + ieee154e_vars.slotDuration |= ((*((uint8_t*)(pkt->payload)+ptr))<<8) & 0xff00; + ptr = ptr + 1; + } } break; @@ -948,7 +955,7 @@ port_INLINE void activity_ti1ORri1() { openserial_startInput(); //this is to emulate a set of serial input slots without having the slotted structure. - radio_setTimerPeriod(TsSlotDuration*(NUMSERIALRX)); + radio_setTimerPeriod(ieee154e_vars.slotDuration*(NUMSERIALRX)); //increase ASN by NUMSERIALRX-1 slots as at this slot is already incremented by 1 for (i=0;iowner = COMPONENT_IEEE802154E_TO_SIXTOP; #ifdef GOLDEN_IMAGE_ROOT - openserial_printInfo(COMPONENT_IEEE802154E,ERR_PACKET_SYNC, - (errorparameter_t)packetReceived->l2_asn.bytes0and1, - (errorparameter_t)packetReceived->l2_timeCorrection); +// openserial_printInfo(COMPONENT_IEEE802154E,ERR_PACKET_SYNC, +// (errorparameter_t)packetReceived->l2_asn.bytes0and1, +// (errorparameter_t)packetReceived->l2_timeCorrection); #endif // post RES's Receive task scheduler_push_task(task_sixtopNotifReceive,TASKPRIO_SIXTOP_NOTIF_RX); diff --git a/openstack/02a-MAClow/IEEE802154E.h b/openstack/02a-MAClow/IEEE802154E.h index 56ad935929..e54af67cf2 100644 --- a/openstack/02a-MAClow/IEEE802154E.h +++ b/openstack/02a-MAClow/IEEE802154E.h @@ -41,6 +41,9 @@ static const uint8_t chTemplate_default[] = { #define IEEE802154E_DESC_TYPE_LONG (1<<15) #define IEEE802154E_DESC_TYPE_SHORT (0<<15) +#define IANA_6TOP_IE_GROUP_ID (2<<11) +#define IANA_6TOP_IE_GROUP_ID_TYPE (1<<15) + #define IEEE802154E_DESC_TYPE_HEADER_IE 0x0000 #define IEEE802154E_DESC_TYPE_PAYLOAD_IE 0x8000 //len field on PAYLOAD/HEADER DESC @@ -142,7 +145,7 @@ enum ieee154e_atomicdurations_enum { TsTxOffset = 70, // 2120us TsLongGT = 36, // 1100us TsTxAckDelay = 33, // 1000us - TsShortGT = 7, // 500us + TsShortGT = 9, // 500us, The standardlized value for this is 400/2=200us(7ticks). Currectly 7 doesn't work for short packet, change it back to 7 when found the problem. #else TsTxOffset = 131, // 4000us TsLongGT = 43, // 1300us @@ -247,6 +250,8 @@ typedef struct { bool isSecurityEnabled; // whether security is applied // time correction int16_t timeCorrection; // store the timeCorrection, prepend and retrieve it inside of frame header + + uint16_t slotDuration; // } ieee154e_vars_t; BEGIN_PACK @@ -279,6 +284,8 @@ void ieee154e_getAsn(uint8_t* array); void ieee154e_setIsAckEnabled(bool isEnabled); void ieee154e_setSingleChannel(uint8_t channel); void ieee154e_setIsSecurityEnabled(bool isEnabled); +void ieee154e_setSlotDuration(uint16_t duration); +uint16_t ieee154e_getSlotDuration(); uint16_t ieee154e_getTimeCorrection(void); // events diff --git a/openstack/02a-MAClow/adaptive_sync.c b/openstack/02a-MAClow/adaptive_sync.c index 76c4cc98d5..53bb639bd9 100644 --- a/openstack/02a-MAClow/adaptive_sync.c +++ b/openstack/02a-MAClow/adaptive_sync.c @@ -173,7 +173,7 @@ Once compensationTimeout == 0, extend or shorten current slot length for one tic void adaptive_sync_countCompensationTimeout() { uint16_t newSlotDuration; - newSlotDuration = TsSlotDuration; + newSlotDuration = ieee154e_getSlotDuration(); // if clockState is not set yet, don't compensate. if (adaptive_sync_vars.clockState == S_NONE) { @@ -215,7 +215,7 @@ void adaptive_sync_countCompensationTimeout_compoundSlots(uint16_t compoundSlots uint8_t compensateTicks; uint16_t newSlotDuration; - newSlotDuration = TsSlotDuration*(compoundSlots+1); + newSlotDuration = ieee154e_getSlotDuration()*(compoundSlots+1); // if clockState is not set yet, don't compensate. if(adaptive_sync_vars.clockState == S_NONE) { diff --git a/openstack/02a-MAClow/topology.c b/openstack/02a-MAClow/topology.c index 63eac8ae23..c6fdcfd81d 100644 --- a/openstack/02a-MAClow/topology.c +++ b/openstack/02a-MAClow/topology.c @@ -56,92 +56,28 @@ bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) { returnVal=FALSE; switch (idmanager_getMyID(ADDR_64B)->addr_64b[7]) { - case 0x4c: + case 0xdf: if ( - ieee802514_header->src.addr_64b[7]==0x00 || - ieee802514_header->src.addr_64b[7]==0x60 + ieee802514_header->src.addr_64b[7]==0x66 ) { returnVal=TRUE; } break; - case 0x60: + case 0x66: if ( - ieee802514_header->src.addr_64b[7]==0x4c || - ieee802514_header->src.addr_64b[7]==0x97 || - ieee802514_header->src.addr_64b[7]==0xc8 + ieee802514_header->src.addr_64b[7]==0xdf || + ieee802514_header->src.addr_64b[7]==0x4f ) { returnVal=TRUE; } break; - case 0xc8: + case 0x4f: if ( - ieee802514_header->src.addr_64b[7]==0x60 || - ieee802514_header->src.addr_64b[7]==0x6f || - ieee802514_header->src.addr_64b[7]==0x50 + ieee802514_header->src.addr_64b[7]==0x66 ) { 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; + break; } return returnVal; #else diff --git a/openstack/02b-MAChigh/otf.c b/openstack/02b-MAChigh/otf.c index 09dd39199c..5ca1934730 100644 --- a/openstack/02b-MAChigh/otf.c +++ b/openstack/02b-MAChigh/otf.c @@ -38,7 +38,8 @@ void otf_addCell_task(void) { sixtop_setHandler(SIX_HANDLER_OTF); // call sixtop - sixtop_addCells( + sixtop_request( + IANA_6TOP_CMD_ADD, &neighbor, 1 ); @@ -56,7 +57,9 @@ void otf_removeCell_task(void) { sixtop_setHandler(SIX_HANDLER_OTF); // call sixtop - sixtop_removeCell( - &neighbor + sixtop_request( + IANA_6TOP_CMD_DELETE, + &neighbor, + 1 ); } \ No newline at end of file diff --git a/openstack/02b-MAChigh/processIE.c b/openstack/02b-MAChigh/processIE.c index 64190b5223..ba0ebea3a8 100644 --- a/openstack/02b-MAChigh/processIE.c +++ b/openstack/02b-MAChigh/processIE.c @@ -37,6 +37,28 @@ port_INLINE void processIE_prependMLMEIE( pkt->payload[1] = (payload_IE_desc.length_groupid_type >> 8) & 0xFF; } +port_INLINE void processIE_prepend_sixtopIE( + OpenQueueEntry_t* pkt, + uint8_t len + ){ + payload_IE_ht payload_IE_desc; + + // reserve space + packetfunctions_reserveHeaderSize( + pkt, + sizeof(payload_IE_ht) + ); + + // prepare header + payload_IE_desc.length_groupid_type = len; + payload_IE_desc.length_groupid_type |= + (IANA_6TOP_IE_GROUP_ID | IANA_6TOP_IE_GROUP_ID_TYPE); + + // copy header + pkt->payload[0] = payload_IE_desc.length_groupid_type & 0xFF; + pkt->payload[1] = (payload_IE_desc.length_groupid_type >> 8) & 0xFF; +} + //===== prepend IEs port_INLINE uint8_t processIE_prependSyncIE(OpenQueueEntry_t* pkt){ @@ -159,14 +181,29 @@ port_INLINE uint8_t processIE_prependTSCHTimeslotIE(OpenQueueEntry_t* pkt){ uint8_t len; mlme_IE_ht mlme_subHeader; - len = 0; - - // reserve space for timeslot template ID - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - // write header - *((uint8_t*)(pkt->payload)) = TIMESLOT_TEMPLATE_ID; + uint16_t duration; - len+=1; + len = 0; + duration = ieee154e_getSlotDuration(); + + if (duration==328){ + // reserve space for timeslot template ID + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + // write header + *((uint8_t*)(pkt->payload)) = TIMESLOT_TEMPLATE_ID; + len+=1; + } else { + // reserve space for timeslot template ID + packetfunctions_reserveHeaderSize(pkt,sizeof(uint16_t)); + // write header + pkt->payload[0] = (uint8_t)(duration & 0x00ff); + pkt->payload[1] = (uint8_t)((duration>>8) & 0x00ff); + // reserve space for timeslot template ID + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + // write header + *((uint8_t*)(pkt->payload)) = 1; + len+=3; + } //===== MLME IE header @@ -220,213 +257,98 @@ port_INLINE uint8_t processIE_prependChannelHoppingIE(OpenQueueEntry_t* pkt){ return len; } -port_INLINE uint8_t processIE_prependOpcodeIE( - OpenQueueEntry_t* pkt, - uint8_t uResCommandID - ){ - uint8_t len; - mlme_IE_ht mlme_subHeader; - - len = 0; - - //===== command ID - - // reserve space - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - - // write header - *((uint8_t*)(pkt->payload)) = uResCommandID; - - len += 1; - - //===== MLME IE header - - // reserve space - packetfunctions_reserveHeaderSize(pkt, sizeof(mlme_IE_ht)); - - // prepare header - mlme_subHeader.length_subID_type = len; - mlme_subHeader.length_subID_type |= - MLME_IE_SUBID_OPCODE << MLME_IE_SUBID_SHIFT| - IEEE802154E_DESC_TYPE_SHORT; - - // copy header - pkt->payload[0] = mlme_subHeader.length_subID_type & 0xFF; - pkt->payload[1] = (mlme_subHeader.length_subID_type >> 8) & 0xFF; - - len += 2; - - return len; +port_INLINE uint8_t processIE_prepend_sixSubIEHeader( + OpenQueueEntry_t* pkt, + uint8_t len + ){ + mlme_IE_ht mlme_subHeader; + //===== MLME IE header + // reserve space + packetfunctions_reserveHeaderSize(pkt, sizeof(mlme_IE_ht)); + + // prepare header + mlme_subHeader.length_subID_type = len; + mlme_subHeader.length_subID_type |= + (IANA_6TOP_SUBIE_ID << MLME_IE_SUBID_SHIFT) | + IEEE802154E_DESC_TYPE_SHORT; + + // copy header + pkt->payload[0] = mlme_subHeader.length_subID_type & 0xFF; + pkt->payload[1] = (mlme_subHeader.length_subID_type >> 8)& 0xFF; + + return 2; } -port_INLINE uint8_t processIE_prependBandwidthIE( - OpenQueueEntry_t* pkt, - uint8_t numOfLinks, - uint8_t slotframeID - ){ - - uint8_t len; - mlme_IE_ht mlme_subHeader; - - len = 0; - - //===== number of cells - - // reserve space - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - - // write header - *((uint8_t*)(pkt->payload)) = numOfLinks; - - len += 1; - - //===== number of cells - - // reserve space - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - - // write header - *((uint8_t*)(pkt->payload)) = slotframeID; - - len += 1; - - //===== MLME IE header - - // reserve space - packetfunctions_reserveHeaderSize(pkt, sizeof(mlme_IE_ht)); - - // prepare header - mlme_subHeader.length_subID_type = len; - mlme_subHeader.length_subID_type |= - (MLME_IE_SUBID_BANDWIDTH << - MLME_IE_SUBID_SHIFT) | - IEEE802154E_DESC_TYPE_SHORT; - - // copy header - pkt->payload[0] = mlme_subHeader.length_subID_type & 0xFF; - pkt->payload[1] = (mlme_subHeader.length_subID_type >> 8) & 0xFF; - - len += 2; +port_INLINE uint8_t processIE_prepend_sixGeneralMessage( + OpenQueueEntry_t* pkt, + uint8_t code + ){ + uint8_t len = 0; + uint8_t temp8b; + + //===== SFID + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + *((uint8_t*)(pkt->payload)) = SFID_SF0; + len += 1; + + pkt->l2_sixtop_returnCode = code; - return len; + //===== version & code + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + temp8b = IANA_6TOP_6P_VERSION; + temp8b |= code << 4; + *((uint8_t*)(pkt->payload)) = temp8b; + len += 1; + + return len; } -port_INLINE uint8_t processIE_prependScheduleIE( - OpenQueueEntry_t* pkt, - uint8_t type, - uint8_t frameID, - uint8_t flag, - cellInfo_ht* cellList +port_INLINE uint8_t processIE_prepend_sixSubID(OpenQueueEntry_t* pkt){ + uint8_t len = 0; + + //===== SFID + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + *((uint8_t*)(pkt->payload)) = IANA_6TOP_SUBIE_ID; + len += 1; + + return len; +} + +port_INLINE uint8_t processIE_prepend_sixCelllist( + OpenQueueEntry_t* pkt, + cellInfo_ht* cellList ){ - uint8_t i; - uint8_t len; - uint8_t temp8b; - uint8_t numOfCells; - mlme_IE_ht mlme_subHeader; + uint8_t i; + uint8_t len; + uint8_t numOfCells; - len = 0; - numOfCells = 0; - - //===== cell list - - for(i=0;ipayload[0] = (uint8_t)(cellList[i].tsNum & 0x00FF); - pkt->payload[1] = (uint8_t)((cellList[i].tsNum & 0xFF00)>>8); - pkt->payload[2] = (uint8_t)(cellList[i].choffset & 0x00FF); - pkt->payload[3] = (uint8_t)((cellList[i].choffset & 0xFF00)>>8); - pkt->payload[4] = cellList[i].linkoptions; - len += 5; - numOfCells++; - } - } - - // record the position of cellObjects - pkt->l2_scheduleIE_numOfCells = numOfCells; - pkt->l2_scheduleIE_cellObjects = pkt->payload; - - //===== number of cells - - // reserve space - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - - // prepare header - temp8b = numOfCells; - temp8b |= flag << 7; - - // copy header - *((uint8_t*)(pkt->payload)) = temp8b; - - len += 1; - - //===== slotframeID - - // reserve space - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - - // prepare header - temp8b = frameID; - - // copy header - *((uint8_t*)(pkt->payload)) = temp8b; - - len += 1; - - // record the frameID - pkt->l2_scheduleIE_frameID = frameID; - - //===== length - - // reserve space - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - - // prepare header - temp8b = len; - - // copy header - *((uint8_t*)(pkt->payload)) = temp8b; - - // length - len += 1; - - //===== type - - // reserve space - packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); - - // prepare header - temp8b = type; - - // copy header - *((uint8_t*)(pkt->payload)) = temp8b; - - len += 1; - - //===== MLME IE header - - // reserve space - packetfunctions_reserveHeaderSize(pkt, sizeof(mlme_IE_ht)); - - // prepare header - mlme_subHeader.length_subID_type = len; - mlme_subHeader.length_subID_type |= - (MLME_IE_SUBID_SCHEDULE << MLME_IE_SUBID_SHIFT) | - IEEE802154E_DESC_TYPE_SHORT; - - // copy header - pkt->payload[0] = mlme_subHeader.length_subID_type & 0xFF; - pkt->payload[1] = (mlme_subHeader.length_subID_type >> 8)& 0xFF; - - len+=2; - - return len; + len = 0; + numOfCells = 0; + + //===== cell list + + for(i=0;ipayload[0] = (uint8_t)(cellList[i].tsNum & 0x00FF); + pkt->payload[1] = (uint8_t)((cellList[i].tsNum & 0xFF00)>>8); + pkt->payload[2] = (uint8_t)(cellList[i].choffset & 0x00FF); + pkt->payload[3] = (uint8_t)((cellList[i].choffset & 0xFF00)>>8); + len += 4; + numOfCells++; + } + } + + // record the position of cellObjects + pkt->l2_sixtop_numOfCells = numOfCells; + pkt->l2_sixtop_cellObjects = pkt->payload; + + return len; } - //===== retrieve IEs port_INLINE void processIE_retrieveSlotframeLinkIE( @@ -512,99 +434,24 @@ port_INLINE void processIE_retrieveSlotframeLinkIE( *ptr=localptr; } -port_INLINE void processIE_retrieveOpcodeIE( - OpenQueueEntry_t* pkt, - uint8_t* ptr, - opcode_IE_ht* opcodeInfo - ){ - uint8_t localptr; - - localptr=*ptr; - - opcodeInfo->opcode = *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - *ptr=localptr; -} - -port_INLINE void processIE_retrieveBandwidthIE( - OpenQueueEntry_t* pkt, - uint8_t * ptr, - bandwidth_IE_ht* bandwidthInfo - ){ - uint8_t localptr; - - localptr=*ptr; - - // [1B] slotframeID - bandwidthInfo->slotframeID = *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - // [1B] number of cells - bandwidthInfo->numOfLinks = *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - *ptr=localptr; -} - -port_INLINE void processIE_retrieveScheduleIE( - OpenQueueEntry_t* pkt, - uint8_t* ptr, - schedule_IE_ht* scheduleInfo - ){ - uint8_t i; - uint8_t temp8b; - uint8_t localptr; - - localptr=*ptr; - - // [1B] type - scheduleInfo->type = *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - // [1B] length - scheduleInfo->length = *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - // [1B] frameID - scheduleInfo->frameID = *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - // [1B] number of cell and flag - temp8b = *((uint8_t*)(pkt->payload)+localptr); - scheduleInfo->numberOfcells = temp8b & 0x7F; - scheduleInfo->flag = (temp8b >> 7) ? TRUE : FALSE; - localptr++; - - if(scheduleInfo->numberOfcells > SCHEDULEIEMAXNUMCELLS) { - //log error - return; - } - - for (i=0;inumberOfcells;i++){ - - // [2B] TimeSlot - scheduleInfo->cellList[i].tsNum = - *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - scheduleInfo->cellList[i].tsNum |= - (*((uint8_t*)(pkt->payload)+localptr))<<8; - localptr++; - - // [2B] Ch.Offset - scheduleInfo->cellList[i].choffset = - *((uint8_t*)(pkt->payload)+localptr); - localptr++; - - scheduleInfo->cellList[i].choffset |= - (*((uint8_t*)(pkt->payload)+localptr))<<8; - localptr++; - - // [1B] LinkOption bitmap - scheduleInfo->cellList[i].linkoptions = - *((uint8_t*)(pkt->payload)+localptr); - localptr++; - } - *ptr=localptr; -} +port_INLINE void processIE_retrieve_sixCelllist( + OpenQueueEntry_t* pkt, + uint8_t ptr, + uint8_t length, + cellInfo_ht* cellList + ){ + uint8_t i=0; + uint8_t localptr = ptr; + uint8_t len = length; + while(len>0){ + cellList[i].tsNum = *((uint8_t*)(pkt->payload)+localptr); + cellList[i].tsNum |= (*((uint8_t*)(pkt->payload)+localptr+1))<<8; + cellList[i].choffset = *((uint8_t*)(pkt->payload)+localptr+2); + cellList[i].choffset |= (*((uint8_t*)(pkt->payload)+localptr+3))<<8; + localptr += 4; + len -= 4; + // mark with linkoptions as ocuppied + cellList[i].linkoptions = CELLTYPE_TX; + i++; + } +} \ No newline at end of file diff --git a/openstack/02b-MAChigh/processIE.h b/openstack/02b-MAChigh/processIE.h index 7b3b665db8..eace5dda83 100644 --- a/openstack/02b-MAChigh/processIE.h +++ b/openstack/02b-MAChigh/processIE.h @@ -21,6 +21,10 @@ #define MLME_IE_SUBID_BANDWIDTH 0x42 #define MLME_IE_SUBID_TRACKID 0x43 #define MLME_IE_SUBID_SCHEDULE 0x44 + +#define IANA_6TOP_SUBIE_ID 0x00 +#define SIXTOP_IE_GROUPID 0x02 + // ========================== typedef ========================================= BEGIN_PACK @@ -132,36 +136,38 @@ void processIE_prependMLMEIE( OpenQueueEntry_t* pkt, uint8_t len ); - +void processIE_prepend_sixtopIE( + OpenQueueEntry_t* pkt, + uint8_t len +); //===== prepend IEs uint8_t processIE_prependSyncIE( - OpenQueueEntry_t* pkt + OpenQueueEntry_t* pkt ); uint8_t processIE_prependSlotframeLinkIE( - OpenQueueEntry_t* pkt + OpenQueueEntry_t* pkt ); uint8_t processIE_prependTSCHTimeslotIE( - OpenQueueEntry_t* pkt + OpenQueueEntry_t* pkt ); uint8_t processIE_prependChannelHoppingIE( - OpenQueueEntry_t* pkt + OpenQueueEntry_t* pkt ); -uint8_t processIE_prependOpcodeIE( - OpenQueueEntry_t* pkt, - uint8_t uResCommandID +uint8_t processIE_prepend_sixSubIEHeader( + OpenQueueEntry_t* pkt, + uint8_t len ); -uint8_t processIE_prependBandwidthIE( - OpenQueueEntry_t* pkt, - uint8_t numOfLinks, - uint8_t slotframeID +uint8_t processIE_prepend_sixGeneralMessage( + OpenQueueEntry_t* pkt, + uint8_t code ); -uint8_t processIE_prependScheduleIE( - OpenQueueEntry_t* pkt, - uint8_t type, - uint8_t frameID, - uint8_t flag, - cellInfo_ht* cellList +uint8_t processIE_prepend_sixSubID( + OpenQueueEntry_t* pkt +); +uint8_t processIE_prepend_sixCelllist( + OpenQueueEntry_t* pkt, + cellInfo_ht* cellList ); //===== retrieve IEs @@ -170,20 +176,11 @@ void processIE_retrieveSlotframeLinkIE( OpenQueueEntry_t* pkt, uint8_t * ptr ); -void processIE_retrieveOpcodeIE( - OpenQueueEntry_t* pkt, - uint8_t* ptr, - opcode_IE_ht* opcodeIE -); -void processIE_retrieveBandwidthIE( - OpenQueueEntry_t* pkt, - uint8_t * ptr, - bandwidth_IE_ht* bandwidthIE -); -void processIE_retrieveScheduleIE( - OpenQueueEntry_t* pkt, - uint8_t * ptr, - schedule_IE_ht* schedule_ie +void processIE_retrieve_sixCelllist( + OpenQueueEntry_t* pkt, + uint8_t ptr, + uint8_t length, + cellInfo_ht* cellList ); #endif diff --git a/openstack/02b-MAChigh/schedule.c b/openstack/02b-MAChigh/schedule.c index 797d63bf20..65cd6644ec 100644 --- a/openstack/02b-MAChigh/schedule.c +++ b/openstack/02b-MAChigh/schedule.c @@ -477,6 +477,53 @@ scheduleEntry_t* schedule_statistic_poorLinkQuality(){ } } +uint16_t schedule_getCellsCounts(uint8_t frameID,cellType_t type, open_addr_t* neighbor){ + uint16_t count = 0; + scheduleEntry_t* scheduleWalker; + + INTERRUPT_DECLARATION(); + DISABLE_INTERRUPTS(); + + if (frameID != SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE){ + ENABLE_INTERRUPTS(); + return 0; + } + + scheduleWalker = schedule_vars.currentScheduleEntry; + do { + if( + packetfunctions_sameAddress(&(scheduleWalker->neighbor),neighbor) && + type == scheduleWalker->type + ){ + count++; + } + scheduleWalker = scheduleWalker->next; + }while(scheduleWalker!=schedule_vars.currentScheduleEntry); + + ENABLE_INTERRUPTS(); + return count; +} +void schedule_removeAllCells( + uint8_t slotframeID, + open_addr_t* previousHop + ){ + uint8_t i; + + // remove all entries in schedule with previousHop address + for(i=0;icreator = COMPONENT_SIXTOP_RES; - pkt->owner = COMPONENT_SIXTOP_RES; - - memcpy( - &(pkt->l2_nextORpreviousHop), - neighbor, - sizeof(open_addr_t) - ); - - // create packet - len = 0; - len += processIE_prependScheduleIE(pkt,type,frameID,flag,cellList); - len += processIE_prependBandwidthIE(pkt,numCells,frameID); - len += processIE_prependOpcodeIE(pkt,SIXTOP_SOFT_CELL_REQ); - processIE_prependMLMEIE(pkt,len); - - // indicate IEs present - pkt->l2_payloadIEpresent = TRUE; - - // send packet - sixtop_send(pkt); - - // update state - sixtop_vars.six2six_state = SIX_WAIT_ADDREQUEST_SENDDONE; - - // arm timeout - opentimers_setPeriod( - sixtop_vars.timeoutTimerId, - TIME_MS, - SIX2SIX_TIMEOUT_MS - ); - opentimers_restart(sixtop_vars.timeoutTimerId); -} - -void sixtop_removeCell(open_addr_t* neighbor){ - OpenQueueEntry_t* pkt; - bool outcome; - uint8_t len; - uint8_t type; - uint8_t frameID; - uint8_t flag; - cellInfo_ht cellList[SCHEDULEIEMAXNUMCELLS]; - - memset(cellList,0,sizeof(cellList)); - - // filter parameters - if (sixtop_vars.six2six_state!=SIX_IDLE){ - return; - } - if (neighbor==NULL){ - return; - } +void sixtop_request(uint8_t code, open_addr_t* neighbor, uint8_t numCells){ + OpenQueueEntry_t* pkt; + uint8_t len; + uint8_t container; + uint8_t frameID; + cellInfo_ht cellList[SCHEDULEIEMAXNUMCELLS]; - // generate candidate cell list - outcome = sixtop_candidateRemoveCellList( - &type, - &frameID, - &flag, - cellList, - neighbor - ); - if(outcome == FALSE){ - return; - } + memset(cellList,0,sizeof(cellList)); - // get a free packet buffer - pkt = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP_RES); - if(pkt==NULL) { - openserial_printError( - COMPONENT_SIXTOP_RES, - ERR_NO_FREE_PACKET_BUFFER, - (errorparameter_t)0, - (errorparameter_t)0 - ); - return; - } + // filter parameters + if(sixtop_vars.six2six_state!=SIX_IDLE){ + return; + } + if (neighbor==NULL){ + return; + } - // update state - sixtop_vars.six2six_state = SIX_SENDING_REMOVEREQUEST; + if (sixtop_vars.handler == SIX_HANDLER_NONE) { + // sxitop handler must not be NONE + return; + } - // declare ownership over that packet - pkt->creator = COMPONENT_SIXTOP_RES; - pkt->owner = COMPONENT_SIXTOP_RES; - - memcpy( - &(pkt->l2_nextORpreviousHop), - neighbor, - sizeof(open_addr_t) - ); - + // generate candidate cell list + if (code == IANA_6TOP_CMD_ADD){ + if (sixtop_candidateAddCellList(&frameID,cellList,numCells)==FALSE){ + return; + } else{ + // container to be define by SF, currently equals to frameID + container = frameID; + } + } + if (code == IANA_6TOP_CMD_DELETE){ + if (sixtop_candidateRemoveCellList(&frameID,cellList,neighbor,numCells)==FALSE){ + return; + } else{ + // container to be define by SF, currently equals to frameID + container = frameID; + } + } + + // get a free packet buffer + pkt = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP_RES); + if (pkt==NULL) { + openserial_printError( + COMPONENT_SIXTOP_RES, + ERR_NO_FREE_PACKET_BUFFER, + (errorparameter_t)0, + (errorparameter_t)0 + ); + return; + } - // create packet - len = 0; - len += processIE_prependScheduleIE(pkt,type,frameID, flag,cellList); - len += processIE_prependOpcodeIE(pkt,SIXTOP_REMOVE_SOFT_CELL_REQUEST); - processIE_prependMLMEIE(pkt,len); - - // indicate IEs present - pkt->l2_payloadIEpresent = TRUE; + // update state + sixtop_vars.six2six_state = SIX_SENDING_REQUEST; + + // take ownership + pkt->creator = COMPONENT_SIXTOP_RES; + pkt->owner = COMPONENT_SIXTOP_RES; + + memcpy(&(pkt->l2_nextORpreviousHop),neighbor,sizeof(open_addr_t)); + + // create packet + len = 0; + if (code == IANA_6TOP_CMD_ADD || IANA_6TOP_CMD_DELETE){ + len += processIE_prepend_sixCelllist(pkt,cellList); + // reserve space for container + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + // write header + *((uint8_t*)(pkt->payload)) = container; + len+=1; + // reserve space for numCells + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + // write header + *((uint8_t*)(pkt->payload)) = numCells; + len+=1; + } else { + // reserve space for container + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + // write header + *((uint8_t*)(pkt->payload)) = container; + len+=1; + } + + len += processIE_prepend_sixGeneralMessage(pkt,code); + len += processIE_prepend_sixSubID(pkt); + processIE_prepend_sixtopIE(pkt,len); - // send packet - sixtop_send(pkt); + // indicate IEs present + pkt->l2_payloadIEpresent = TRUE; - // update state - sixtop_vars.six2six_state = SIX_WAIT_REMOVEREQUEST_SENDDONE; + // send packet + sixtop_send(pkt); + + //update states + switch(code){ + case IANA_6TOP_CMD_ADD: + sixtop_vars.six2six_state = SIX_WAIT_ADDREQUEST_SENDDONE; + break; + case IANA_6TOP_CMD_DELETE: + sixtop_vars.six2six_state = SIX_WAIT_DELETEREQUEST_SENDDONE; + break; + case IANA_6TOP_CMD_COUNT: + sixtop_vars.six2six_state = SIX_WAIT_COUNTREQUEST_SENDDONE; + break; + case IANA_6TOP_CMD_LIST: + sixtop_vars.six2six_state = SIX_WAIT_LISTREQUEST_SENDDONE; + break; + case IANA_6TOP_CMD_CLEAR: + sixtop_vars.six2six_state = SIX_WAIT_CLEARREQUEST_SENDDONE; + break; + } - // arm timeout - opentimers_setPeriod( - sixtop_vars.timeoutTimerId, - TIME_MS, - SIX2SIX_TIMEOUT_MS - ); - opentimers_restart(sixtop_vars.timeoutTimerId); + // arm timeout + opentimers_setPeriod( + sixtop_vars.timeoutTimerId, + TIME_MS, + SIX2SIX_TIMEOUT_MS + ); + opentimers_restart(sixtop_vars.timeoutTimerId); } -void sixtop_removeCellByInfo(open_addr_t* neighbor,cellInfo_ht* cellInfo){ - OpenQueueEntry_t* pkt; - uint8_t len; - uint8_t type; - uint8_t frameID; - uint8_t flag; - cellInfo_ht cellList[SCHEDULEIEMAXNUMCELLS]; +void sixtop_addORremoveCellByInfo(uint8_t code,open_addr_t* neighbor,cellInfo_ht* cellInfo){ + OpenQueueEntry_t* pkt; + uint8_t len; + uint8_t frameID; + uint8_t container; + cellInfo_ht cellList[SCHEDULEIEMAXNUMCELLS]; - memset(cellList,0,sizeof(cellList)); + memset(cellList,0,sizeof(cellList)); - // filter parameters - if (sixtop_vars.six2six_state!=SIX_IDLE){ - return; - } - if (neighbor==NULL){ - return; - } - if (sixtop_vars.handler == SIX_HANDLER_NONE) { - // sixtop handler must not be NONE - return; - } + // filter parameters + if (sixtop_vars.six2six_state!=SIX_IDLE){ + return; + } + if (neighbor==NULL){ + return; + } + if (sixtop_vars.handler == SIX_HANDLER_NONE) { + // sixtop handler must not be NONE + return; + } - // set cell list. only the first one - type = 1; - frameID = SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE; - flag = 1; - memcpy(&(cellList[0]),cellInfo,sizeof(cellInfo_ht)); + // set cell list (only first one is to be removed) + frameID = SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE; + container = frameID; + memcpy(&(cellList[0]),cellInfo,sizeof(cellList)); - // get a free packet buffer - pkt = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP_RES); - if(pkt==NULL) { - openserial_printError( - COMPONENT_SIXTOP_RES, - ERR_NO_FREE_PACKET_BUFFER, - (errorparameter_t)0, - (errorparameter_t)0 - ); - return; - } + // get a free packet buffer + pkt = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP_RES); + if(pkt==NULL) { + openserial_printError( + COMPONENT_SIXTOP_RES, + ERR_NO_FREE_PACKET_BUFFER, + (errorparameter_t)0, + (errorparameter_t)0 + ); + return; + } - // update state - sixtop_vars.six2six_state = SIX_SENDING_REMOVEREQUEST; + // update state + sixtop_vars.six2six_state = SIX_SENDING_REQUEST; - // declare ownership over that packet - pkt->creator = COMPONENT_SIXTOP_RES; - pkt->owner = COMPONENT_SIXTOP_RES; + // declare ownership over that packet + pkt->creator = COMPONENT_SIXTOP_RES; + pkt->owner = COMPONENT_SIXTOP_RES; - memcpy( - &(pkt->l2_nextORpreviousHop), - neighbor, - sizeof(open_addr_t) - ); - + memcpy(&(pkt->l2_nextORpreviousHop),neighbor,sizeof(open_addr_t)); + + len = 0; + len += processIE_prepend_sixCelllist(pkt,cellList); + // reserve space for container + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + // write header + *((uint8_t*)(pkt->payload)) = container; + len+=1; + // reserve space for numCells + packetfunctions_reserveHeaderSize(pkt,sizeof(uint8_t)); + // write header + *((uint8_t*)(pkt->payload)) = 1; + len+=1; + + len += processIE_prepend_sixGeneralMessage(pkt,code); + len += processIE_prepend_sixSubID(pkt); + processIE_prepend_sixtopIE(pkt,len); - // create packet - len = 0; - len += processIE_prependScheduleIE(pkt,type,frameID, flag,cellList); - len += processIE_prependOpcodeIE(pkt,SIXTOP_REMOVE_SOFT_CELL_REQUEST); - processIE_prependMLMEIE(pkt,len); - - // indicate IEs present - pkt->l2_payloadIEpresent = TRUE; + // indicate IEs present + pkt->l2_payloadIEpresent = TRUE; - // send packet - sixtop_send(pkt); + // send packet + sixtop_send(pkt); - // update state - sixtop_vars.six2six_state = SIX_WAIT_REMOVEREQUEST_SENDDONE; + //update states + switch(code){ + case IANA_6TOP_CMD_ADD: + sixtop_vars.six2six_state = SIX_WAIT_ADDREQUEST_SENDDONE; + break; + case IANA_6TOP_CMD_DELETE: + sixtop_vars.six2six_state = SIX_WAIT_DELETEREQUEST_SENDDONE; + break; + } // arm timeout opentimers_setPeriod( @@ -407,7 +361,6 @@ void sixtop_removeCellByInfo(open_addr_t* neighbor,cellInfo_ht* cellInfo){ SIX2SIX_TIMEOUT_MS ); opentimers_restart(sixtop_vars.timeoutTimerId); - } //======= maintaning @@ -420,7 +373,7 @@ void sixtop_maintaining(uint16_t slotOffset,open_addr_t* neighbor){ linkInfo.choffset = info.channelOffset; linkInfo.linkoptions = info.link_type; sixtop_vars.handler = SIX_HANDLER_MAINTAIN; - sixtop_removeCellByInfo(neighbor, &linkInfo); + sixtop_addORremoveCellByInfo(IANA_6TOP_CMD_DELETE,neighbor, &linkInfo); } else { //should log this error @@ -531,78 +484,77 @@ void task_sixtopNotifSendDone() { } void task_sixtopNotifReceive() { - OpenQueueEntry_t* msg; - uint16_t lenIE; - - // get received packet from openqueue - msg = openqueue_sixtopGetReceivedPacket(); - if (msg==NULL) { - openserial_printCritical( - COMPONENT_SIXTOP, - ERR_NO_RECEIVED_PACKET, - (errorparameter_t)0, - (errorparameter_t)0 - ); - return; - } - - // take ownership - msg->owner = COMPONENT_SIXTOP; - - // process the header IEs - lenIE=0; - if( - msg->l2_frameType == IEEE154_TYPE_DATA && - msg->l2_payloadIEpresent == TRUE && - sixtop_processIEs(msg, &lenIE) == FALSE - ) { - // free the packet's RAM memory - openqueue_freePacketBuffer(msg); - //log error - return; - } - - // toss the header IEs - packetfunctions_tossHeader(msg,lenIE); - - // update neighbor statistics - neighbors_indicateRx( - &(msg->l2_nextORpreviousHop), - msg->l1_rssi, - &msg->l2_asn, - msg->l2_joinPriorityPresent, - msg->l2_joinPriority - ); + OpenQueueEntry_t* msg; + uint16_t lenIE; + // get received packet from openqueue + msg = openqueue_sixtopGetReceivedPacket(); + if (msg==NULL) { + openserial_printCritical( + COMPONENT_SIXTOP, + ERR_NO_RECEIVED_PACKET, + (errorparameter_t)0, + (errorparameter_t)0 + ); + return; + } - // reset it to avoid race conditions with this var. - msg->l2_joinPriorityPresent = FALSE; + // take ownership + msg->owner = COMPONENT_SIXTOP; + + // process the header IEs + lenIE=0; + if( + msg->l2_frameType == IEEE154_TYPE_DATA && + msg->l2_payloadIEpresent == TRUE && + sixtop_processIEs(msg, &lenIE) == FALSE + ) { + // free the packet's RAM memory + openqueue_freePacketBuffer(msg); + //log error + return; + } - // send the packet up the stack, if it qualifies - switch (msg->l2_frameType) { - case IEEE154_TYPE_BEACON: - case IEEE154_TYPE_DATA: - case IEEE154_TYPE_CMD: - if (msg->length>0) { + // toss the header IEs + packetfunctions_tossHeader(msg,lenIE); + + // update neighbor statistics + neighbors_indicateRx( + &(msg->l2_nextORpreviousHop), + msg->l1_rssi, + &msg->l2_asn, + msg->l2_joinPriorityPresent, + msg->l2_joinPriority + ); + + // reset it to avoid race conditions with this var. + msg->l2_joinPriorityPresent = FALSE; + + // send the packet up the stack, if it qualifies + switch (msg->l2_frameType) { + case IEEE154_TYPE_BEACON: + case IEEE154_TYPE_DATA: + case IEEE154_TYPE_CMD: + if (msg->length>0) { // send to upper layer iphc_receive(msg); - } else { + } else { // free up the RAM openqueue_freePacketBuffer(msg); - } - break; - case IEEE154_TYPE_ACK: - default: - // free the packet's RAM memory - openqueue_freePacketBuffer(msg); - // log the error - openserial_printError( + } + break; + case IEEE154_TYPE_ACK: + default: + // free the packet's RAM memory + openqueue_freePacketBuffer(msg); + // log the error + openserial_printError( COMPONENT_SIXTOP, ERR_MSG_UNKNOWN_TYPE, (errorparameter_t)msg->l2_frameType, (errorparameter_t)0 - ); - break; - } + ); + break; + } } //======= debugging @@ -646,6 +598,10 @@ bool debugPrint_kaPeriod() { return TRUE; } +void sixtop_setIsResponseEnabled(bool isEnabled){ + sixtop_vars.isResponseEnabled = isEnabled; +} + //=========================== private ========================================= /** @@ -907,8 +863,8 @@ void sixtop_six2six_sendDone(OpenQueueEntry_t* msg, owerror_t error){ memset(cellList,0,SCHEDULEIEMAXNUMCELLS*sizeof(cellInfo_ht)); - ptr = msg->l2_scheduleIE_cellObjects; - numOfCells = msg->l2_scheduleIE_numOfCells; + ptr = msg->l2_sixtop_cellObjects; + numOfCells = msg->l2_sixtop_numOfCells; msg->owner = COMPONENT_SIXTOP_RES; if(error == E_FAIL) { @@ -917,388 +873,447 @@ void sixtop_six2six_sendDone(OpenQueueEntry_t* msg, owerror_t error){ return; } - switch (sixtop_vars.six2six_state) { - case SIX_WAIT_ADDREQUEST_SENDDONE: - sixtop_vars.six2six_state = SIX_WAIT_ADDRESPONSE; - break; - case SIX_WAIT_ADDRESPONSE_SENDDONE: - if (error == E_SUCCESS && numOfCells > 0){ - for (i=0;il2_scheduleIE_frameID, - numOfCells, - cellList, - &(msg->l2_nextORpreviousHop), - sixtop_vars.six2six_state); - } - sixtop_vars.six2six_state = SIX_IDLE; - break; - case SIX_WAIT_REMOVEREQUEST_SENDDONE: - if(error == E_SUCCESS && numOfCells > 0){ - for (i=0;il2_sixtop_returnCode == IANA_6TOP_RC_SUCCESS && error == E_SUCCESS){ + if ( + msg->l2_sixtop_requestCommand == IANA_6TOP_CMD_ADD || + msg->l2_sixtop_requestCommand == IANA_6TOP_CMD_DELETE + ){ + if (numOfCells>0){ + for (i=0;il2_sixtop_requestCommand == IANA_6TOP_CMD_ADD){ + sixtop_addCellsByState( + msg->l2_sixtop_frameID, + cellList, + &(msg->l2_nextORpreviousHop), + sixtop_vars.six2six_state); + } else { + sixtop_removeCellsByState( + msg->l2_sixtop_frameID, + cellList, + &(msg->l2_nextORpreviousHop)); + } + } + + } else{ + if (msg->l2_sixtop_requestCommand == IANA_6TOP_CMD_CLEAR){ + schedule_removeAllCells(msg->l2_sixtop_frameID, + &(msg->l2_nextORpreviousHop)); + } } - sixtop_removeCellsByState( - msg->l2_scheduleIE_frameID, - numOfCells, - cellList, - &(msg->l2_nextORpreviousHop) + } + + sixtop_vars.six2six_state = SIX_IDLE; + sixtop_vars.handler = SIX_HANDLER_NONE; + opentimers_stop(sixtop_vars.timeoutTimerId); + + if (sixtop_vars.handler == SIX_HANDLER_MAINTAIN){ + sixtop_request( + IANA_6TOP_CMD_DELETE, + &(msg->l2_nextORpreviousHop), + 1 ); - } - sixtop_vars.six2six_state = SIX_IDLE; - opentimers_stop(sixtop_vars.timeoutTimerId); - leds_debug_off(); - if (sixtop_vars.handler == SIX_HANDLER_MAINTAIN){ - sixtop_addCells(&(msg->l2_nextORpreviousHop),1); - sixtop_vars.handler = SIX_HANDLER_NONE; - } - break; - default: - //log error - break; - } + sixtop_request(IANA_6TOP_CMD_ADD,&(msg->l2_nextORpreviousHop),1); + sixtop_vars.handler = SIX_HANDLER_NONE; + } + break; + default: + //log error + sixtop_vars.six2six_state = SIX_IDLE; + break; + } - // discard reservation packets this component has created - openqueue_freePacketBuffer(msg); + // discard reservation packets this component has created + openqueue_freePacketBuffer(msg); } port_INLINE bool sixtop_processIEs(OpenQueueEntry_t* pkt, uint16_t * lenIE) { - uint8_t ptr; - uint8_t temp_8b,gr_elem_id,subid; - uint16_t temp_16b,len,sublen; - opcode_IE_ht opcode_ie; - bandwidth_IE_ht bandwidth_ie; - schedule_IE_ht schedule_ie; - - ptr=0; - memset(&opcode_ie,0,sizeof(opcode_IE_ht)); - memset(&bandwidth_ie,0,sizeof(bandwidth_IE_ht)); - memset(&schedule_ie,0,sizeof(schedule_IE_ht)); + uint8_t ptr; + uint8_t temp_8b,gr_elem_id,subid; + uint16_t temp_16b,len,sublen; + uint8_t version,commandIdORcode; + uint8_t sfId; + + ptr=0; - //candidate IE header if type ==0 header IE if type==1 payload IE - temp_8b = *((uint8_t*)(pkt->payload)+ptr); - ptr++; - temp_16b = temp_8b + ((*((uint8_t*)(pkt->payload)+ptr))<<8); - ptr++; - *lenIE = ptr; - if( - (temp_16b & IEEE802154E_DESC_TYPE_PAYLOAD_IE) == - IEEE802154E_DESC_TYPE_PAYLOAD_IE - ){ - //payload IE - last bit is 1 - len = temp_16b & IEEE802154E_DESC_LEN_PAYLOAD_IE_MASK; - gr_elem_id = - (temp_16b & IEEE802154E_DESC_GROUPID_PAYLOAD_IE_MASK)>> - IEEE802154E_DESC_GROUPID_PAYLOAD_IE_SHIFT; - }else { - //header IE - last bit is 0 - len = temp_16b & IEEE802154E_DESC_LEN_HEADER_IE_MASK; - gr_elem_id = (temp_16b & IEEE802154E_DESC_ELEMENTID_HEADER_IE_MASK)>> - IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT; - } + //candidate IE header if type ==0 header IE if type==1 payload IE + temp_8b = *((uint8_t*)(pkt->payload)+ptr); + ptr++; + temp_16b = temp_8b + ((*((uint8_t*)(pkt->payload)+ptr))<<8); + ptr++; + *lenIE = ptr; + if( + (temp_16b & IEEE802154E_DESC_TYPE_PAYLOAD_IE) == + IEEE802154E_DESC_TYPE_PAYLOAD_IE + ){ + //payload IE - last bit is 1 + len = temp_16b & IEEE802154E_DESC_LEN_PAYLOAD_IE_MASK; + gr_elem_id = + (temp_16b & IEEE802154E_DESC_GROUPID_PAYLOAD_IE_MASK)>> + IEEE802154E_DESC_GROUPID_PAYLOAD_IE_SHIFT; + }else { + //header IE - last bit is 0 + len = temp_16b & IEEE802154E_DESC_LEN_HEADER_IE_MASK; + gr_elem_id = (temp_16b & IEEE802154E_DESC_ELEMENTID_HEADER_IE_MASK)>> + IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT; + } - *lenIE += len; - //now determine sub elements if any - switch(gr_elem_id){ - //this is the only groupID that we parse. See page 82. - case IEEE802154E_MLME_IE_GROUPID: + *lenIE += len; + //now determine sub elements if any + switch(gr_elem_id){ + //this is the only groupID that we parse. See page 82. + case IEEE802154E_MLME_IE_GROUPID: //IE content can be any of the sub-IEs. Parse and see which do{ - //read sub IE header - temp_8b = *((uint8_t*)(pkt->payload)+ptr); - ptr = ptr + 1; - temp_16b = temp_8b + ((*((uint8_t*)(pkt->payload)+ptr))<<8); - ptr = ptr + 1; - len = len - 2; //remove header fields len - if( - (temp_16b & IEEE802154E_DESC_TYPE_LONG) == - IEEE802154E_DESC_TYPE_LONG - ){ - //long sub-IE - last bit is 1 - sublen = temp_16b & IEEE802154E_DESC_LEN_LONG_MLME_IE_MASK; - subid= - (temp_16b & IEEE802154E_DESC_SUBID_LONG_MLME_IE_MASK)>> - IEEE802154E_DESC_SUBID_LONG_MLME_IE_SHIFT; - } else { - //short IE - last bit is 0 - sublen = temp_16b & IEEE802154E_DESC_LEN_SHORT_MLME_IE_MASK; - subid = (temp_16b & IEEE802154E_DESC_SUBID_SHORT_MLME_IE_MASK)>> - IEEE802154E_DESC_SUBID_SHORT_MLME_IE_SHIFT; - } - switch(subid){ - case MLME_IE_SUBID_OPCODE: - processIE_retrieveOpcodeIE(pkt,&ptr,&opcode_ie); - break; - case MLME_IE_SUBID_BANDWIDTH: - processIE_retrieveBandwidthIE(pkt,&ptr,&bandwidth_ie); - break; - case MLME_IE_SUBID_TRACKID: - break; - case MLME_IE_SUBID_SCHEDULE: - processIE_retrieveScheduleIE(pkt,&ptr,&schedule_ie); - break; - default: - return FALSE; - break; + //read sub IE header + temp_8b = *((uint8_t*)(pkt->payload)+ptr); + ptr = ptr + 1; + temp_16b = temp_8b + ((*((uint8_t*)(pkt->payload)+ptr))<<8); + ptr = ptr + 1; + len = len - 2; //remove header fields len + if( + (temp_16b & IEEE802154E_DESC_TYPE_LONG) == + IEEE802154E_DESC_TYPE_LONG + ){ + //long sub-IE - last bit is 1 + sublen = temp_16b & IEEE802154E_DESC_LEN_LONG_MLME_IE_MASK; + subid= + (temp_16b & IEEE802154E_DESC_SUBID_LONG_MLME_IE_MASK)>> + IEEE802154E_DESC_SUBID_LONG_MLME_IE_SHIFT; + } else { + //short IE - last bit is 0 + sublen = temp_16b & IEEE802154E_DESC_LEN_SHORT_MLME_IE_MASK; + subid = (temp_16b & IEEE802154E_DESC_SUBID_SHORT_MLME_IE_MASK)>> + IEEE802154E_DESC_SUBID_SHORT_MLME_IE_SHIFT; + } + switch(subid){ + case IANA_6TOP_SUBIE_ID: + temp_8b = *((uint8_t*)(pkt->payload)+ptr); + ptr = ptr + 1; + // get 6P version and command ID + version = temp_8b & 0x0f; + commandIdORcode = (temp_8b >> 4) & 0x0f; + // get sf_id + sfId = *((uint8_t*)(pkt->payload)+ptr); + ptr = ptr + 1; + sixtop_notifyReceiveCommand(version,commandIdORcode,sfId,ptr,sublen-2,pkt); + ptr += sublen-2; + break; + default: + return FALSE; + } + len = len - sublen; + } while(len>0); + break; + case SIXTOP_IE_GROUPID: + subid = *((uint8_t*)(pkt->payload)+ptr); + ptr += 1; + sublen = len - 1; + switch(subid){ + case IANA_6TOP_SUBIE_ID: + temp_8b = *((uint8_t*)(pkt->payload)+ptr); + ptr = ptr + 1; + // get 6P version and command ID + version = temp_8b & 0x0f; + commandIdORcode = (temp_8b >> 4) & 0x0f; + // get sf_id + sfId = *((uint8_t*)(pkt->payload)+ptr); + ptr = ptr + 1; + sixtop_notifyReceiveCommand(version,commandIdORcode,sfId,ptr,sublen-2,pkt); + ptr += sublen-2; + break; + default: + return FALSE; } - len = len - sublen; - } while(len>0); - - break; + break; default: - *lenIE = 0;//no header or not recognized. - return FALSE; - } - if (*lenIE>127) { - // log the error - openserial_printError(COMPONENT_IEEE802154E,ERR_HEADER_TOO_LONG, + *lenIE = 0;//no header or not recognized. + return FALSE; + } + if (*lenIE>127) { + // log the error + openserial_printError(COMPONENT_IEEE802154E,ERR_HEADER_TOO_LONG, (errorparameter_t)*lenIE, (errorparameter_t)1); - } - - if(*lenIE>0) { - sixtop_notifyReceiveCommand(&opcode_ie, - &bandwidth_ie, - &schedule_ie, - &(pkt->l2_nextORpreviousHop)); - } - - return TRUE; + } + return TRUE; } void sixtop_notifyReceiveCommand( - opcode_IE_ht* opcode_ie, - bandwidth_IE_ht* bandwidth_ie, - schedule_IE_ht* schedule_ie, - open_addr_t* addr){ - switch(opcode_ie->opcode){ - case SIXTOP_SOFT_CELL_REQ: - if(sixtop_vars.six2six_state == SIX_IDLE) - { - sixtop_vars.six2six_state = SIX_ADDREQUEST_RECEIVED; - //received uResCommand is reserve link request - sixtop_notifyReceiveLinkRequest(bandwidth_ie,schedule_ie,addr); - } - break; - case SIXTOP_SOFT_CELL_RESPONSE: - if(sixtop_vars.six2six_state == SIX_WAIT_ADDRESPONSE){ - sixtop_vars.six2six_state = SIX_ADDRESPONSE_RECEIVED; - //received uResCommand is reserve link response - sixtop_notifyReceiveLinkResponse(bandwidth_ie,schedule_ie,addr); - } - break; - case SIXTOP_REMOVE_SOFT_CELL_REQUEST: - if(sixtop_vars.six2six_state == SIX_IDLE){ - sixtop_vars.six2six_state = SIX_REMOVEREQUEST_RECEIVED; - //received uResComand is remove link request - sixtop_notifyReceiveRemoveLinkRequest(schedule_ie,addr); - } - break; - default: - // log the error - break; - } -} - -void sixtop_notifyReceiveLinkRequest( - bandwidth_IE_ht* bandwidth_ie, - schedule_IE_ht* schedule_ie, - open_addr_t* addr){ - - uint8_t bw,numOfcells,frameID; - bool scheduleCellSuccess; - - frameID = schedule_ie->frameID; - numOfcells = schedule_ie->numberOfcells; - bw = bandwidth_ie->numOfLinks; - - // need to check whether the links are available to be scheduled. - if(bw > numOfcells || - schedule_ie->frameID != bandwidth_ie->slotframeID || - sixtop_areAvailableCellsToBeScheduled(frameID, - numOfcells, - schedule_ie->cellList, - bw) == FALSE){ - scheduleCellSuccess = FALSE; - } else { - scheduleCellSuccess = TRUE; - } - - //call link response command - sixtop_linkResponse(scheduleCellSuccess, - addr, - bandwidth_ie->numOfLinks, - schedule_ie); -} - -void sixtop_linkResponse( - bool scheduleCellSuccess, - open_addr_t* tempNeighbor, - uint8_t bandwidth, - schedule_IE_ht* schedule_ie){ - - OpenQueueEntry_t* sixtopPkt; - uint8_t len=0; - uint8_t bw; - uint8_t type,frameID,flag; - cellInfo_ht* cellList; - - // get parameters for scheduleIE - type = schedule_ie->type; - frameID = schedule_ie->frameID; - flag = schedule_ie->flag; - cellList = schedule_ie->cellList; - - // get a free packet buffer - sixtopPkt = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP_RES); - - if(sixtopPkt==NULL) { - openserial_printError(COMPONENT_SIXTOP_RES,ERR_NO_FREE_PACKET_BUFFER, - (errorparameter_t)0, - (errorparameter_t)0); - return; - } + uint8_t version, + uint8_t commandIdORcode, + uint8_t sfId, + uint8_t ptr, + uint8_t length, + OpenQueueEntry_t* pkt +){ + uint8_t code; + uint8_t frameID; + uint8_t numOfCells; + uint16_t count; + cellInfo_ht cellList[SCHEDULEIEMAXNUMCELLS]; + OpenQueueEntry_t* response_pkt; + uint8_t len = 0; + uint8_t container; - // changing state to resLinkRespone command - sixtop_vars.six2six_state = SIX_SENDING_ADDRESPONSE; + memset(cellList,0,sizeof(cellList)); - // declare ownership over that packet - sixtopPkt->creator = COMPONENT_SIXTOP_RES; - sixtopPkt->owner = COMPONENT_SIXTOP_RES; - - memcpy(&(sixtopPkt->l2_nextORpreviousHop),tempNeighbor,sizeof(open_addr_t)); - // set SubFrameAndLinkIE - len += processIE_prependScheduleIE(sixtopPkt, - type, - frameID, - flag, - cellList); + // get a free packet buffer + response_pkt = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP_RES); + if (response_pkt==NULL) { + openserial_printError( + COMPONENT_SIXTOP_RES, + ERR_NO_FREE_PACKET_BUFFER, + (errorparameter_t)0, + (errorparameter_t)0 + ); + return; + } + + // take ownership + response_pkt->creator = COMPONENT_SIXTOP_RES; + response_pkt->owner = COMPONENT_SIXTOP_RES; - if(scheduleCellSuccess){ - bw = bandwidth; - } else { - bw = 0; - } - //add BandwidthIE - len += processIE_prependBandwidthIE(sixtopPkt,bw,frameID); - //add opcodeIE - len += processIE_prependOpcodeIE(sixtopPkt,SIXTOP_SOFT_CELL_RESPONSE); - //add IE header - processIE_prependMLMEIE(sixtopPkt,len); + memcpy(&(response_pkt->l2_nextORpreviousHop), + &(pkt->l2_nextORpreviousHop), + sizeof(open_addr_t) + ); - //I has an IE in my payload - sixtopPkt->l2_payloadIEpresent = TRUE; - - sixtop_send(sixtopPkt); - - sixtop_vars.six2six_state = SIX_WAIT_ADDRESPONSE_SENDDONE; -} - -void sixtop_notifyReceiveLinkResponse( - bandwidth_IE_ht* bandwidth_ie, - schedule_IE_ht* schedule_ie, - open_addr_t* addr){ - - uint8_t bw,numOfcells,frameID; - - frameID = schedule_ie->frameID; - numOfcells = schedule_ie->numberOfcells; - bw = bandwidth_ie->numOfLinks; - - if(bw == 0){ - // link request failed - // todo- should inform some one - return; - } else { - // need to check whether the links are available to be scheduled. - if(bw != numOfcells || - schedule_ie->frameID != bandwidth_ie->slotframeID || - sixtop_areAvailableCellsToBeScheduled(frameID, - numOfcells, - schedule_ie->cellList, - bw) == FALSE){ - // link request failed,inform uplayer - } else { - sixtop_addCellsByState(frameID, - bw, - schedule_ie->cellList, - addr, - sixtop_vars.six2six_state); - // link request success,inform uplayer - } - } - leds_debug_off(); - sixtop_vars.six2six_state = SIX_IDLE; - sixtop_vars.handler = SIX_HANDLER_NONE; - - opentimers_stop(sixtop_vars.timeoutTimerId); + //===== if the version or sfID are correct + if (version != IANA_6TOP_6P_VERSION || sfId != SFID_SF0){ + if (version != IANA_6TOP_6P_VERSION){ + code = IANA_6TOP_RC_VER_ERR; + } else { + code = IANA_6TOP_RC_SFID_ERR; + } + } else { + //====== the version and sfID are correct + //------ if this is a command + if ( + commandIdORcode == IANA_6TOP_CMD_ADD || + commandIdORcode == IANA_6TOP_CMD_DELETE || + commandIdORcode == IANA_6TOP_CMD_COUNT || + commandIdORcode == IANA_6TOP_CMD_LIST || + commandIdORcode == IANA_6TOP_CMD_CLEAR + ){ + // if I am already in a 6top transactions + if (sixtop_vars.six2six_state != SIX_IDLE){ + code = IANA_6TOP_RC_ERR; + } else { + sixtop_vars.six2six_state = SIX_REQUEST_RECEIVED; + + switch(commandIdORcode){ + case IANA_6TOP_CMD_ADD: + case IANA_6TOP_CMD_DELETE: + numOfCells = *((uint8_t*)(pkt->payload)+ptr); + container = *((uint8_t*)(pkt->payload)+ptr+1); + frameID = container; + processIE_retrieve_sixCelllist(pkt,ptr+2,length-2,cellList); + if ( + ( + commandIdORcode == IANA_6TOP_CMD_ADD && + sixtop_areAvailableCellsToBeScheduled(frameID,numOfCells,cellList) + ) || + ( + commandIdORcode == IANA_6TOP_CMD_DELETE && + sixtop_areAvailableCellsToBeRemoved(frameID,numOfCells,cellList,&(pkt->l2_nextORpreviousHop)) + ) + ){ + code = IANA_6TOP_RC_SUCCESS; + len += processIE_prepend_sixCelllist(response_pkt,cellList); + } else { + code = IANA_6TOP_RC_RESET; + } + break; + case IANA_6TOP_CMD_COUNT: + container = *((uint8_t*)(pkt->payload)+ptr); + frameID = container; + count = schedule_getCellsCounts(frameID, + CELLTYPE_RX, + &(pkt->l2_nextORpreviousHop)); + code = IANA_6TOP_RC_SUCCESS; + packetfunctions_reserveHeaderSize(response_pkt,2); + response_pkt->payload[0] = count & 0xFF; + response_pkt->payload[1] = (count>>8) & 0xFF; + len = 2; + break; + case IANA_6TOP_CMD_LIST: + container = *((uint8_t*)(pkt->payload)+ptr); + frameID = container; + numOfCells = sixtop_getCelllist(frameID, + &(pkt->l2_nextORpreviousHop), + cellList); + code = IANA_6TOP_RC_SUCCESS; + if (numOfCells>0){ + len += processIE_prepend_sixCelllist(response_pkt,cellList); + } + break; + case IANA_6TOP_CMD_CLEAR: + container = *((uint8_t*)(pkt->payload)+ptr); + frameID = container; + schedule_removeAllCells(frameID, + &(pkt->l2_nextORpreviousHop)); + code = IANA_6TOP_RC_SUCCESS; + break; + } + } + response_pkt->l2_sixtop_requestCommand = commandIdORcode; + response_pkt->l2_sixtop_frameID = frameID; + + len += processIE_prepend_sixGeneralMessage(response_pkt,code); + len += processIE_prepend_sixSubID(response_pkt); + processIE_prepend_sixtopIE(response_pkt,len); + // indicate IEs present + response_pkt->l2_payloadIEpresent = TRUE; + if (sixtop_vars.isResponseEnabled){ + // send packet + sixtop_send(response_pkt); + } + // update state + sixtop_vars.six2six_state = SIX_WAIT_RESPONSE_SENDDONE; + // arm timeout + opentimers_setPeriod( + sixtop_vars.timeoutTimerId, + TIME_MS, + SIX2SIX_TIMEOUT_MS + ); + opentimers_restart(sixtop_vars.timeoutTimerId); + } else { + //------ if this is a return code + // if the code is SUCCESS + if (commandIdORcode==IANA_6TOP_RC_SUCCESS){ + switch(sixtop_vars.six2six_state){ + case SIX_WAIT_ADDRESPONSE: + case SIX_WAIT_DELETERESPONSE: + processIE_retrieve_sixCelllist(pkt,ptr,length,cellList); + // always default frameID + frameID = SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE; + if (sixtop_vars.six2six_state == SIX_WAIT_ADDRESPONSE){ + sixtop_addCellsByState(frameID, + cellList, + &(pkt->l2_nextORpreviousHop), + sixtop_vars.six2six_state + ); + } else { + sixtop_removeCellsByState( + frameID, + cellList, + &(pkt->l2_nextORpreviousHop)); + } + break; + case SIX_WAIT_COUNTRESPONSE: + count = *((uint8_t*)(pkt->payload)+ptr); + ptr += 1; + count |= (*((uint8_t*)(pkt->payload)+ptr))<<8; +#ifdef GOLDEN_IMAGE_ROOT + openserial_printInfo(COMPONENT_SIXTOP,ERR_SIXTOP_COUNT, + (errorparameter_t)count, + (errorparameter_t)sixtop_vars.six2six_state); +#endif + break; + case SIX_WAIT_LISTRESPONSE: + processIE_retrieve_sixCelllist(pkt,ptr,length,cellList); +#ifdef GOLDEN_IMAGE_ROOT + // print out first two cells in the list + openserial_printInfo(COMPONENT_SIXTOP,ERR_SIXTOP_LIST, + (errorparameter_t)cellList[0].tsNum, + (errorparameter_t)cellList[1].tsNum); +#endif + break; + case SIX_WAIT_CLEARRESPONSE: + + break; + default: + code = IANA_6TOP_RC_ERR; + } + } else { + // TBD... + } +#ifdef GOLDEN_IMAGE_ROOT + openserial_printInfo(COMPONENT_SIXTOP,ERR_SIXTOP_RETURNCODE, + (errorparameter_t)commandIdORcode, + (errorparameter_t)sixtop_vars.six2six_state); +#endif + sixtop_vars.six2six_state = SIX_IDLE; + sixtop_vars.handler = SIX_HANDLER_NONE; + opentimers_stop(sixtop_vars.timeoutTimerId); + } + } } -void sixtop_notifyReceiveRemoveLinkRequest( - schedule_IE_ht* schedule_ie, - open_addr_t* addr){ - - uint8_t numOfCells,frameID; - cellInfo_ht* cellList; - - numOfCells = schedule_ie->numberOfcells; - frameID = schedule_ie->frameID; - cellList = schedule_ie->cellList; - - leds_debug_on(); - - sixtop_removeCellsByState(frameID,numOfCells,cellList,addr); - - if (sixtop_vars.handler == SIX_HANDLER_OTF) { - // notify OTF - otf_notif_removedCell(); - } else { - if (sixtop_vars.handler == SIX_HANDLER_MAINTAIN) { - // if sixtop remove request handler is - sixtop_vars.handler = SIX_HANDLER_NONE; - } else { - // if any other handlers exist +uint8_t sixtop_getCelllist( + uint8_t frameID, + open_addr_t* neighbor, + cellInfo_ht* cellList + ){ + uint8_t i=0; + scheduleEntry_t* scheduleWalker; + scheduleEntry_t* currentEntry; + + INTERRUPT_DECLARATION(); + DISABLE_INTERRUPTS(); + + if (frameID != SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE){ + ENABLE_INTERRUPTS(); + return 0; + } + + memset(cellList,0,SCHEDULEIEMAXNUMCELLS*sizeof(cellInfo_ht)); + + scheduleWalker = schedule_getCurrentScheduleEntry(); + currentEntry = scheduleWalker; + do { + if(packetfunctions_sameAddress(&(scheduleWalker->neighbor),neighbor)){ + cellList[i].tsNum = scheduleWalker->slotOffset; + cellList[i].choffset = scheduleWalker->channelOffset; + cellList[i].linkoptions = scheduleWalker->type; + i++; } - } + scheduleWalker = scheduleWalker->next; + }while(scheduleWalker!=currentEntry && i!=SCHEDULEIEMAXNUMCELLS); - sixtop_vars.six2six_state = SIX_IDLE; - - leds_debug_off(); + ENABLE_INTERRUPTS(); + return i; } //======= helper functions bool sixtop_candidateAddCellList( - uint8_t* type, uint8_t* frameID, - uint8_t* flag, - cellInfo_ht* cellList + cellInfo_ht* cellList, + uint8_t requiredCells ){ frameLength_t i; uint8_t counter; uint8_t numCandCells; - *type = 1; *frameID = schedule_getFrameHandle(); - *flag = 1; // the cells listed in cellList are available to be schedule. numCandCells=0; for(counter=0;counterSCHEDULEIEMAXNUMCELLS || numOfCells>SCHEDULEIEMAXNUMCELLS){ + if(bw == 0 || bw>SCHEDULEIEMAXNUMCELLS){ // log wrong parameter error TODO available = FALSE; @@ -1450,11 +1454,11 @@ bool sixtop_areAvailableCellsToBeScheduled( cellList[i].linkoptions = CELLTYPE_OFF; } i++; - }while(i0); + }while(i0); if(bw==0){ //the rest link will not be scheduled, mark them as off type - while(iSCHEDULEIEMAXNUMCELLS){ + // log wrong parameter error TODO + available = FALSE; + } else { + do { + schedule_getSlotInfo(cellList[i].tsNum,neighbor,&info); + if(info.link_type == CELLTYPE_RX){ + bw--; + } else { + cellList[i].linkoptions = CELLTYPE_OFF; + } + i++; + }while(i0); + + if(bw==0){ + //the rest link will not be scheduled, mark them as off type + while(iowner = COMPONENT_IPHC; - - // by default, the "next header" field is carried inline - nh=IPHC_NH_INLINE; - - // error checking - if (idmanager_getIsDAGroot()==TRUE && - packetfunctions_isAllRoutersMulticast(&(msg->l3_destinationAdd))==FALSE) { - openserial_printCritical(COMPONENT_IPHC,ERR_BRIDGE_MISMATCH, - (errorparameter_t)0, - (errorparameter_t)0); - return E_FAIL; - } + OpenQueueEntry_t* msg, + ipv6_header_iht* ipv6_outer_header, + ipv6_header_iht* ipv6_inner_header, + rpl_option_ht* rpl_option, + uint32_t* flow_label, + uint8_t* rh3_copy, + uint8_t rh3_length, + uint8_t fw_SendOrfw_Rcv + ) { + open_addr_t temp_dest_prefix; + open_addr_t temp_dest_mac64b; + open_addr_t temp_src_prefix; + open_addr_t temp_src_mac64b; + uint8_t sam; + // take ownership over the packet + msg->owner = COMPONENT_IPHC; - //discard the packet.. hop limit reached. - if (ipv6_outer_header->hop_limit==0) { - openserial_printError(COMPONENT_IPHC,ERR_HOP_LIMIT_REACHED, + // error checking + if (idmanager_getIsDAGroot()==TRUE && + packetfunctions_isAllRoutersMulticast(&(msg->l3_destinationAdd))==FALSE) { + openserial_printCritical(COMPONENT_IPHC,ERR_BRIDGE_MISMATCH, (errorparameter_t)0, (errorparameter_t)0); - return E_FAIL; - } + return E_FAIL; + } - m = IPHC_M_NO; - - packetfunctions_ip128bToMac64b(&(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); - //xv poipoi -- get the src prefix as well - packetfunctions_ip128bToMac64b(&(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(&temp_dest_prefix,&temp_src_prefix)) { - //dest and src on same prefix - if (neighbors_isStableNeighbor(&(msg->l3_destinationAdd))) { - //if direct neighbors, MAC nextHop and IP destination indicate same node - //the source can be ME or another who I am relaying from. If its me then SAM is elided, - //if not SAM is 64b address - if (fw_SendOrfw_Rcv==PCKTFORWARD){ - sam = IPHC_SAM_64B; //case forwarding a packet - p_src = &temp_src_mac64b; - //poipoi xv forcing elided addresses on src routing, this needs to be fixed so any type of address should be supported. - } else if (fw_SendOrfw_Rcv==PCKTSEND){ - sam = IPHC_SAM_ELIDED; - p_src = NULL; + //discard the packet.. hop limit reached. + if (ipv6_outer_header->src.type != ADDR_NONE){ + // there is IPinIP check hop limit in ip in ip encapsulation + if (ipv6_outer_header->hop_limit==0){ + openserial_printError(COMPONENT_IPHC,ERR_HOP_LIMIT_REACHED, + (errorparameter_t)0, + (errorparameter_t)0); + return E_FAIL; } else { - openserial_printCritical(COMPONENT_IPHC,ERR_INVALID_FWDMODE, - (errorparameter_t)0, - (errorparameter_t)0); - } - dam = IPHC_DAM_ELIDED; - p_dest = NULL; - } else { - //else, not a direct neighbour 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(&(msg->l3_destinationAdd))==FALSE){ - if(ipv6_outer_header->next_header!=IANA_IPv6ROUTE){ - sam = IPHC_SAM_128B; - dam = IPHC_DAM_128B; - p_dest = &(msg->l3_destinationAdd); - p_src = &(msg->l3_sourceAdd); - }else{ - //source routing - sam = IPHC_SAM_128B; - dam = IPHC_DAM_ELIDED; //poipoi xv not true, should not be elided. - p_dest = NULL; - p_src = &(msg->l3_sourceAdd); - } - } 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); - } - } - //check if we are forwarding a packet and it comes with the next header compressed. We want to preserve that state in the following hop. - -// if ((fw_SendOrfw_Rcv==PCKTFORWARD) && ipv6_outer_header->next_header_compressed) nh=IPHC_NH_COMPRESSED; - // the next header will be compressed if it's set to "compressed" - if (ipv6_outer_header->next_header_compressed) nh=IPHC_NH_COMPRESSED; - - // decrement the packet's hop limit - ipv6_outer_header->hop_limit--; - - if(packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd))==FALSE) { - next_header=*((uint8_t*)(msg->payload)); // next_header is nhc ipv6 header - } else { - next_header=msg->l4_protocol; - } + // decrement the packet's hop limit + ipv6_outer_header->hop_limit--; + } + } else { + if (ipv6_inner_header->hop_limit==0) { + openserial_printError(COMPONENT_IPHC,ERR_HOP_LIMIT_REACHED, + (errorparameter_t)0, + (errorparameter_t)0); + return E_FAIL; + } else { + // decrement the packet's hop limit + ipv6_inner_header->hop_limit--; + } + } - //prepend Option hop by hop header except when src routing and dst is not 0xffff - //-- this is a little trick as src routing is using an option header set to 0x00 - if (rpl_option->optionType==RPL_HOPBYHOP_HEADER_OPTION_TYPE - && packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd))==FALSE - ){ - iphc_prependIPv6HopByHopHeader(msg, msg->l4_protocol, nh, rpl_option); - //change nh to point to the newly added header - next_header=IANA_IPv6HOPOPT;// use 0x00 as NH to indicate option header -- see rfc 2460 - } - //then regular header - + packetfunctions_ip128bToMac64b(&(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); + //xv poipoi -- get the src prefix as well + packetfunctions_ip128bToMac64b(&(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(&temp_dest_prefix,&temp_src_prefix)) { + sam = IPHC_SAM_64B; // no ipinip 6loRH if in the same prefix + } 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(&(msg->l3_destinationAdd))==FALSE){ + // ip in ip will be presented + sam = IPHC_SAM_128B; + } else { + // this is DIO, source address elided, multicast bit is set + sam = IPHC_SAM_ELIDED; + } + } - if (iphc_prependIPv6Header(msg, - tf, - *flow_label, // value_flowlabel - nh, - next_header, - IPHC_HLIM_INLINE, - ipv6_outer_header->hop_limit, - IPHC_CID_NO, - IPHC_SAC_STATELESS, - sam, - m, - IPHC_DAC_STATELESS, - dam, - p_dest, - p_src, - fw_SendOrfw_Rcv - )==E_FAIL) { - return E_FAIL; - } - return sixtop_send(msg); + //IPinIP 6LoRH will be added at here if necessary. + if (packetfunctions_sameAddress(&temp_dest_prefix,&temp_src_prefix)){ + // same network, IPinIP is elided + } else { + if (packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd))==FALSE){ + if ( + ( + ipv6_outer_header->src.type == ADDR_NONE && + packetfunctions_sameAddress(&(msg->l3_sourceAdd),(open_addr_t*)dagroot) + ) || + ( + ipv6_outer_header->src.type != ADDR_NONE && + packetfunctions_sameAddress(&(ipv6_outer_header->src),(open_addr_t*)dagroot) + ) + ){ + // hop limit + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = ipv6_outer_header->hop_limit; + // type + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = IPECAP_6LOTH_TYPE; + // length + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = ELECTIVE_6LoRH | 1; + } + else { + if (sam == IPHC_SAM_128B){ + // encapsulate address + packetfunctions_writeAddress(msg, &(msg->l3_sourceAdd),OW_BIG_ENDIAN); + // hoplim + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = ipv6_outer_header->hop_limit; + // type + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = IPECAP_6LOTH_TYPE; + // length + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = ELECTIVE_6LoRH | 17; + } + } + } else { + // this is DIO, no IPinIP either + } + } + + //prepend Option hop by hop header except when src routing and dst is not 0xffff + //-- this is a little trick as src routing is using an option header set to 0x00 + if ( + rpl_option->optionType==RPL_HOPBYHOP_HEADER_OPTION_TYPE && + packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd))==FALSE + ){ + iphc_prependIPv6HopByHopHeader(msg, msg->l4_protocol, rpl_option); + } + + // copy RH3s back if length > 0 + if (rh3_length > 0){ + packetfunctions_reserveHeaderSize(msg,rh3_length); + memcpy(&msg->payload[0],&rh3_copy[0],rh3_length); + } + + // if there are 6LoRH in the packet, add page dispatch no.1 + if ( + (*((uint8_t*)(msg->payload)) & FORMAT_6LORH_MASK) == CRITICAL_6LORH || + (*((uint8_t*)(msg->payload)) & FORMAT_6LORH_MASK) == ELECTIVE_6LoRH + ){ + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = PAGE_DISPATCH_NO_1; + } + + return sixtop_send(msg); } //send from bridge: 6LoWPAN header already added by OpenLBR, send as is @@ -226,43 +219,51 @@ void iphc_sendDone(OpenQueueEntry_t* msg, owerror_t error) { } void iphc_receive(OpenQueueEntry_t* msg) { - ipv6_header_iht ipv6_outer_header; - ipv6_header_iht ipv6_inner_header; - ipv6_hopbyhop_iht ipv6_hop_header; - rpl_option_ht rpl_option; - - msg->owner = COMPONENT_IPHC; + ipv6_header_iht ipv6_outer_header; + ipv6_header_iht ipv6_inner_header; + uint8_t page_length; + rpl_option_ht rpl_option; + uint8_t rpi_length; - // then regular header - iphc_retrieveIPv6Header(msg,&ipv6_outer_header,&ipv6_inner_header); + msg->owner = COMPONENT_IPHC; - if (idmanager_getIsDAGroot()==FALSE || - packetfunctions_isBroadcastMulticast(&(ipv6_outer_header.dest))) { - packetfunctions_tossHeader(msg,ipv6_outer_header.header_length); + memset(&ipv6_outer_header,0,sizeof(ipv6_header_iht)); + memset(&ipv6_inner_header,0,sizeof(ipv6_header_iht)); + memset(&rpl_option,0,sizeof(rpl_option_ht)); + + // then regular header + iphc_retrieveIPv6Header(msg,&ipv6_outer_header,&ipv6_inner_header,&page_length); + + // if the address is broadcast address, the ipv6 header is the inner header + if ( + idmanager_getIsDAGroot()==FALSE || + packetfunctions_isBroadcastMulticast(&(ipv6_inner_header.dest)) + ) { + packetfunctions_tossHeader(msg,page_length); + if ( + ipv6_outer_header.next_header==IANA_IPv6HOPOPT && + ipv6_outer_header.hopByhop_option != NULL + ) { + // retrieve hop-by-hop header (includes RPL option) + rpi_length = iphc_retrieveIPv6HopByHopHeader( + msg, + &rpl_option + ); + + // toss the headers + packetfunctions_tossHeader( + msg, + rpi_length + ); + } - if (ipv6_outer_header.next_header==IANA_IPv6HOPOPT) { - // retrieve hop-by-hop header (includes RPL option) - iphc_retrieveIPv6HopByHopHeader( + // send up the stack + forwarding_receive( msg, - &ipv6_hop_header, + &ipv6_outer_header, + &ipv6_inner_header, &rpl_option - ); - - // toss the headers - packetfunctions_tossHeader( - msg, - IPv6HOP_HDR_LEN+ipv6_hop_header.HdrExtLen - ); - } - - // send up the stack - forwarding_receive( - msg, - &ipv6_outer_header, - &ipv6_inner_header, - &ipv6_hop_header, - &rpl_option - ); + ); } else { openbridge_receive(msg); //out to the OpenVisualizer } @@ -519,340 +520,491 @@ owerror_t iphc_prependIPv6Header( /** \brief Retrieve an IPv6 header from a message. */ -void iphc_retrieveIPv6Header(OpenQueueEntry_t* msg, ipv6_header_iht* ipv6_outer_header, ipv6_header_iht* ipv6_inner_header) { - uint8_t temp_8b; - open_addr_t temp_addr_16b; - open_addr_t temp_addr_64b; - uint8_t dispatch; - uint8_t tf; - bool nh; - uint8_t hlim; - uint8_t sam; - uint8_t m; - uint8_t dam; - - uint8_t extention_header_length; - - ipv6_outer_header->header_length = 0; - ipv6_inner_header->header_length = 0; - // four steps to retrieve: - // step 1. IPHC outer header - // step 2. IPv6 extention header (NHC format) - // step 3. IPv6 header (NHC format) - // step 4. IPv6 inner header - - //======================= 1. IPHC outer header ============================== - iphc_retrieveIphcHeader(&temp_addr_16b, &temp_addr_64b,&dispatch,&tf,&nh,&hlim, - &sam, - &m, - &dam, - msg, - ipv6_outer_header, - 0); - if (packetfunctions_isAllRoutersMulticast(&(ipv6_outer_header->dest))){ - // this is a DIO packet, no extention header, no other ip inner header - return; - } - //======================= 2. IPv6 extention header ========================== - extention_header_length = 0; - if (ipv6_outer_header->next_header_compressed==TRUE) { - // During the parsing of the nh field, we found that the next header was - // compressed. We now identify which next (compressed) header this is, and - // populate the ipv6_header->next_header field accordingly. It's the role of - // the appropriate transport module to decompress the header. - - temp_8b = *((uint8_t*)(msg->payload)+ipv6_outer_header->header_length); - - if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { - ipv6_outer_header->next_header = IANA_UDP; - } else { - switch((temp_8b & NHC_EID_MASK)>>1) { - case NHC_EID_HOP_VAL: - // hop-by-hop header - ipv6_outer_header->next_header = IANA_IPv6HOPOPT; -// ipv6_outer_header->next_header_compressed -// = temp_8b & NHC_NH_MASK; - ipv6_outer_header->hopByhop_option = (uint8_t*)(msg->payload) + \ - ipv6_outer_header->header_length; - // hopByhop option header legnth - extention_header_length += 2+(*((uint8_t*)(msg->payload)+ipv6_outer_header->header_length+1)); - break; - case NHC_EID_ROUTING_VAL: - // routing header - ipv6_outer_header->next_header = IANA_IPv6ROUTE; -// ipv6_outer_header->next_header_compressed -// = temp_8b & NHC_NH_MASK; - ipv6_outer_header->routing_header = (uint8_t*)(msg->payload) + \ - ipv6_outer_header->header_length; - extention_header_length += 2+(*((uint8_t*)(msg->payload)+ipv6_outer_header->header_length+1)); - break; - case NHC_EID_IPv6_VAL: - // next header is IPHC inner header, we will process below - break; - default: - // the next header could be another IPv6 extension header - ipv6_outer_header->next_header = IANA_UNDEFINED; - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)11, - (errorparameter_t)ipv6_outer_header->next_header - ); - } - } - } else { - // the next header could be an IPv6 extension header, or malformed - ipv6_outer_header->next_header = IANA_UNDEFINED; - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)12, - (errorparameter_t)ipv6_outer_header->next_header - ); - } - //======================= 3. IPv6 header ==================================== - temp_8b = *((uint8_t*)(msg->payload)+ipv6_outer_header->header_length + \ - extention_header_length); - if (((temp_8b & NHC_EID_MASK)>>1) == NHC_EID_IPv6_VAL) { - if (extention_header_length == 0 && ipv6_outer_header->next_header != IANA_UNDEFINED) { - // no next header found at step 2, set next header as my IPv6 header - // since there is no IANA for ipv6 header yet, use the NHC extention - // header identifier instead temporarily. - ipv6_outer_header->next_header = temp_8b; +void iphc_retrieveIPv6Header(OpenQueueEntry_t* msg, ipv6_header_iht* ipv6_outer_header, ipv6_header_iht* ipv6_inner_header,uint8_t* page_length) { + uint8_t temp_8b; + open_addr_t temp_addr_16b; + open_addr_t temp_addr_64b; + uint8_t dispatch; + uint8_t tf; + bool nh; + uint8_t hlim; + uint8_t sam; + uint8_t m; + uint8_t dam; + uint8_t size; + uint8_t lorh_type; + uint8_t rh3_index; + uint8_t page; + uint8_t ipinip_length; + + uint8_t extention_header_length; + + *page_length = 0; + extention_header_length = 0; + rh3_index = 0; + ipv6_outer_header->header_length = 0; + ipv6_inner_header->header_length = 0; + + // four steps to retrieve: + // step 1. Paging number + // step 2. IP in IP 6LoRH + // step 3. IPv6 extention header + // step 4. IPv6 inner header + // ====================== 1. paging number ================================= + temp_8b = *((uint8_t*)(msg->payload)+ipv6_outer_header->header_length); + if ((temp_8b&PAGE_DISPATCH_TAG) == PAGE_DISPATCH_TAG){ + page = temp_8b&PAGE_DISPATCH_NUM; + *page_length = 1; + } else { + page = 0; + } + //======================= 2. IPv6 extention header ========================= + if(page==1){ + extention_header_length = 0; + temp_8b = *((uint8_t*)(msg->payload)+*page_length+extention_header_length); + while ((temp_8b&FORMAT_6LORH_MASK) == CRITICAL_6LORH){ + lorh_type = *((uint8_t*)(msg->payload)+*page_length+extention_header_length+1); + if(lorh_type<=RH3_6LOTH_TYPE_4){ + if (rh3_index == MAXNUM_RH3){ + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)13, + (errorparameter_t)(rh3_index) + ); + return; + } + if (rh3_index==0){ + if (ipv6_outer_header->hopByhop_option == NULL){ + ipv6_outer_header->next_header = IANA_IPv6ROUTE; + } + ipv6_outer_header->routing_header[rh3_index] = (uint8_t*)(msg->payload) + \ + *page_length + \ + extention_header_length; + } + size = temp_8b & RH3_6LOTH_SIZE_MASK; + size += 1; + switch(lorh_type){ + case 0: + extention_header_length += 2+ 1*size; + break; + case 1: + extention_header_length += 2+ 2*size; + break; + case 2: + extention_header_length += 2+ 4*size; + break; + case 3: + extention_header_length += 2+ 8*size; + break; + case 4: + extention_header_length += 2+ 16*size; + break; + } + temp_8b = *(uint8_t*)((msg->payload) + \ + *page_length + \ + extention_header_length); + } else { + if (lorh_type==5){ + if (ipv6_outer_header->routing_header[0] == NULL){ + ipv6_outer_header->next_header = IANA_IPv6HOPOPT; + } + ipv6_outer_header->hopByhop_option = (uint8_t*)(msg->payload) + \ + *page_length + \ + extention_header_length; + switch(temp_8b & (I_FLAG | K_FLAG)){ + case 0: + extention_header_length += 2+3; + break; + case 1: + case 2: + extention_header_length += 2+2; + break; + case 3: + extention_header_length += 2+1; + break; + } + temp_8b = *(uint8_t*)((msg->payload) + \ + *page_length + \ + extention_header_length); + } else{ + //log wrong inf + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)14, + (errorparameter_t)(lorh_type) + ); + } + } } - extention_header_length += sizeof(uint8_t); - } else { - // the next header could be an IPv6 extension header, or malformed - ipv6_outer_header->next_header = IANA_UNDEFINED; - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)13, - (errorparameter_t)ipv6_outer_header->next_header - ); - } - //======================= 4. IPHC inner header ============================== - iphc_retrieveIphcHeader(&temp_addr_16b, &temp_addr_64b,&dispatch,&tf,&nh,&hlim, - &sam, - &m, - &dam, - msg, - ipv6_inner_header, - extention_header_length + ipv6_outer_header->header_length); + } + // ====================== 3. 6LoRH IPinIP ================================== + // ip header is always at the beginning if not being elided + if (page == 1){ + temp_8b = *(uint8_t*)(msg->payload+ipv6_outer_header->header_length+*page_length+extention_header_length); + if ((temp_8b & FORMAT_6LORH_MASK) == ELECTIVE_6LoRH){ + // this is an elective 6LoRH + ipinip_length = temp_8b & IPINIP_LEN_6LORH_MASK; + ipv6_outer_header->header_length += 1; + temp_8b = *(uint8_t*)(msg->payload+ipv6_outer_header->header_length+*page_length+extention_header_length); + if (temp_8b == IPINIP_TYPE_6LORH){ + // this is IpinIP 6LoRH + ipv6_outer_header->header_length += 1; + ipv6_outer_header->hop_limit = *(uint8_t*)(msg->payload+ipv6_outer_header->header_length+*page_length+extention_header_length); + ipv6_outer_header->header_length += 1; + // destination address maybe is the first address in RH3 6LoRH OR dest adress in IPHC, reset first + // update destination address if necessary after the processing + ipv6_outer_header->dest.type = ADDR_NONE; + memset(&(ipv6_outer_header->dest.addr_128b[0]),0,16); + if (ipinip_length == 1){ + // source address is root + memset(&(ipv6_outer_header->src),0,sizeof(open_addr_t)); + ipv6_outer_header->src.type = ADDR_128B; + ipv6_outer_header->src.addr_128b[0] = 0xbb; + ipv6_outer_header->src.addr_128b[1] = 0xbb; + ipv6_outer_header->src.addr_128b[15] = 0x01; + // destination address is the first address in RH3 6LoRH OR dest adress in IPHC + } else{ + switch(ipinip_length-1){ + case 16: + // this is source address + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_outer_header->header_length+*page_length+extention_header_length)),ADDR_128B,&ipv6_outer_header->src,OW_BIG_ENDIAN); + ipv6_outer_header->header_length += 16*sizeof(uint8_t); + break; + case 8: + // this is source address + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_outer_header->header_length+*page_length+extention_header_length)),ADDR_64B,&temp_addr_64b,OW_BIG_ENDIAN); + ipv6_outer_header->header_length += 8*sizeof(uint8_t); + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_outer_header->src); + break; + default: + // do not support other length yet and destination address will be in RH3 or IPHC + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)12, + (errorparameter_t)(ipinip_length-1) + ); + } + } + } else { + // don't defined yet + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)13, + (errorparameter_t)(rh3_index) + ); + } + } else { + // ip in ip is elided: the followig is a critical 6lorh + // finish the ip header compression + } + } + //======================= 4. IPHC inner header ============================= + iphc_retrieveIphcHeader( + &temp_addr_16b, + &temp_addr_64b, + &dispatch, + &tf, + &nh, + &hlim, + &sam, + &m, + &dam, + msg, + ipv6_inner_header, + extention_header_length + ipv6_outer_header->header_length + *page_length + ); } -void iphc_retrieveIphcHeader(open_addr_t* temp_addr_16b, - open_addr_t* temp_addr_64b, - uint8_t* dispatch, - uint8_t* tf, - bool* nh, - uint8_t* hlim, - uint8_t* sam, - uint8_t* m, - uint8_t* dam, - OpenQueueEntry_t* msg, - ipv6_header_iht* ipv6_header, - uint8_t previousLen){ +uint8_t iphc_retrieveIphcHeader(open_addr_t* temp_addr_16b, + open_addr_t* temp_addr_64b, + uint8_t* dispatch, + uint8_t* tf, + bool* nh, + uint8_t* hlim, + uint8_t* sam, + uint8_t* m, + uint8_t* dam, + OpenQueueEntry_t* msg, + ipv6_header_iht* ipv6_header, + uint8_t previousLen){ - uint8_t temp_8b; - // header - temp_8b = *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen); - *dispatch = (temp_8b >> IPHC_DISPATCH) & 0x07; // 3b - *tf = (temp_8b >> IPHC_TF) & 0x03; // 2b - *nh = (temp_8b >> IPHC_NH) & 0x01; // 1b - *hlim = (temp_8b >> IPHC_HLIM) & 0x03; // 2b - ipv6_header->header_length += sizeof(uint8_t); - temp_8b = *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen); - // cid unused - // sac unused - *sam = (temp_8b >> IPHC_SAM) & 0x03; // 2b - // m unused - *m = (temp_8b >> IPHC_M) & 0x01; // 1b - // dac unused - *dam = (temp_8b >> IPHC_DAM) & 0x03; // 2b - ipv6_header->header_length += sizeof(uint8_t); - - // dispatch - switch (*dispatch) { - case IPHC_DISPATCH_IPHC: - break; - default: - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)5, - (errorparameter_t)(*dispatch) - ); - break; - } - - // flowlabel - switch (*tf) { - case IPHC_TF_3B: + uint8_t page; + uint8_t temp_8b; + uint8_t ipinip_length; + + temp_8b = *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen); + + if ((temp_8b&PAGE_DISPATCH_TAG) == PAGE_DISPATCH_TAG){ + page = temp_8b&PAGE_DISPATCH_NUM; + ipv6_header->header_length += sizeof(uint8_t); + } else { + page = 0; + } + + if ( + page==0 || + (page==1 && (*((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen) & 0xC0) != 0x80) + ){ + // header + temp_8b = *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen); + *dispatch = (temp_8b >> IPHC_DISPATCH) & 0x07; // 3b + *tf = (temp_8b >> IPHC_TF) & 0x03; // 2b + *nh = (temp_8b >> IPHC_NH) & 0x01; // 1b + *hlim = (temp_8b >> IPHC_HLIM) & 0x03; // 2b + ipv6_header->header_length += sizeof(uint8_t); + temp_8b = *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen); + // cid unused + // sac unused + *sam = (temp_8b >> IPHC_SAM) & 0x03; // 2b + // m unused + *m = (temp_8b >> IPHC_M) & 0x01; // 1b + // dac unused + *dam = (temp_8b >> IPHC_DAM) & 0x03; // 2b + ipv6_header->header_length += sizeof(uint8_t); + + // dispatch + switch (*dispatch) { + case IPHC_DISPATCH_IPHC: + break; + default: + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)5, + (errorparameter_t)(*dispatch) + ); + break; + } + + // flowlabel + switch (*tf) { + case IPHC_TF_3B: - ipv6_header->flow_label = 0; - ipv6_header->flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen)) << 0; - ipv6_header->header_length += sizeof(uint8_t); - ipv6_header->flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen)) << 8; - ipv6_header->header_length += sizeof(uint8_t); - ipv6_header->flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen)) << 16; - ipv6_header->header_length += sizeof(uint8_t); - break; - case IPHC_TF_ELIDED: - ipv6_header->flow_label = 0; - break; - case IPHC_TF_4B: - //unsupported - case IPHC_TF_1B: - //unsupported - default: - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)6, - (errorparameter_t)(*tf) - ); - break; - } - - // next header - switch (*nh) { - case IPHC_NH_INLINE: - // Full 8 bits for Next Header are carried in-line - ipv6_header->next_header_compressed = FALSE; - ipv6_header->next_header = *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen); - ipv6_header->header_length += sizeof(uint8_t); - - break; - case IPHC_NH_COMPRESSED: - // the Next header field is compressed and the next header is encoded - // using LOWPAN_NHC, which is discussed in Section 4.1 of RFC6282 - // we don't parse anything here, but will look at the (compressed) - // next header after having parsed all address fields. - ipv6_header->next_header_compressed = TRUE; - break; - default: - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)7, - (errorparameter_t)(*nh) - ); - break; - } - - // hop limit - switch (*hlim) { - case IPHC_HLIM_INLINE: - ipv6_header->hop_limit = *((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)); - ipv6_header->header_length += sizeof(uint8_t); - break; - case IPHC_HLIM_1: - ipv6_header->hop_limit = 1; - break; - case IPHC_HLIM_64: - ipv6_header->hop_limit = 64; - break; - case IPHC_HLIM_255: - ipv6_header->hop_limit = 255; - break; - default: - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)8, - (errorparameter_t)(*hlim) - ); - break; - } - - // source address - switch (*sam) { - case IPHC_SAM_ELIDED: - packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&(msg->l2_nextORpreviousHop),&ipv6_header->src); - break; - case IPHC_SAM_16B: - packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_16B,temp_addr_16b,OW_BIG_ENDIAN); - ipv6_header->header_length += 2*sizeof(uint8_t); - packetfunctions_mac16bToMac64b(temp_addr_16b,temp_addr_64b); - packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->src); - break; - case IPHC_SAM_64B: - packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_64B,temp_addr_64b,OW_BIG_ENDIAN); - ipv6_header->header_length += 8*sizeof(uint8_t); - packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->src); - break; - case IPHC_SAM_128B: - packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_128B,&ipv6_header->src,OW_BIG_ENDIAN); - ipv6_header->header_length += 16*sizeof(uint8_t); - break; - default: - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)9, - (errorparameter_t)(*sam) - ); - break; - } - - // destination address - if(*m == IPHC_M_YES) { - switch (*dam) { - case IPHC_DAM_ELIDED: - ipv6_header->dest.type = ADDR_128B; - memcpy(&(ipv6_header->dest.addr_128b[0]),all_routers_multicast,sizeof(all_routers_multicast)); - ipv6_header->dest.addr_128b[15] = *(msg->payload+ipv6_header->header_length+previousLen); - ipv6_header->header_length += sizeof(uint8_t); + ipv6_header->flow_label = 0; + ipv6_header->flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen)) << 0; + ipv6_header->header_length += sizeof(uint8_t); + ipv6_header->flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen)) << 8; + ipv6_header->header_length += sizeof(uint8_t); + ipv6_header->flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen)) << 16; + ipv6_header->header_length += sizeof(uint8_t); + break; + case IPHC_TF_ELIDED: + ipv6_header->flow_label = 0; break; - case IPHC_DAM_16B: - // tengfei: todo + case IPHC_TF_4B: + //unsupported + case IPHC_TF_1B: + //unsupported + default: + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)6, + (errorparameter_t)(*tf) + ); break; - case IPHC_DAM_64B: - // tengfei: todo + } + + // next header + switch (*nh) { + case IPHC_NH_INLINE: + // Full 8 bits for Next Header are carried in-line + ipv6_header->next_header_compressed = FALSE; + ipv6_header->next_header = *((uint8_t*)(msg->payload)+ipv6_header->header_length+previousLen); + ipv6_header->header_length += sizeof(uint8_t); + break; - case IPHC_DAM_128B: - // tengfei: todo + case IPHC_NH_COMPRESSED: + // the Next header field is compressed and the next header is encoded + // using LOWPAN_NHC, which is discussed in Section 4.1 of RFC6282 + // we don't parse anything here, but will look at the (compressed) + // next header after having parsed all address fields. + ipv6_header->next_header_compressed = TRUE; break; default: openserial_printError( COMPONENT_IPHC, ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)10, - (errorparameter_t)(*dam) + (errorparameter_t)7, + (errorparameter_t)(*nh) ); break; } - } else { - switch (*dam) { - case IPHC_DAM_ELIDED: - packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),idmanager_getMyID(ADDR_64B),&(ipv6_header->dest)); + + // hop limit + switch (*hlim) { + case IPHC_HLIM_INLINE: + ipv6_header->hop_limit = *((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)); + ipv6_header->header_length += sizeof(uint8_t); + break; + case IPHC_HLIM_1: + ipv6_header->hop_limit = 1; break; - case IPHC_DAM_16B: + case IPHC_HLIM_64: + ipv6_header->hop_limit = 64; + break; + case IPHC_HLIM_255: + ipv6_header->hop_limit = 255; + break; + default: + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)8, + (errorparameter_t)(*hlim) + ); + break; + } + + // source address + switch (*sam) { + case IPHC_SAM_ELIDED: + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&(msg->l2_nextORpreviousHop),&ipv6_header->src); + break; + case IPHC_SAM_16B: packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_16B,temp_addr_16b,OW_BIG_ENDIAN); ipv6_header->header_length += 2*sizeof(uint8_t); packetfunctions_mac16bToMac64b(temp_addr_16b,temp_addr_64b); - packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->dest); + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->src); break; - case IPHC_DAM_64B: + case IPHC_SAM_64B: packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_64B,temp_addr_64b,OW_BIG_ENDIAN); ipv6_header->header_length += 8*sizeof(uint8_t); - packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->dest); + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->src); break; - case IPHC_DAM_128B: - packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_128B,&ipv6_header->dest,OW_BIG_ENDIAN); + case IPHC_SAM_128B: + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_128B,&ipv6_header->src,OW_BIG_ENDIAN); ipv6_header->header_length += 16*sizeof(uint8_t); break; default: openserial_printError( COMPONENT_IPHC, ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)10, - (errorparameter_t)(*dam) + (errorparameter_t)9, + (errorparameter_t)(*sam) ); break; } - } + + // destination address + if(*m == IPHC_M_YES) { + switch (*dam) { + case IPHC_DAM_ELIDED: + ipv6_header->dest.type = ADDR_128B; + memcpy(&(ipv6_header->dest.addr_128b[0]),all_routers_multicast,sizeof(all_routers_multicast)); + ipv6_header->dest.addr_128b[15] = *(msg->payload+ipv6_header->header_length+previousLen); + ipv6_header->header_length += sizeof(uint8_t); + break; + case IPHC_DAM_16B: + // tengfei: todo + break; + case IPHC_DAM_64B: + // tengfei: todo + break; + case IPHC_DAM_128B: + // tengfei: todo + break; + default: + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)10, + (errorparameter_t)(*dam) + ); + break; + } + } else { + switch (*dam) { + case IPHC_DAM_ELIDED: + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),idmanager_getMyID(ADDR_64B),&(ipv6_header->dest)); + break; + case IPHC_DAM_16B: + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_16B,temp_addr_16b,OW_BIG_ENDIAN); + ipv6_header->header_length += 2*sizeof(uint8_t); + packetfunctions_mac16bToMac64b(temp_addr_16b,temp_addr_64b); + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->dest); + break; + case IPHC_DAM_64B: + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_64B,temp_addr_64b,OW_BIG_ENDIAN); + ipv6_header->header_length += 8*sizeof(uint8_t); + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->dest); + break; + case IPHC_DAM_128B: + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_128B,&ipv6_header->dest,OW_BIG_ENDIAN); + ipv6_header->header_length += 16*sizeof(uint8_t); + break; + default: + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)10, + (errorparameter_t)(*dam) + ); + break; + } + } + } else { + // we are in 6LoRH now + if (page == 1){ + temp_8b = *(uint8_t*)(msg->payload+ipv6_header->header_length+previousLen); + if ((temp_8b & FORMAT_6LORH_MASK) == ELECTIVE_6LoRH){ + // this is an elective 6LoRH + ipinip_length = temp_8b & IPINIP_LEN_6LORH_MASK; + ipv6_header->header_length += 1; + temp_8b = *(uint8_t*)(msg->payload+ipv6_header->header_length+previousLen); + if (temp_8b == IPINIP_TYPE_6LORH){ + // this is IpinIP 6LoRH + ipv6_header->header_length += 1; + ipv6_header->hop_limit = *(uint8_t*)(msg->payload+ipv6_header->header_length+previousLen); + ipv6_header->header_length += 1; + // destination address maybe is the first address in RH3 6LoRH OR dest adress in IPHC, reset first + // update destination address if necessary after the processing + ipv6_header->dest.type = ADDR_NONE; + memset(&(ipv6_header->dest.addr_128b[0]),0,16); + if (ipinip_length == 1){ + // source address is root + memset(&(ipv6_header->src),0,sizeof(open_addr_t)); + ipv6_header->src.type = ADDR_128B; + ipv6_header->src.addr_128b[0] = 0xbb; + ipv6_header->src.addr_128b[1] = 0xbb; + ipv6_header->src.addr_128b[15] = 0x01; + // destination address is the first address in RH3 6LoRH OR dest adress in IPHC + } else{ + switch(ipinip_length-1){ + case 16: + // this is source address + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_128B,&ipv6_header->src,OW_BIG_ENDIAN); + ipv6_header->header_length += 16*sizeof(uint8_t); + break; + case 8: + // this is source address + packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header->header_length+previousLen)),ADDR_64B,temp_addr_64b,OW_BIG_ENDIAN); + ipv6_header->header_length += 8*sizeof(uint8_t); + packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),temp_addr_64b,&ipv6_header->src); + break; + default: + // do not support other length yet and destination address will be in RH3 or IPHC + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)12, + (errorparameter_t)(ipinip_length-1) + ); + } + } + } + + } else { + // ip in ip is elided: the followig is a critical 6lorh + // finish the ip header compression + } + } + } + return page; } //===== IPv6 hop-by-hop header @@ -870,40 +1022,30 @@ void iphc_retrieveIphcHeader(open_addr_t* temp_addr_16b, void iphc_prependIPv6HopByHopHeader( OpenQueueEntry_t* msg, uint8_t nextheader, - uint8_t nh, rpl_option_ht* rpl_option ){ - // RPL option - packetfunctions_reserveHeaderSize(msg,sizeof(rpl_option_ht)); - memcpy(msg->payload,rpl_option,sizeof(rpl_option_ht)); + uint8_t temp_8b; - // header length (http://tools.ietf.org/html/rfc6282#section-4.2) - packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); - *((uint8_t*)(msg->payload)) = sizeof(rpl_option_ht); + if ((rpl_option->flags & K_FLAG) == 0){ + packetfunctions_reserveHeaderSize(msg,sizeof(uint16_t)); + msg->payload[0] = (uint8_t)((rpl_option->senderRank&0xFF00)>>8); + msg->payload[1] = (uint8_t)(rpl_option->senderRank&0x00FF); + } else { + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = (uint8_t)((rpl_option->senderRank&0xFF00)>>8); + } - // next header - switch (nh) { - case IPHC_NH_INLINE: - // inline next header field - packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); - *((uint8_t*)(msg->payload)) = nextheader; - - // append NHC field on the extension header should be 1110 0000 - packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); - *((uint8_t*)(msg->payload)) = NHC_IPv6EXT_ID; - break; - case IPHC_NH_COMPRESSED: - packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); - *((uint8_t*)(msg->payload)) = NHC_IPv6EXT_ID | 0x01; // mark last bit as 1 - break; - default: - openserial_printCritical( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)3, - (errorparameter_t)nh - ); + if ((rpl_option->flags & I_FLAG) == 0){ + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = rpl_option->rplInstanceID; } + + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = RPI_6LOTH_TYPE; + + temp_8b = CRITICAL_6LORH | rpl_option->flags; + packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); + *((uint8_t*)(msg->payload)) = temp_8b; } /** @@ -915,85 +1057,53 @@ void iphc_prependIPv6HopByHopHeader( \param[out] rpl_option Pointer to the structure to hold the retrieved RPL option. */ -void iphc_retrieveIPv6HopByHopHeader( +uint8_t iphc_retrieveIPv6HopByHopHeader( OpenQueueEntry_t* msg, - ipv6_hopbyhop_iht* hopbyhop_header, rpl_option_ht* rpl_option ){ uint8_t temp_8b; + uint8_t type; + uint8_t length; // initialize the header length (will increment at each field) - hopbyhop_header->headerlen = 0; - - hopbyhop_header->lowpan_nhc = *((uint8_t*)(msg->payload)+ hopbyhop_header->headerlen); - hopbyhop_header->headerlen += sizeof(uint8_t); - - // next header - switch (hopbyhop_header->lowpan_nhc & NHC_NH_MASK) { - case IPHC_NH_INLINE: - // full 8 bits for Next Header are carried in-line - - hopbyhop_header->next_header_compressed = FALSE; - hopbyhop_header->nextHeader = *((uint8_t*)(msg->payload)+hopbyhop_header->headerlen); - hopbyhop_header->headerlen += sizeof(uint8_t); - break; - case IPHC_NH_COMPRESSED: - // The Next header field is compressed and the next header is encoded - // using LOWPAN_NHC, which is discussed in Section 4.1 of RFC6282. - // We don't parse anything here; we will look at the (compressed) - // next header after having parsed all address fields. - - hopbyhop_header->next_header_compressed = TRUE; - break; - default: - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)7, - (errorparameter_t)hopbyhop_header->lowpan_nhc); - break; - } + length = 0; - // option length - hopbyhop_header->HdrExtLen = *((uint8_t*)(msg->payload)+hopbyhop_header->headerlen); - hopbyhop_header->headerlen += sizeof(uint8_t); + temp_8b = *((uint8_t*)(msg->payload)+length); + type = *((uint8_t*)(msg->payload)+length+1); - // RPL option - memcpy(rpl_option,((uint8_t*)(msg->payload)+hopbyhop_header->headerlen),sizeof(rpl_option_ht)); - hopbyhop_header->headerlen+= sizeof(rpl_option_ht); - - // next header - if (hopbyhop_header->next_header_compressed==TRUE) { - // During the parsing of the nh field, we found that the next header was - // compressed. We now identify which next (compressed) header this is, - // and populate the hopbyhop_header.nextHeader field accordingly. It's - // the role of the appropriate transport module to decompress the header. - - temp_8b = *((uint8_t*)(msg->payload)+ hopbyhop_header->headerlen); - - if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { - hopbyhop_header->nextHeader = IANA_UDP; - } else { - if ((temp_8b & NHC_IPv6EXT_MASK) == NHC_IPv6EXT_ID) { - switch ((temp_8b & NHC_EID_MASK) >> 1) { - case NHC_EID_IPv6_VAL: - // current IANA do not assign a number for ipv6 header yet - // http://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml#ipv6-parameters-1 - // mark as NHC ipv6 header identifier temporarily - hopbyhop_header->nextHeader = temp_8b; - break; - default: - // the next header could be an IPv6 extension header, or malformed - hopbyhop_header->nextHeader = IANA_UNDEFINED; - - openserial_printError( - COMPONENT_IPHC, - ERR_6LOWPAN_UNSUPPORTED, - (errorparameter_t)14, - (errorparameter_t)hopbyhop_header->nextHeader - ); - } - } - } + if ( + (temp_8b & FORMAT_6LORH_MASK) == CRITICAL_6LORH && + type == RPI_6LOTH_TYPE + ){ + // this is 6LoRH RPI, move pointer to compressed field + length += sizeof(uint16_t); + // get the O, R, F I and K value + rpl_option->flags = (uint8_t)(temp_8b & FLAG_MASK); + // check FLAG I to get rplinstance ID + if ((temp_8b & I_FLAG)==0){ + rpl_option->rplInstanceID = *((uint8_t*)(msg->payload)+length); + length += sizeof(uint8_t); + } else { + // Global RPLInstanceID + rpl_option->rplInstanceID = 0; + } + // check FLAG K to get senderRannk + if ((temp_8b & K_FLAG)==0){ + rpl_option->senderRank = *((uint8_t*)(msg->payload)+length); + rpl_option->senderRank = ((rpl_option->senderRank)<<8)+*((uint8_t*)(msg->payload)+length+1); + length += sizeof(uint16_t); + } else{ + rpl_option->senderRank = *((uint8_t*)(msg->payload)+length); + rpl_option->senderRank = rpl_option->senderRank*256; + length += sizeof(uint8_t); + } + } else { + openserial_printError( + COMPONENT_IPHC, + ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)14, + (errorparameter_t)type + ); } + return length; } diff --git a/openstack/03a-IPHC/iphc.h b/openstack/03a-IPHC/iphc.h index 7e05c62d60..f25828c801 100644 --- a/openstack/03a-IPHC/iphc.h +++ b/openstack/03a-IPHC/iphc.h @@ -14,6 +14,7 @@ #define IPHC_DEFAULT_HOP_LIMIT 65 #define IPv6HOP_HDR_LEN 2 // tengfei: should be 2 +#define MAXNUM_RH3 3 enum IPHC_enums { IPHC_DISPATCH = 5, @@ -56,6 +57,8 @@ enum NHC_enums { NHC_EID_HOP_VAL = 0x00, NHC_EID_ROUTING_VAL = 0x01, NHC_EID_IPv6_VAL = 0x07, + // next header is iphc + NHC_IPHC_ID = 0xe7, }; enum NHC_NH_enums { @@ -122,6 +125,37 @@ enum IPHC_OUTER_INNER_enums { IPHC_INNER = 1, }; +enum FORMAT_6LORH_enums { + FORMAT_6LORH_MASK = 0xE0, + CRITICAL_6LORH = 0x80, + ELECTIVE_6LoRH = 0xa0, +}; + +enum IPINIP_LEN_6LORH_enums { + IPINIP_LEN_6LORH_MASK = 0x1F, + IPINIP_TYPE_6LORH = 0x06, +}; + +enum TYPE_6LORH_enums{ + RH3_6LOTH_TYPE_0 = 0x00, + RH3_6LOTH_TYPE_1 = 0x01, + RH3_6LOTH_TYPE_2 = 0x02, + RH3_6LOTH_TYPE_3 = 0x03, + RH3_6LOTH_TYPE_4 = 0x04, + RPI_6LOTH_TYPE = 0x05, + IPECAP_6LOTH_TYPE = 0x06, +}; + +enum SIZE_6LORH_RH3_enums{ + RH3_6LOTH_SIZE_MASK = 0x1F, +}; + +enum PAGE_DISPATCH_enums{ + PAGE_DISPATCH_NO_1 = 0xF1, + PAGE_DISPATCH_TAG = 0xF0, + PAGE_DISPATCH_NUM = 0x0F, +}; + //=========================== typedef ========================================= typedef struct { @@ -129,7 +163,7 @@ typedef struct { uint32_t flow_label; bool next_header_compressed; uint8_t next_header; - uint8_t* routing_header; + uint8_t* routing_header[MAXNUM_RH3]; uint8_t* hopByhop_option; uint8_t hop_limit; open_addr_t src; @@ -172,9 +206,8 @@ Described in http://tools.ietf.org/html/rfc6553#section-3 */ BEGIN_PACK typedef struct { - uint8_t optionType; ///< RPL_HOPBYHOP_HEADER_OPTION_TYPE - uint8_t optionLen; ///< 8-bit field indicating the length of the option, in octets, excluding the Option Type and Opt Data Len fields. - uint8_t flags; ///< ORF00000 + uint8_t optionType; + uint8_t flags; ///< 000ORFIK uint8_t rplInstanceID; ///< instanceid uint16_t senderRank; ///< RPL rank of the sender of the packet } rpl_option_ht; @@ -191,6 +224,8 @@ owerror_t iphc_sendFromForwarding( ipv6_header_iht* ipv6_inner_header, rpl_option_ht* rpl_option, uint32_t* flow_label, + uint8_t* rh3_copy, + uint8_t rh3_length, uint8_t fw_SendOrfw_Rcv ); owerror_t iphc_sendFromBridge(OpenQueueEntry_t *msg); diff --git a/openstack/03b-IPv6/forwarding.c b/openstack/03b-IPv6/forwarding.c index 3903579f52..c081a4729b 100644 --- a/openstack/03b-IPv6/forwarding.c +++ b/openstack/03b-IPv6/forwarding.c @@ -32,7 +32,8 @@ owerror_t forwarding_send_internal_RoutingTable( owerror_t forwarding_send_internal_SourceRouting( OpenQueueEntry_t* msg, ipv6_header_iht* ipv6_outer_header, - ipv6_header_iht* ipv6_inner_header + ipv6_header_iht* ipv6_inner_header, + rpl_option_ht* rpl_option ); void forwarding_createRplOption( rpl_option_ht* rpl_option, @@ -57,88 +58,114 @@ at this mote. \param[in,out] msg Packet to send. */ owerror_t forwarding_send(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; - - // take ownership over the packet - msg->owner = COMPONENT_FORWARDING; - - // retrieve my prefix and EUI64 - myprefix = idmanager_getMyID(ADDR_PREFIX); - myadd64 = idmanager_getMyID(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_outer_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT; - - // create the RPL hop-by-hop option - - forwarding_createRplOption( + 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(ADDR_PREFIX); + myadd64 = idmanager_getMyID(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( &rpl_option, // rpl_option to fill in 0x00 // flags - ); - - - // inner header is required only when the destination address is NOT broadcast address - if (packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd)) == FALSE) { - //IPHC inner header and NHC IPv6 header will be added at here - iphc_prependIPv6Header( - msg, - IPHC_TF_ELIDED, - flow_label, - // we should pass the parameter "msg->l4_protocol_compressed" here. - // but since currectly the upper layers doesn't set the l4_protocol_compressed - // parameter and the OPENQUEUE COMPONEN didn't reset this value either. So using - // "msg->l4_protocol_compressed" here may cause wrong result. - // Using IPHC_NH_INLINE instead temporarily. This should be fixed later. - IPHC_NH_INLINE, - msg->l4_protocol, - IPHC_HLIM_64, - ipv6_outer_header.hop_limit, - IPHC_CID_NO, - IPHC_SAC_STATELESS, - IPHC_SAM_64B, - IPHC_M_NO, - IPHC_DAC_STATELESS, - IPHC_DAM_ELIDED, - &(msg->l3_destinationAdd), - &(msg->l3_sourceAdd), - PCKTSEND - ); - // preprend NHC ipv6 next header - packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); - *((uint8_t*)(msg->payload)) = (uint8_t)(NHC_IPv6EXT_ID + \ - (uint8_t)(NHC_EID_IPv6_VAL << 1) + \ - (uint8_t)(NHC_NH_INLINE)); - // msg->l4_protocol = *((uint8_t*)(msg->payload)); - // for IPHC outer header its next header is option hopByhop header OR NHC ipv6. - // both of them are compressed - ipv6_outer_header.next_header_compressed = TRUE; - } - - return forwarding_send_internal_RoutingTable( - msg, - &ipv6_outer_header, - &ipv6_inner_header, - &rpl_option, - &flow_label, - PCKTSEND - ); + ); + + packetfunctions_ip128bToMac64b(&(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); + //xv poipoi -- get the src prefix as well + packetfunctions_ip128bToMac64b(&(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(&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(&(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(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( + msg, + &ipv6_outer_header, + &ipv6_inner_header, + &rpl_option, + &flow_label, + PCKTSEND + ); } /** @@ -199,146 +226,124 @@ void forwarding_receive( OpenQueueEntry_t* msg, ipv6_header_iht* ipv6_outer_header, ipv6_header_iht* ipv6_inner_header, - ipv6_hopbyhop_iht* ipv6_hop_header, rpl_option_ht* rpl_option - ) { - uint8_t flags; - uint16_t senderRank; + ) { + uint8_t flags; + uint16_t senderRank; - // take ownership - msg->owner = COMPONENT_FORWARDING; + // take ownership + msg->owner = COMPONENT_FORWARDING; - // determine L4 protocol - if (ipv6_outer_header->next_header==IANA_IPv6HOPOPT){ - // get information from ipv6_hop_header - - msg->l4_protocol = ipv6_hop_header->nextHeader; - msg->l4_protocol_compressed = ipv6_hop_header->next_header_compressed; - } else { - // get information from ipv6_header - - msg->l4_protocol = ipv6_outer_header->next_header; - msg->l4_protocol_compressed = ipv6_outer_header->next_header_compressed; - } + // determine L4 protocol + // get information from ipv6_header + msg->l4_protocol = ipv6_inner_header->next_header; + msg->l4_protocol_compressed = ipv6_inner_header->next_header_compressed; - // populate packets metadata with L3 information - memcpy(&(msg->l3_destinationAdd),&ipv6_outer_header->dest,sizeof(open_addr_t)); - memcpy(&(msg->l3_sourceAdd), &ipv6_outer_header->src, sizeof(open_addr_t)); - - if ( - ( - idmanager_isMyAddress(&ipv6_outer_header->dest) + // populate packets metadata with L3 information + memcpy(&(msg->l3_destinationAdd),&ipv6_inner_header->dest, sizeof(open_addr_t)); + memcpy(&(msg->l3_sourceAdd), &ipv6_inner_header->src, sizeof(open_addr_t)); + + if ( + ( + idmanager_isMyAddress(&(msg->l3_destinationAdd)) || - packetfunctions_isBroadcastMulticast(&ipv6_outer_header->dest) - ) - && - ipv6_outer_header->next_header!=IANA_IPv6ROUTE - ) { - // this packet is for me, no source routing header. - // toss ipv6 NHC header - if (packetfunctions_isBroadcastMulticast(&ipv6_outer_header->dest)==FALSE) { - packetfunctions_tossHeader(msg,sizeof(uint8_t)); - msg->l4_protocol = ipv6_inner_header->next_header; - msg->l4_protocol_compressed = ipv6_inner_header->next_header_compressed; - // toss iphc inner header - packetfunctions_tossHeader(msg,ipv6_inner_header->header_length); - } - - // indicate received packet to upper layer - switch(msg->l4_protocol) { - case IANA_TCP: + packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd)) + ) + && + ipv6_outer_header->next_header!=IANA_IPv6ROUTE + ) { + if (ipv6_outer_header->src.type != ADDR_NONE){ + packetfunctions_tossHeader(msg,ipv6_outer_header->header_length); + } + // this packet is for me, no source routing header // toss iphc inner header + packetfunctions_tossHeader(msg,ipv6_inner_header->header_length); + // indicate received packet to upper layer + switch(msg->l4_protocol) { + case IANA_TCP: opentcp_receive(msg); break; - case IANA_UDP: + case IANA_UDP: openudp_receive(msg); break; - case IANA_ICMPv6: + case IANA_ICMPv6: icmpv6_receive(msg); break; - default: - + default: // log error openserial_printError( - COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, - (errorparameter_t)msg->l4_protocol, - (errorparameter_t)1 + COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, + (errorparameter_t)msg->l4_protocol, + (errorparameter_t)1 ); // free packet openqueue_freePacketBuffer(msg); - } - } else { - // this packet is not for me: relay + } + } else { + // this packet is not for me: relay - // change the creator of the packet - msg->creator = COMPONENT_FORWARDING; + // change the creator of the packet + msg->creator = COMPONENT_FORWARDING; - if (ipv6_outer_header->next_header!=IANA_IPv6ROUTE) { - // no source routing header present - //check if flow label rpl header - - flags = rpl_option->flags; - senderRank = rpl_option->senderRank; - - if ((flags & O_FLAG)!=0){ - // wrong direction - - // log error - openserial_printError( - COMPONENT_FORWARDING, - ERR_WRONG_DIRECTION, - (errorparameter_t)flags, - (errorparameter_t)senderRank - ); - } - - - if (senderRank < neighbors_getMyDAGrank()){ - // loop detected - // set flag - rpl_option->flags |= R_FLAG; - - // log error - openserial_printError( - COMPONENT_FORWARDING, - ERR_LOOP_DETECTED, - (errorparameter_t) senderRank, - (errorparameter_t) neighbors_getMyDAGrank() - ); - } - - - forwarding_createRplOption(rpl_option, rpl_option->flags); - // resend as if from upper layer - if ( - forwarding_send_internal_RoutingTable( - msg, - ipv6_outer_header, - ipv6_inner_header, - rpl_option, - &(ipv6_outer_header->flow_label), - PCKTFORWARD - )==E_FAIL + if (ipv6_outer_header->next_header!=IANA_IPv6ROUTE) { + flags = rpl_option->flags; + senderRank = rpl_option->senderRank; + if ((flags & O_FLAG)!=0){ + // wrong direction + // log error + openserial_printError( + COMPONENT_FORWARDING, + ERR_WRONG_DIRECTION, + (errorparameter_t)flags, + (errorparameter_t)senderRank + ); + } + if (senderRank < neighbors_getMyDAGrank()){ + // loop detected + // set flag + rpl_option->flags |= R_FLAG; + // log error + openserial_printError( + COMPONENT_FORWARDING, + ERR_LOOP_DETECTED, + (errorparameter_t) senderRank, + (errorparameter_t) neighbors_getMyDAGrank() + ); + } + forwarding_createRplOption(rpl_option, rpl_option->flags); + // resend as if from upper layer + if ( + forwarding_send_internal_RoutingTable( + msg, + ipv6_outer_header, + ipv6_inner_header, + rpl_option, + &(ipv6_outer_header->flow_label), + PCKTFORWARD + )==E_FAIL ) { - openqueue_freePacketBuffer(msg); - } - } else { - // source routing header present - - if (forwarding_send_internal_SourceRouting(msg,ipv6_outer_header,ipv6_inner_header)==E_FAIL) { - - // already freed by send_internal - - // log error - openserial_printError( - COMPONENT_FORWARDING, - ERR_INVALID_FWDMODE, - (errorparameter_t)0, - (errorparameter_t)0 - ); - } - } - } + openqueue_freePacketBuffer(msg); + } + } else { + // source routing header present + if ( + forwarding_send_internal_SourceRouting( + msg, + ipv6_outer_header, + ipv6_inner_header, + rpl_option + )==E_FAIL + ) { + // log error + openserial_printError( + COMPONENT_FORWARDING, + ERR_INVALID_FWDMODE, + (errorparameter_t)0, + (errorparameter_t)0 + ); + } + } + } } //=========================== private ========================================= @@ -399,6 +404,10 @@ owerror_t forwarding_send_internal_RoutingTable( return E_FAIL; } + if (ipv6_outer_header->src.type != ADDR_NONE){ + packetfunctions_tossHeader(msg,ipv6_outer_header->header_length); + } + // send to next lower layer return iphc_sendFromForwarding( msg, @@ -406,6 +415,8 @@ owerror_t forwarding_send_internal_RoutingTable( ipv6_inner_header, rpl_option, flow_label, + NULL, // no rh3 + 0, fw_SendOrfw_Rcv ); } @@ -422,231 +433,289 @@ How to process the routing header is detailed in \param[in] ipv6_header The packet's IPv6 header. */ owerror_t forwarding_send_internal_SourceRouting( - OpenQueueEntry_t* msg, - ipv6_header_iht* ipv6_outer_header, - ipv6_header_iht* ipv6_inner_header - ) { - uint8_t local_CmprE; - uint8_t local_CmprI; - uint8_t numAddr; - uint8_t hlen; - uint8_t addressposition; - uint8_t* runningPointer; - uint8_t octetsAddressSize; - open_addr_t* prefix; - rpl_routing_ht* rpl_routing_hdr; - rpl_option_ht rpl_option; - - // reset hop-by-hop option - memset(&rpl_option,0,sizeof(rpl_option_ht)); - - // get my prefix - prefix = idmanager_getMyID(ADDR_PREFIX); - - // cast packet to RPL routing header - rpl_routing_hdr = (rpl_routing_ht*)(msg->payload); - - // point behind the RPL routing header - runningPointer = (msg->payload)+sizeof(rpl_routing_ht); - - // retrieve CmprE and CmprI - - // CmprE 4-bit unsigned integer. Number of prefix octets - // from the last segment (i.e., segment n) that are - // elided. For example, an SRH carrying a full IPv6 - // address in Addressesn sets CmprE to 0. - - local_CmprE = rpl_routing_hdr->CmprICmprE & 0x0f; - local_CmprI = rpl_routing_hdr->CmprICmprE & 0xf0; - local_CmprI = local_CmprI>>4; - - // since NH is set, The Length field contained in a compressed IPv6 Extension Header - // indicates the number of octets that pertain to the (compressed) - // extension header following the Length field. this changes - // the Length field definition in [RFC2460] from indicating the header - // size in 8-octet units, not including the first 8 octets. Changing - // the Length field to be in units of octets removes wasteful internal - // fragmentation. -// numAddr = (((rpl_routing_hdr->HdrExtLen*8)-rpl_routing_hdr->PadRes-(16-local_CmprE))/(16-local_CmprI))+1; - numAddr = ((rpl_routing_hdr->HdrExtLen-6-(16-local_CmprE))/(16-local_CmprI))+1; - - if (rpl_routing_hdr->SegmentsLeft==0){ - // no more segments left, this is the last hop - - // push packet up the stack - msg->l4_protocol = rpl_routing_hdr->nextHeader; - hlen = rpl_routing_hdr->HdrExtLen; //in units - - // toss RPL routing header - packetfunctions_tossHeader(msg,sizeof(rpl_routing_ht)); - - // toss source route addresses - packetfunctions_tossHeader(msg,hlen-6); //total hlen - 6(type, cmprE+cmprI,pad,reserved) - - - // toss ipv6 NHC header - packetfunctions_tossHeader(msg,sizeof(uint8_t)); - msg->l4_protocol = ipv6_inner_header->next_header; - msg->l4_protocol_compressed = ipv6_inner_header->next_header_compressed; - // toss iphc inner header - packetfunctions_tossHeader(msg,ipv6_inner_header->header_length); + 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(&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(&firstAddr,&temp_prefix,&temp_addr64); + if ( + packetfunctions_sameAddress(&temp_prefix,idmanager_getMyID(ADDR_PREFIX)) && + packetfunctions_sameAddress(&temp_addr64,idmanager_getMyID(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(msg,hlen); + packetfunctions_reserveHeaderSize(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( + &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(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( + &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(msg,hlen); + if (next_size>0){ + next_size -= 1; + packetfunctions_reserveHeaderSize(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(msg,1); + msg->payload[0] = firstAddr.addr_128b[15]; + break; + case RH3_6LOTH_TYPE_1: + packetfunctions_reserveHeaderSize(msg,2); + memcpy(&msg->payload[0],&firstAddr.addr_128b[14],2); + break; + case RH3_6LOTH_TYPE_2: + packetfunctions_reserveHeaderSize(msg,4); + memcpy(&msg->payload[0],&firstAddr.addr_128b[12],4); + break; + case RH3_6LOTH_TYPE_3: + packetfunctions_reserveHeaderSize(msg,8); + memcpy(&msg->payload[0],&firstAddr.addr_128b[8],8); + break; + case RH3_6LOTH_TYPE_4: + packetfunctions_reserveHeaderSize(msg,16); + memcpy(&msg->payload[0],&firstAddr.addr_128b[0],16); + break; + } + packetfunctions_reserveHeaderSize(msg,2); + msg->payload[0] = CRITICAL_6LORH | 0; + msg->payload[1] = type; + packetfunctions_ip128bToMac64b( + &firstAddr, + &temp_prefix, + &msg->l2_nextORpreviousHop + ); + } + } else { + // there is no next RH3-6loRH, remove current one + packetfunctions_tossHeader(msg,hlen); + packetfunctions_ip128bToMac64b( + &msg->l3_destinationAdd, + &temp_prefix, + &msg->l2_nextORpreviousHop + ); + } + } + } else { + // log error + openserial_printError( + 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(msg,RH3_length); + + // retrieve hop-by-hop header (includes RPL option) + rpi_length = iphc_retrieveIPv6HopByHopHeader( + msg, + rpl_option + ); + + // toss the headers + packetfunctions_tossHeader( + msg, + rpi_length + ); - // indicate reception to upper layer - 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: + flags = rpl_option->flags; + senderRank = rpl_option->senderRank; + if ((flags & O_FLAG)!=O_FLAG){ + // wrong direction + // log error openserial_printError( - COMPONENT_FORWARDING, - ERR_WRONG_TRAN_PROTOCOL, - (errorparameter_t)msg->l4_protocol, - (errorparameter_t)1 + COMPONENT_FORWARDING, + ERR_WRONG_DIRECTION, + (errorparameter_t)flags, + (errorparameter_t)senderRank ); - //not sure that this is correct as iphc will free it? - openqueue_freePacketBuffer(msg); - return E_FAIL; - } - - // stop executing here (successful) - return E_SUCCESS; - - } else { - // this is not the last hop - - if (rpl_routing_hdr->SegmentsLeft>numAddr) { - // error code: there are more segments left than space in source route - - // TODO: send ICMPv6 packet (code 0) to originator - - openserial_printError( - COMPONENT_FORWARDING, - ERR_NO_NEXTHOP, - (errorparameter_t)0, - (errorparameter_t)0 - ); - openqueue_freePacketBuffer(msg); - return E_FAIL; - - } else { - - // decrement number of segments left - rpl_routing_hdr->SegmentsLeft--; - - // find next hop address in source route, start from 0 - addressposition = numAddr-(rpl_routing_hdr->SegmentsLeft)-1; -// addressposition = rpl_routing_hdr->SegmentsLeft; - - // how many octets have the address? - if (rpl_routing_hdr->SegmentsLeft > 0){ - // max addr length - number of prefix octets that are elided in the internal route elements - octetsAddressSize = LENGTH_ADDR128b - local_CmprI; - } else { - // max addr length - number of prefix octets that are elided in the last route elements - octetsAddressSize = LENGTH_ADDR128b - local_CmprE; - } - - switch(octetsAddressSize) { - - case LENGTH_ADDR16b: - - // write previous hop - msg->l2_nextORpreviousHop.type = ADDR_16B; - memcpy( - &(msg->l2_nextORpreviousHop.addr_16b), - runningPointer+((addressposition)*octetsAddressSize), - octetsAddressSize - ); - - // write next hop - msg->l3_destinationAdd.type = ADDR_16B; - memcpy( - &(msg->l3_destinationAdd.addr_16b), - runningPointer+((addressposition)*octetsAddressSize), - octetsAddressSize - ); - - break; - - case LENGTH_ADDR64b: - - // write previous hop - msg->l2_nextORpreviousHop.type = ADDR_64B; - memcpy( - &(msg->l2_nextORpreviousHop.addr_64b), - runningPointer+((addressposition)*octetsAddressSize), - octetsAddressSize - ); - - //this is 128b address as send from forwarding function - //takes care of reducing it if needed. - - //write next hop - msg->l3_destinationAdd.type = ADDR_128B; - memcpy( - &(msg->l3_destinationAdd.addr_128b[0]), - prefix->prefix, - LENGTH_ADDR64b - ); - - memcpy( - &(msg->l3_destinationAdd.addr_128b[8]), - runningPointer+((addressposition)*octetsAddressSize), - octetsAddressSize - ); - - break; - - case LENGTH_ADDR128b: - - // write previous hop - msg->l2_nextORpreviousHop.type = ADDR_128B; - memcpy( - &(msg->l2_nextORpreviousHop.addr_128b), - runningPointer+((addressposition)*octetsAddressSize), - octetsAddressSize - ); - - // write next hop - msg->l3_destinationAdd.type = ADDR_128B; - memcpy( - &(msg->l3_destinationAdd.addr_128b), - runningPointer+((addressposition)*octetsAddressSize), - octetsAddressSize - ); - - break; - - default: - // any other value is not supported by now - - openserial_printError( - COMPONENT_FORWARDING, - ERR_INVALID_PARAM, - (errorparameter_t)1, - (errorparameter_t)0 - ); - openqueue_freePacketBuffer(msg); - return E_FAIL; - } - } - } - - // send to next lower layer - return iphc_sendFromForwarding( - msg, - ipv6_outer_header, - ipv6_inner_header, - &rpl_option, - &ipv6_outer_header->flow_label, - PCKTFORWARD - ); + } + if (senderRank > neighbors_getMyDAGrank()){ + // loop detected + // set flag + rpl_option->flags |= R_FLAG; + // log error + openserial_printError( + COMPONENT_FORWARDING, + ERR_LOOP_DETECTED, + (errorparameter_t) senderRank, + (errorparameter_t) neighbors_getMyDAGrank() + ); + } + forwarding_createRplOption(rpl_option, rpl_option->flags); + // toss the IP in IP 6LoRH + packetfunctions_tossHeader(msg, ipv6_outer_header->header_length); + } else { + RH3_length = 0; + } + + // send to next lower layer + return iphc_sendFromForwarding( + msg, + ipv6_outer_header, + ipv6_inner_header, + rpl_option, + &ipv6_outer_header->flow_label, + &RH3_copy[0], + RH3_length, + PCKTFORWARD + ); } @@ -657,16 +726,23 @@ owerror_t forwarding_send_internal_SourceRouting( \param[in] flags The flags to indicate in the RPL option. */ void forwarding_createRplOption(rpl_option_ht* rpl_option, uint8_t flags) { - // set the RPL hop-by-hop header - rpl_option->optionType = RPL_HOPBYHOP_HEADER_OPTION_TYPE; - - // 8-bit field indicating the length of the option, in - // octets, excluding the Option Type and Opt Data Len fields. - // 4-bytes, flags+instanceID+senderrank - no sub-tlvs - rpl_option->optionLen = 0x04; + uint8_t I,K; + rpl_option->optionType = RPL_HOPBYHOP_HEADER_OPTION_TYPE; + rpl_option->rplInstanceID = icmpv6rpl_getRPLIntanceID(); + rpl_option->senderRank = neighbors_getMyDAGrank(); - rpl_option->flags = flags; - rpl_option->rplInstanceID = icmpv6rpl_getRPLIntanceID(); - rpl_option->senderRank = neighbors_getMyDAGrank(); + if (rpl_option->rplInstanceID == 0){ + I = 1; + } else { + I = 0; + } + + if ((rpl_option->senderRank & 0x00FF) == 0){ + K = 1; + } else { + K = 0; + } + + rpl_option->flags = (flags & ~I_FLAG & ~K_FLAG) | (I<<1) | K; } diff --git a/openstack/03b-IPv6/forwarding.h b/openstack/03b-IPv6/forwarding.h index 649c3fc314..89479e5147 100644 --- a/openstack/03b-IPv6/forwarding.h +++ b/openstack/03b-IPv6/forwarding.h @@ -20,9 +20,12 @@ enum { }; enum { - O_FLAG = 0x80, - R_FLAG = 0x40, - F_FLAG = 0x20, + O_FLAG = 0x10, + R_FLAG = 0x08, + F_FLAG = 0x04, + I_FLAG = 0x02, + K_FLAG = 0x01, + FLAG_MASK = 0x1F, }; //=========================== typedef ========================================= @@ -55,7 +58,6 @@ void forwarding_receive( OpenQueueEntry_t* msg, ipv6_header_iht* ipv6_outer_header, ipv6_header_iht* ipv6_inner_header, - ipv6_hopbyhop_iht* ipv6_hop_header, rpl_option_ht* rpl_option ); diff --git a/openstack/03b-IPv6/icmpv6rpl.c b/openstack/03b-IPv6/icmpv6rpl.c index 468da3babd..b0cfc8b30a 100644 --- a/openstack/03b-IPv6/icmpv6rpl.c +++ b/openstack/03b-IPv6/icmpv6rpl.c @@ -152,6 +152,10 @@ void icmpv6rpl_writeDODAGid(uint8_t* dodagid) { uint8_t icmpv6rpl_getRPLIntanceID(){ return icmpv6rpl_vars.dao.rplinstanceId; } + +void icmpv6rpl_getRPLDODAGid(uint8_t* address_128b){ + memcpy(address_128b,icmpv6rpl_vars.dao.DODAGID,16); +} /** \brief Called when DIO/DAO was sent. diff --git a/openstack/03b-IPv6/icmpv6rpl.h b/openstack/03b-IPv6/icmpv6rpl.h index 515363c04e..8ca020ece4 100644 --- a/openstack/03b-IPv6/icmpv6rpl.h +++ b/openstack/03b-IPv6/icmpv6rpl.h @@ -162,6 +162,7 @@ void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, owerror_t error); void icmpv6rpl_receive(OpenQueueEntry_t* msg); void icmpv6rpl_writeDODAGid(uint8_t* dodagid); uint8_t icmpv6rpl_getRPLIntanceID(void); +void icmpv6rpl_getRPLDODAGid(uint8_t* address_128b); void icmpv6rpl_setDIOPeriod(uint16_t dioPeriod); void icmpv6rpl_setDAOPeriod(uint16_t daoPeriod); /** diff --git a/openstack/cross-layers/packetfunctions.c b/openstack/cross-layers/packetfunctions.c index b371645124..87b7f2dbc2 100644 --- a/openstack/cross-layers/packetfunctions.c +++ b/openstack/cross-layers/packetfunctions.c @@ -321,7 +321,7 @@ void packetfunctions_duplicatePacket(OpenQueueEntry_t* dst, OpenQueueEntry_t* sr dst->l2_ASNpayload = dst->payload + (src->l2_ASNpayload - src->payload); // update l2_scheduleIE_cellObjects pointer - dst->l2_scheduleIE_cellObjects = dst->payload + (src->l2_scheduleIE_cellObjects - src->payload); + dst->l2_sixtop_cellObjects = dst->payload + (src->l2_sixtop_cellObjects - src->payload); // update l2_payload pointer dst->l2_payload = dst->payload + (src->l2_payload - src->payload); diff --git a/projects/common/03oos_sniffer/03oos_sniffer.c b/projects/common/03oos_sniffer/03oos_sniffer.c index f3e2590657..426df7dca1 100644 --- a/projects/common/03oos_sniffer/03oos_sniffer.c +++ b/projects/common/03oos_sniffer/03oos_sniffer.c @@ -12,6 +12,9 @@ #include "03oos_sniffer.h" #include "openserial.h" #include "idmanager.h" +#include "sixtop.h" +#include "processIE.h" +#include "neighbors.h" //=========================== defines ========================================= @@ -160,17 +163,23 @@ void task_uploadPacket(){ void openbridge_triggerData(void){return;} void sixtop_setEBPeriod(uint8_t ebPeriod){return;} +void sixtop_addORremoveCellByInfo(uint8_t code,open_addr_t* neighbor,cellInfo_ht* cellInfo){return;} +void sixtop_request(uint8_t code,open_addr_t* neighbor, uint8_t numCells){return;} +void sixtop_setHandler(six2six_handler_t handler){return;} +void sixtop_setIsResponseEnabled(bool isEnabled){return;} void ieee154e_setSingleChannel(uint8_t channel){return;} void icmpv6rpl_setDIOPeriod(uint16_t dioPeriod) {return;} void icmpv6rpl_setDAOPeriod(uint16_t daoPeriod) {return;} void neighbors_setMyDAGrank(uint16_t rank) {return;} void sixtop_setKaPeriod(uint16_t kaPeriod) {return;} void ieee154e_setIsSecurityEnabled(bool isEnabled) {return;} +void ieee154e_setSlotDuration(uint16_t duration) {return;} void schedule_setFrameLength(uint16_t frameLength) {return;} void icmpv6rpl_writeDODAGid(uint8_t* dodagid) {return;} void ieee154e_setIsAckEnabled(bool isEnabled) {return;} void ieee154e_getAsn(uint8_t* array) {return;} void neighbors_updateMyDAGrankAndNeighborPreference(void) {return;} +bool neighbors_getPreferredParentEui64(open_addr_t* neighbor){return TRUE;} void schedule_startDAGroot(void) {return;} bool debugPrint_asn(void) {return TRUE;} diff --git a/projects/python/SConscript.env b/projects/python/SConscript.env index f607d71454..7b9b3d11be 100644 --- a/projects/python/SConscript.env +++ b/projects/python/SConscript.env @@ -510,6 +510,8 @@ functionsToChange = [ 'ieee154e_setIsAckEnabled', 'ieee154e_setSingleChannel', 'ieee154e_setIsSecurityEnabled', + 'ieee154e_setSlotDuration', + 'ieee154e_getSlotDuration', # topology 'topology_isAcceptablePacket', # neighbors @@ -536,17 +538,18 @@ functionsToChange = [ 'neighbors_setMyDAGrank', # processIE 'processIE_prependMLMEIE', + 'processIE_prepend_sixtopIE', 'processIE_prependSyncIE', 'processIE_prependSlotframeLinkIE', 'processIE_prependTSCHTimeslotIE', 'processIE_prependChannelHoppingIE', - 'processIE_prependOpcodeIE', - 'processIE_prependBandwidthIE', - 'processIE_prependScheduleIE', + 'processIE_prepend_sixSubIEHeader', + 'processIE_prepend_sixGeneralMessage', + 'processIE_prepend_sixSubID', + 'processIE_prepend_sixCelllist', + 'processIE_prepend_sixResponse', 'processIE_retrieveSlotframeLinkIE', - 'processIE_retrieveOpcodeIE', - 'processIE_retrieveBandwidthIE', - 'processIE_retrieveScheduleIE', + 'processIE_retrieve_sixCelllist', # schedule 'schedule_init', 'schedule_startDAGroot', @@ -561,6 +564,9 @@ functionsToChange = [ 'schedule_removeActiveSlot', 'schedule_isSlotOffsetAvailable', 'schedule_statistic_poorLinkQuality', + 'schedule_getCellsCounts', + 'schedule_removeAllCells', + 'schedule_getCurrentScheduleEntry', 'schedule_syncSlotOffset', 'schedule_advanceSlot', 'schedule_getNextActiveSlotOffset', @@ -575,7 +581,7 @@ functionsToChange = [ 'schedule_indicateRx', 'schedule_indicateTx', 'schedule_resetEntry', - # ord + # otf 'otf_init', 'otf_notif_addedCell', 'otf_notif_removedCell', @@ -586,15 +592,15 @@ functionsToChange = [ 'sixtop_setKaPeriod', 'sixtop_setEBPeriod', 'sixtop_setHandler', - 'sixtop_addCells', - 'sixtop_removeCell', - 'sixtop_removeCellByInfo', + 'sixtop_request', + 'sixtop_addORremoveCellByInfo', 'sixtop_maintaining', 'sixtop_send', 'task_sixtopNotifSendDone', 'task_sixtopNotifReceive', 'debugPrint_myDAGrank', 'debugPrint_kaPeriod', + 'sixtop_setIsResponseEnabled', 'sixtop_send_internal', 'sixtop_maintenance_timer_cb', 'sixtop_timeout_timer_cb', @@ -605,15 +611,13 @@ functionsToChange = [ 'sixtop_six2six_sendDone', 'sixtop_processIEs', 'sixtop_notifyReceiveCommand', - 'sixtop_notifyReceiveLinkRequest', - 'sixtop_linkResponse', - 'sixtop_notifyReceiveLinkResponse', - 'sixtop_notifyReceiveRemoveLinkRequest', + 'sixtop_getCelllist', 'sixtop_candidateAddCellList', 'sixtop_candidateRemoveCellList', 'sixtop_addCellsByState', 'sixtop_removeCellsByState', 'sixtop_areAvailableCellsToBeScheduled', + 'sixtop_areAvailableCellsToBeRemoved', # iphc 'iphc_init', 'iphc_sendFromForwarding', @@ -661,6 +665,7 @@ functionsToChange = [ 'icmpv6rpl_timer_DAO_task', 'sendDAO', 'icmpv6rpl_getRPLIntanceID', + 'icmpv6rpl_getRPLDODAGid', 'icmpv6rpl_writeDODAGid', 'icmpv6rpl_setDIOPeriod', 'icmpv6rpl_setDAOPeriod',