*** stock_iot-lab_M3/openwsn/02a-MAClow/IEEE802154E.c Thu Apr 24 11:01:36 2014 --- riot-openwsn-wip/openwsn/02a-MAClow/IEEE802154E.c Thu Apr 24 16:55:54 2014 *************** *** 9,126 **** #include "schedule.h" #include "packetfunctions.h" #include "scheduler.h" ! #include "leds.h" #include "neighbors.h" #include "debugpins.h" #include "res.h" //=========================== variables ======================================= ! typedef struct { ! // misc ! asn_t asn; // current absolute slot number ! slotOffset_t slotOffset; // current slot offset ! slotOffset_t nextActiveSlotOffset; // next active slot offset ! PORT_TIMER_WIDTH deSyncTimeout; // how many slots left before looses sync ! bool isSync; // TRUE iff mote is synchronized to network ! // as shown on the chronogram ! ieee154e_state_t state; // state of the FSM ! OpenQueueEntry_t* dataToSend; // pointer to the data to send ! OpenQueueEntry_t* dataReceived; // pointer to the data received ! OpenQueueEntry_t* ackToSend; // pointer to the ack to send ! OpenQueueEntry_t* ackReceived; // pointer to the ack received ! PORT_TIMER_WIDTH lastCapturedTime; // last captured time ! PORT_TIMER_WIDTH syncCapturedTime; // captured time used to sync ! //channel hopping ! uint8_t freq; // frequency of the current slot ! uint8_t asnOffset; // offset inside the frame ! } ieee154e_vars_t; ! ! ieee154e_vars_t ieee154e_vars; ! ! typedef struct { ! PORT_TIMER_WIDTH num_newSlot; ! PORT_TIMER_WIDTH num_timer; ! PORT_TIMER_WIDTH num_startOfFrame; ! PORT_TIMER_WIDTH num_endOfFrame; ! } ieee154e_dbg_t; ! ! ieee154e_dbg_t ieee154e_dbg; ! ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t numSyncPkt; // how many times synchronized on a non-ACK packet ! uint8_t numSyncAck; // how many times synchronized on an ACK ! PORT_SIGNED_INT_WIDTH minCorrection; // minimum time correction ! PORT_SIGNED_INT_WIDTH maxCorrection; // maximum time correction ! uint8_t numDeSync; // number of times a desync happened ! } ieee154e_stats_t; ! PRAGMA(pack()); ! ieee154e_stats_t ieee154e_stats; //=========================== prototypes ====================================== ! // SYNCHRONIZING ! void activity_synchronize_newSlot(); ! void activity_synchronize_startOfFrame(PORT_TIMER_WIDTH capturedTime); ! void activity_synchronize_endOfFrame(PORT_TIMER_WIDTH capturedTime); // TX ! void activity_ti1ORri1(); ! void activity_ti2(); ! void activity_tie1(); ! void activity_ti3(); ! void activity_tie2(); ! void activity_ti4(PORT_TIMER_WIDTH capturedTime); ! void activity_tie3(); ! void activity_ti5(PORT_TIMER_WIDTH capturedTime); ! void activity_ti6(); ! void activity_tie4(); ! void activity_ti7(); ! void activity_tie5(); ! void activity_ti8(PORT_TIMER_WIDTH capturedTime); ! void activity_tie6(); ! void activity_ti9(PORT_TIMER_WIDTH capturedTime); // RX ! void activity_ri2(); ! void activity_rie1(); ! void activity_ri3(); ! void activity_rie2(); ! void activity_ri4(PORT_TIMER_WIDTH capturedTime); ! void activity_rie3(); ! void activity_ri5(PORT_TIMER_WIDTH capturedTime); ! void activity_ri6(); ! void activity_rie4(); ! void activity_ri7(); ! void activity_rie5(); ! void activity_ri8(PORT_TIMER_WIDTH capturedTime); ! void activity_rie6(); ! void activity_ri9(PORT_TIMER_WIDTH capturedTime); // frame validity check ! bool isValidAdv(ieee802154_header_iht* ieee802514_header); bool isValidRxFrame(ieee802154_header_iht* ieee802514_header); bool isValidAck(ieee802154_header_iht* ieee802514_header, OpenQueueEntry_t* packetSent); // ASN handling ! void incrementAsnOffset(); ! void asnWriteToAdv(OpenQueueEntry_t* advFrame); ! void asnStoreFromAdv(OpenQueueEntry_t* advFrame); // synchronization ! void synchronizePacket(PORT_TIMER_WIDTH timeReceived); void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection); void changeIsSync(bool newIsSync); // notifying upper layer ! void notif_sendDone(OpenQueueEntry_t* packetSent, error_t error); void notif_receive(OpenQueueEntry_t* packetReceived); // statistics ! void resetStats(); void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection); // misc uint8_t calculateFrequency(uint8_t channelOffset); void changeState(ieee154e_state_t newstate); ! void endSlot(); ! bool debugPrint_asn(); ! bool debugPrint_isSync(); //=========================== admin =========================================== --- 9,99 ---- #include "schedule.h" #include "packetfunctions.h" #include "scheduler.h" ! #include "leds_ow.h" #include "neighbors.h" #include "debugpins.h" #include "res.h" + #include "thread.h" + + #define ENABLE_DEBUG (0) + #include "debug.h" + //=========================== variables ======================================= ! ieee154e_vars_t ieee154e_vars; ! ieee154e_stats_t ieee154e_stats; ! ieee154e_dbg_t ieee154e_dbg; ! //static char openwsn_ieee802154e_rec_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! //static char openwsn_ieee802154e_send_stack[KERNEL_CONF_STACKSIZE_MAIN]; //=========================== prototypes ====================================== ! void isr_ieee154e_newSlot(void); ! void isr_ieee154e_timer(void); // SYNCHRONIZING ! void activity_synchronize_newSlot(void); ! void activity_synchronize_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_synchronize_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); // TX ! void activity_ti1ORri1(void); ! void activity_ti2(void); ! void activity_tie1(void); ! void activity_ti3(void); ! void activity_tie2(void); ! void activity_ti4(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_tie3(void); ! void activity_ti5(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_ti6(void); ! void activity_tie4(void); ! void activity_ti7(void); ! void activity_tie5(void); ! void activity_ti8(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_tie6(void); ! void activity_ti9(PORT_RADIOTIMER_WIDTH capturedTime); // RX ! void activity_ri2(void); ! void activity_rie1(void); ! void activity_ri3(void); ! void activity_rie2(void); ! void activity_ri4(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_rie3(void); ! void activity_ri5(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_ri6(void); ! void activity_rie4(void); ! void activity_ri7(void); ! void activity_rie5(void); ! void activity_ri8(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_rie6(void); ! void activity_ri9(PORT_RADIOTIMER_WIDTH capturedTime); // frame validity check ! bool isValidRxFrame(ieee802154_header_iht* ieee802514_header); bool isValidAck(ieee802154_header_iht* ieee802514_header, OpenQueueEntry_t* packetSent); + // IEs Handling + bool ieee154e_processIEs(OpenQueueEntry_t* pkt, uint16_t * lenIE);//xv poipoi + void ieee154e_processSlotframeLinkIE(OpenQueueEntry_t* pkt,uint8_t * ptr);//xv poipoi // ASN handling ! void incrementAsnOffset(void); ! void asnStoreFromAdv(uint8_t* asn); ! void joinPriorityStoreFromAdv(uint8_t jp); // synchronization ! void synchronizePacket(PORT_RADIOTIMER_WIDTH timeReceived); void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection); void changeIsSync(bool newIsSync); // notifying upper layer ! void notif_sendDone(OpenQueueEntry_t* packetSent, owerror_t error); void notif_receive(OpenQueueEntry_t* packetReceived); // statistics ! void resetStats(void); void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection); // misc uint8_t calculateFrequency(uint8_t channelOffset); void changeState(ieee154e_state_t newstate); ! void endSlot(void); ! bool debugPrint_asn(void); ! bool debugPrint_isSync(void); //=========================== admin =========================================== *************** *** 130,137 **** Call this function once before any other function in this module, possibly during boot-up. */ ! void ieee154e_init() { ! // initialize variables memset(&ieee154e_vars,0,sizeof(ieee154e_vars_t)); memset(&ieee154e_dbg,0,sizeof(ieee154e_dbg_t)); --- 103,110 ---- Call this function once before any other function in this module, possibly during boot-up. */ ! void ieee154e_init(void) { ! DEBUG("%s\n",__PRETTY_FUNCTION__); // initialize variables memset(&ieee154e_vars,0,sizeof(ieee154e_vars_t)); memset(&ieee154e_dbg,0,sizeof(ieee154e_dbg_t)); *************** *** 162,178 **** /** /brief Difference between some older ASN and the current ASN. ! \param someASN [in] some ASN to compare to the current \returns The ASN difference, or 0xffff if more than 65535 different */ ! PORT_TIMER_WIDTH ieee154e_asnDiff(asn_t* someASN) { ! PORT_TIMER_WIDTH diff; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); if (ieee154e_vars.asn.byte4 != someASN->byte4) { ENABLE_INTERRUPTS(); ! return (PORT_TIMER_WIDTH)0xFFFFFFFF;; } diff = 0; --- 135,151 ---- /** /brief Difference between some older ASN and the current ASN. ! \param[in] someASN some ASN to compare to the current \returns The ASN difference, or 0xffff if more than 65535 different */ ! PORT_RADIOTIMER_WIDTH ieee154e_asnDiff(asn_t* someASN) { ! PORT_RADIOTIMER_WIDTH diff; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); if (ieee154e_vars.asn.byte4 != someASN->byte4) { ENABLE_INTERRUPTS(); ! return (PORT_RADIOTIMER_WIDTH)0xFFFFFFFF;; } diff = 0; *************** *** 184,190 **** diff += 0xffff-someASN->bytes0and1; diff += 1; } else { ! diff = (PORT_TIMER_WIDTH)0xFFFFFFFF;; } ENABLE_INTERRUPTS(); return diff; --- 157,163 ---- diff += 0xffff-someASN->bytes0and1; diff += 1; } else { ! diff = (PORT_RADIOTIMER_WIDTH)0xFFFFFFFF; } ENABLE_INTERRUPTS(); return diff; *************** *** 197,210 **** This function executes in ISR mode, when the new slot timer fires. */ ! void isr_ieee154e_newSlot() { radio_setTimerPeriod(TsSlotDuration); if (ieee154e_vars.isSync==FALSE) { ! activity_synchronize_newSlot(); } else { activity_ti1ORri1(); } ieee154e_dbg.num_newSlot++; } /** --- 170,196 ---- This function executes in ISR mode, when the new slot timer fires. */ ! void isr_ieee154e_newSlot(void) { ! DEBUG("%s\n",__PRETTY_FUNCTION__); radio_setTimerPeriod(TsSlotDuration); + DEBUG("step 1\n"); if (ieee154e_vars.isSync==FALSE) { ! DEBUG("step 2.1\n"); ! if (idmanager_getIsDAGroot()==TRUE) { ! DEBUG("step 2.1.1\n"); ! changeIsSync(TRUE); ! } else { ! DEBUG("step 2.1.2\n"); ! activity_synchronize_newSlot(); ! DEBUG("step 2.1.3\n"); ! } } else { + DEBUG("step 2.2.1\n"); activity_ti1ORri1(); + DEBUG("step 2.2.2\n"); } ieee154e_dbg.num_newSlot++; + DEBUG("end.\n"); } /** *************** *** 212,218 **** This function executes in ISR mode, when the FSM timer fires. */ ! void isr_ieee154e_timer() { switch (ieee154e_vars.state) { case S_TXDATAOFFSET: activity_ti2(); --- 198,204 ---- This function executes in ISR mode, when the FSM timer fires. */ ! void isr_ieee154e_timer(void) { switch (ieee154e_vars.state) { case S_TXDATAOFFSET: activity_ti2(); *************** *** 291,297 **** This function executes in ISR mode. */ ! void ieee154e_startOfFrame(PORT_TIMER_WIDTH capturedTime) { if (ieee154e_vars.isSync==FALSE) { activity_synchronize_startOfFrame(capturedTime); } else { --- 277,283 ---- This function executes in ISR mode. */ ! void ieee154e_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { if (ieee154e_vars.isSync==FALSE) { activity_synchronize_startOfFrame(capturedTime); } else { *************** *** 339,345 **** This function executes in ISR mode. */ ! void ieee154e_endOfFrame(PORT_TIMER_WIDTH capturedTime) { if (ieee154e_vars.isSync==FALSE) { activity_synchronize_endOfFrame(capturedTime); } else { --- 325,331 ---- This function executes in ISR mode. */ ! void ieee154e_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { if (ieee154e_vars.isSync==FALSE) { activity_synchronize_endOfFrame(capturedTime); } else { *************** *** 379,385 **** \returns TRUE if this function printed something, FALSE otherwise. */ ! bool debugPrint_asn() { asn_t output; output.byte4 = ieee154e_vars.asn.byte4; output.bytes2and3 = ieee154e_vars.asn.bytes2and3; --- 365,371 ---- \returns TRUE if this function printed something, FALSE otherwise. */ ! bool debugPrint_asn(void) { asn_t output; output.byte4 = ieee154e_vars.asn.byte4; output.bytes2and3 = ieee154e_vars.asn.bytes2and3; *************** *** 396,402 **** \returns TRUE if this function printed something, FALSE otherwise. */ ! bool debugPrint_isSync() { uint8_t output=0; output = ieee154e_vars.isSync; openserial_printStatus(STATUS_ISSYNC,(uint8_t*)&output,sizeof(uint8_t)); --- 382,388 ---- \returns TRUE if this function printed something, FALSE otherwise. */ ! bool debugPrint_isSync(void) { uint8_t output=0; output = ieee154e_vars.isSync; openserial_printStatus(STATUS_ISSYNC,(uint8_t*)&output,sizeof(uint8_t)); *************** *** 411,419 **** \returns TRUE if this function printed something, FALSE otherwise. */ ! bool debugPrint_macStats() { // send current stats over serial openserial_printStatus(STATUS_MACSTATS,(uint8_t*)&ieee154e_stats,sizeof(ieee154e_stats_t)); return TRUE; } --- 397,410 ---- \returns TRUE if this function printed something, FALSE otherwise. */ ! bool debugPrint_macStats(void) { // send current stats over serial + ieee154e_stats.dutyCycle/=(float)SUPERFRAME_LENGTH; //avg on the all slots of a frame + ieee154e_stats.dutyCycle/=STATUS_MAX;//because this is executed once every 10 times of debugprint + ieee154e_stats.dutyCycle*=100.0;//as is a percentage openserial_printStatus(STATUS_MACSTATS,(uint8_t*)&ieee154e_stats,sizeof(ieee154e_stats_t)); + ieee154e_stats.dutyCycle=0; //reset for the next superframe. + return TRUE; } *************** *** 421,455 **** //======= SYNCHRONIZING ! port_INLINE void activity_synchronize_newSlot() { // I'm in the middle of receiving a packet if (ieee154e_vars.state==S_SYNCRX) { return; } // if this is the first time I call this function while not synchronized, // switch on the radio in Rx mode if (ieee154e_vars.state!=S_SYNCLISTEN) { // change state changeState(S_SYNCLISTEN); ! // turn off the radio (in case it wasn't yet) radio_rfOff(); ! // configure the radio to listen to the default synchronizing channel radio_setFrequency(SYNCHRONIZING_CHANNEL); ! // update record of current channel ieee154e_vars.freq = SYNCHRONIZING_CHANNEL; // switch on the radio in Rx mode. radio_rxEnable(); radio_rxNow(); } // increment ASN (used only to schedule serial activity) incrementAsnOffset(); ! // to be able to receive and transmist serial even when not synchronized // take turns every 8 slots sending and receiving if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0000) { --- 412,453 ---- //======= SYNCHRONIZING ! port_INLINE void activity_synchronize_newSlot(void) { ! DEBUG("%s\n",__PRETTY_FUNCTION__); // I'm in the middle of receiving a packet if (ieee154e_vars.state==S_SYNCRX) { return; } + DEBUG("step 1\n"); // if this is the first time I call this function while not synchronized, // switch on the radio in Rx mode if (ieee154e_vars.state!=S_SYNCLISTEN) { + DEBUG("step 2.1\n"); // change state changeState(S_SYNCLISTEN); ! DEBUG("step 2.x\n"); // turn off the radio (in case it wasn't yet) radio_rfOff(); ! DEBUG("step 2.2\n"); // configure the radio to listen to the default synchronizing channel radio_setFrequency(SYNCHRONIZING_CHANNEL); ! DEBUG("step 2.3\n"); // update record of current channel ieee154e_vars.freq = SYNCHRONIZING_CHANNEL; // switch on the radio in Rx mode. radio_rxEnable(); + DEBUG("step 2.4\n"); + ieee154e_vars.radioOnInit=radio_getTimerValue(); + ieee154e_vars.radioOnThisSlot=TRUE; radio_rxNow(); + DEBUG("step 2.5\n"); } // increment ASN (used only to schedule serial activity) incrementAsnOffset(); ! DEBUG("step 3\n"); // to be able to receive and transmist serial even when not synchronized // take turns every 8 slots sending and receiving if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0000) { *************** *** 461,467 **** } } ! port_INLINE void activity_synchronize_startOfFrame(PORT_TIMER_WIDTH capturedTime) { // don't care about packet if I'm not listening if (ieee154e_vars.state!=S_SYNCLISTEN) { --- 459,465 ---- } } ! port_INLINE void activity_synchronize_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { // don't care about packet if I'm not listening if (ieee154e_vars.state!=S_SYNCLISTEN) { *************** *** 481,488 **** ieee154e_vars.syncCapturedTime = capturedTime; } ! port_INLINE void activity_synchronize_endOfFrame(PORT_TIMER_WIDTH capturedTime) { ieee802154_header_iht ieee802514_header; // check state if (ieee154e_vars.state!=S_SYNCRX) { --- 479,487 ---- ieee154e_vars.syncCapturedTime = capturedTime; } ! port_INLINE void activity_synchronize_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { ieee802154_header_iht ieee802514_header; + uint16_t lenIE=0;//len of IEs being received if any. // check state if (ieee154e_vars.state!=S_SYNCRX) { *************** *** 532,538 **** sizeof(ieee154e_vars.dataReceived->packet), &ieee154e_vars.dataReceived->l1_rssi, &ieee154e_vars.dataReceived->l1_lqi, ! &ieee154e_vars.dataReceived->l1_crc); // break if packet too short if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX) { --- 531,537 ---- sizeof(ieee154e_vars.dataReceived->packet), &ieee154e_vars.dataReceived->l1_rssi, &ieee154e_vars.dataReceived->l1_lqi, ! (uint8_t*)(&ieee154e_vars.dataReceived->l1_crc)); // break if packet too short if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX) { *************** *** 566,588 **** ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! // toss the IEEE802.15.4 header packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); // break if invalid ADV ! if (isValidAdv(&ieee802514_header)==FALSE) { // break from the do-while loop and execute the clean-up code below break; } // turn off the radio radio_rfOff(); ! // record the ASN from the ADV payload ! asnStoreFromAdv(ieee154e_vars.dataReceived); ! ! // toss the ADV payload ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ADV_PAYLOAD_LENGTH); // synchronize (for the first time) to the sender's ADV synchronizePacket(ieee154e_vars.syncCapturedTime); --- 565,592 ---- ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! // toss the IEEE802.15.4 header -- this does not include IEs as they are processed ! // next. packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); + // handle IEs -- xv poipoi // break if invalid ADV ! if ((ieee802514_header.valid==TRUE && ! ieee802514_header.ieListPresent==TRUE && ! ieee802514_header.frameType==IEEE154_TYPE_BEACON && ! packetfunctions_sameAddress(&ieee802514_header.panid,idmanager_getMyID(ADDR_PANID)) && ! ieee154e_processIEs(ieee154e_vars.dataReceived,&lenIE))==FALSE) { // break from the do-while loop and execute the clean-up code below break; } // turn off the radio radio_rfOff(); + //compute radio duty cycle + ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); ! // toss the IEs including Synch ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,lenIE); // synchronize (for the first time) to the sender's ADV synchronizePacket(ieee154e_vars.syncCapturedTime); *************** *** 619,631 **** changeState(S_SYNCLISTEN); } //======= TX ! port_INLINE void activity_ti1ORri1() { cellType_t cellType; open_addr_t neighbor; uint8_t i; ! // increment ASN (do this first so debug pins are in sync) incrementAsnOffset(); --- 623,782 ---- changeState(S_SYNCLISTEN); } + //xv poipoi - IE Handling + port_INLINE bool ieee154e_processIEs(OpenQueueEntry_t* pkt, uint16_t * lenIE) + { + uint8_t ptr,byte0,byte1; + uint8_t temp_8b,gr_elem_id,subid; + uint16_t temp_16b,len,sublen; + volatile PORT_SIGNED_INT_WIDTH timeCorrection; + + 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)>>IEEE802154E_DESC_LEN_PAYLOAD_IE_SHIFT; + 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)>>IEEE802154E_DESC_LEN_HEADER_IE_SHIFT; + 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: + //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)>>IEEE802154E_DESC_LEN_LONG_MLME_IE_SHIFT; + 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)>>IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT; + subid = (temp_16b & IEEE802154E_DESC_SUBID_SHORT_MLME_IE_MASK)>>IEEE802154E_DESC_SUBID_SHORT_MLME_IE_SHIFT; + } + switch(subid){ + case IEEE802154E_MLME_SYNC_IE_SUBID: + //content is ASN and Join Priority + if (idmanager_getIsDAGroot()==FALSE) { + asnStoreFromAdv((uint8_t*)(pkt->payload)+ptr); + ptr = ptr + 5; //add ASN len + joinPriorityStoreFromAdv(*((uint8_t*)(pkt->payload)+ptr)); + ptr = ptr + 1; + } + break; + case IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID: + ieee154e_processSlotframeLinkIE(pkt,&ptr); + break; + case IEEE802154E_MLME_TIMESLOT_IE_SUBID: + //TODO + break; + default: + return FALSE; + break; + } + len = len - sublen; + } while(len>0); + + break; + //the rest are elementID + case IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID: + //IE content is time correction -- apply the time correction on ack received. + if (idmanager_getIsDAGroot()==FALSE && + neighbors_isPreferredParent(&(pkt->l2_nextORpreviousHop)) ) { + byte0 = *((uint8_t*)(pkt->payload)+ptr); + ptr++; + byte1 = *((uint8_t*)(pkt->payload)+ptr); + ptr++; + + timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_RADIOTIMER_WIDTH)byte1<<8 | (PORT_RADIOTIMER_WIDTH)byte0); + timeCorrection /= US_PER_TICK; + timeCorrection = -timeCorrection; + synchronizeAck(timeCorrection); + } + 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, + (errorparameter_t)*lenIE, + (errorparameter_t)1); + } + return TRUE; + } + + port_INLINE void ieee154e_processSlotframeLinkIE(OpenQueueEntry_t* pkt,uint8_t * ptr){ + uint8_t numSlotFrames,i,j,localptr; + slotframelink_IE_t sfInfo; + linkInfo_subIE_t linkInfo; + localptr=*ptr; + // number of slot frames 1B + numSlotFrames = *((uint8_t*)(pkt->payload)+localptr); + localptr++; + // for each slotframe + i=0; + while(i < numSlotFrames){ + //1-slotftramehandle 1B + sfInfo.slotframehandle=*((uint8_t*)(pkt->payload)+localptr); + localptr++; + //2-slotframe size 2B + sfInfo.slotframesize = *((uint8_t*)(pkt->payload)+localptr); + localptr++; + sfInfo.slotframesize |= (*((uint8_t*)(pkt->payload)+localptr))<<8; + localptr++;; + //3-number of links 1B + sfInfo.numlinks= *((uint8_t*)(pkt->payload)+localptr); + localptr++; + + for (j=0;jpayload)+localptr); + localptr++; + linkInfo.tsNum |= (*((uint8_t*)(pkt->payload)+localptr))<<8; + localptr++; + //Ch.Offset 2B + linkInfo.choffset = *((uint8_t*)(pkt->payload)+localptr); + localptr++; + linkInfo.choffset |= (*((uint8_t*)(pkt->payload)+localptr))<<8; + localptr++; + //LinkOption bitmap 1B + linkInfo.linkoptions = *((uint8_t*)(pkt->payload)+localptr); + localptr++; + //xv poipoi + //TODO - inform schedule of that link so it can update if needed. + } + i++; + } + *ptr=localptr; + } + //======= TX ! port_INLINE void activity_ti1ORri1(void) { cellType_t cellType; open_addr_t neighbor; uint8_t i; ! synch_IE_t syn_IE; ! // increment ASN (do this first so debug pins are in sync) incrementAsnOffset(); *************** *** 703,711 **** // change state changeState(S_TXDATAOFFSET); // change owner ! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; // fill in the ASN field of the ADV ! asnWriteToAdv(ieee154e_vars.dataToSend); // record that I attempt to transmit this packet ieee154e_vars.dataToSend->l2_numTxAttempts++; // arm tt1 --- 854,867 ---- // change state changeState(S_TXDATAOFFSET); // change owner ! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; ! //copy synch IE -- should be Little endian??? // fill in the ASN field of the ADV ! ieee154e_getAsn(syn_IE.asn); ! syn_IE.join_priority = neighbors_getMyDAGrank()/(2*MINHOPRANKINCREASE); //poipoi -- use dagrank(rank) ! ! memcpy(ieee154e_vars.dataToSend->l2_ASNpayload,&syn_IE,sizeof(synch_IE_t)); ! // record that I attempt to transmit this packet ieee154e_vars.dataToSend->l2_numTxAttempts++; // arm tt1 *************** *** 779,785 **** } } ! port_INLINE void activity_ti2() { // change state changeState(S_TXDATAPREPARE); --- 935,941 ---- } } ! port_INLINE void activity_ti2(void) { // change state changeState(S_TXDATAPREPARE); *************** *** 787,793 **** ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); // configure the radio for that frequency - //radio_setFrequency(frequency); radio_setFrequency(ieee154e_vars.freq); // load the packet in the radio's Tx buffer --- 943,948 ---- *************** *** 796,802 **** // enable the radio in Tx mode. This does not send the packet. radio_txEnable(); ! // arm tt2 radiotimer_schedule(DURATION_tt2); --- 951,958 ---- // enable the radio in Tx mode. This does not send the packet. radio_txEnable(); ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; // arm tt2 radiotimer_schedule(DURATION_tt2); *************** *** 804,810 **** changeState(S_TXDATAREADY); } ! port_INLINE void activity_tie1() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXDATAPREPARE_OVERFLOW, (errorparameter_t)ieee154e_vars.state, --- 960,966 ---- changeState(S_TXDATAREADY); } ! port_INLINE void activity_tie1(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXDATAPREPARE_OVERFLOW, (errorparameter_t)ieee154e_vars.state, *************** *** 814,820 **** endSlot(); } ! port_INLINE void activity_ti3() { // change state changeState(S_TXDATADELAY); --- 970,976 ---- endSlot(); } ! port_INLINE void activity_ti3(void) { // change state changeState(S_TXDATADELAY); *************** *** 825,831 **** radio_txNow(); } ! port_INLINE void activity_tie2() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIO_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 981,987 ---- radio_txNow(); } ! port_INLINE void activity_tie2(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIO_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 835,841 **** endSlot(); } ! port_INLINE void activity_ti4(PORT_TIMER_WIDTH capturedTime) { // change state changeState(S_TXDATA); --- 991,998 ---- endSlot(); } ! //start of frame interrupt ! port_INLINE void activity_ti4(PORT_RADIOTIMER_WIDTH capturedTime) { // change state changeState(S_TXDATA); *************** *** 849,855 **** radiotimer_schedule(DURATION_tt4); } ! port_INLINE void activity_tie3() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 1006,1012 ---- radiotimer_schedule(DURATION_tt4); } ! port_INLINE void activity_tie3(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 859,865 **** endSlot(); } ! port_INLINE void activity_ti5(PORT_TIMER_WIDTH capturedTime) { bool listenForAck; // change state --- 1016,1022 ---- endSlot(); } ! port_INLINE void activity_ti5(PORT_RADIOTIMER_WIDTH capturedTime) { bool listenForAck; // change state *************** *** 869,875 **** radiotimer_cancel(); // turn off the radio ! radio_rfOff(); // record the captured time ieee154e_vars.lastCapturedTime = capturedTime; --- 1026,1033 ---- radiotimer_cancel(); // turn off the radio ! radio_rfOff(); ! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); // record the captured time ieee154e_vars.lastCapturedTime = capturedTime; *************** *** 896,902 **** } } ! port_INLINE void activity_ti6() { // change state changeState(S_RXACKPREPARE); --- 1054,1060 ---- } } ! port_INLINE void activity_ti6(void) { // change state changeState(S_RXACKPREPARE); *************** *** 904,915 **** ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); // configure the radio for that frequency - //radio_setFrequency(frequency); radio_setFrequency(ieee154e_vars.freq); // enable the radio in Rx mode. The radio is not actively listening yet. radio_rxEnable(); ! // arm tt6 radiotimer_schedule(DURATION_tt6); --- 1062,1074 ---- ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); // configure the radio for that frequency radio_setFrequency(ieee154e_vars.freq); // enable the radio in Rx mode. The radio is not actively listening yet. radio_rxEnable(); ! //caputre init of radio for duty cycle calculation ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; // arm tt6 radiotimer_schedule(DURATION_tt6); *************** *** 917,923 **** changeState(S_RXACKREADY); } ! port_INLINE void activity_tie4() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXACKPREPARE_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 1076,1082 ---- changeState(S_RXACKREADY); } ! port_INLINE void activity_tie4(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXACKPREPARE_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 927,933 **** endSlot(); } ! port_INLINE void activity_ti7() { // change state changeState(S_RXACKLISTEN); --- 1086,1092 ---- endSlot(); } ! port_INLINE void activity_ti7(void) { // change state changeState(S_RXACKLISTEN); *************** *** 938,944 **** radiotimer_schedule(DURATION_tt7); } ! port_INLINE void activity_tie5() { // indicate transmit failed to schedule to keep stats schedule_indicateTx(&ieee154e_vars.asn,FALSE); --- 1097,1103 ---- radiotimer_schedule(DURATION_tt7); } ! port_INLINE void activity_tie5(void) { // indicate transmit failed to schedule to keep stats schedule_indicateTx(&ieee154e_vars.asn,FALSE); *************** *** 960,966 **** endSlot(); } ! port_INLINE void activity_ti8(PORT_TIMER_WIDTH capturedTime) { // change state changeState(S_RXACK); --- 1119,1125 ---- endSlot(); } ! port_INLINE void activity_ti8(PORT_RADIOTIMER_WIDTH capturedTime) { // change state changeState(S_RXACK); *************** *** 974,989 **** radiotimer_schedule(DURATION_tt8); } ! port_INLINE void activity_tie6() { // abort endSlot(); } ! port_INLINE void activity_ti9(PORT_TIMER_WIDTH capturedTime) { ieee802154_header_iht ieee802514_header; ! volatile PORT_SIGNED_INT_WIDTH timeCorrection; ! uint8_t byte0; ! uint8_t byte1; // change state changeState(S_TXPROC); --- 1133,1147 ---- radiotimer_schedule(DURATION_tt8); } ! port_INLINE void activity_tie6(void) { // abort endSlot(); } ! port_INLINE void activity_ti9(PORT_RADIOTIMER_WIDTH capturedTime) { ieee802154_header_iht ieee802514_header; ! //volatile PORT_SIGNED_INT_WIDTH timeCorrection; ! uint16_t lenIE; // change state changeState(S_TXPROC); *************** *** 993,998 **** --- 1151,1158 ---- // turn off the radio radio_rfOff(); + //compute tics radio on. + ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); // record the captured time ieee154e_vars.lastCapturedTime = capturedTime; *************** *** 1031,1037 **** sizeof(ieee154e_vars.ackReceived->packet), &ieee154e_vars.ackReceived->l1_rssi, &ieee154e_vars.ackReceived->l1_lqi, ! &ieee154e_vars.ackReceived->l1_crc); // break if wrong length if (ieee154e_vars.ackReceived->lengthlength>LENGTH_IEEE154_MAX) { --- 1191,1197 ---- sizeof(ieee154e_vars.ackReceived->packet), &ieee154e_vars.ackReceived->l1_rssi, &ieee154e_vars.ackReceived->l1_lqi, ! (uint8_t*)&ieee154e_vars.ackReceived->l1_crc); // break if wrong length if (ieee154e_vars.ackReceived->lengthlength>LENGTH_IEEE154_MAX) { *************** *** 1074,1090 **** // break from the do-while loop and execute the clean-up code below break; } ! // resynchronize if I'm not a DAGroot and ACK from preferred parent ! if (idmanager_getIsDAGroot()==FALSE && ! neighbors_isPreferredParent(&(ieee154e_vars.ackReceived->l2_nextORpreviousHop)) ) { ! byte0 = ieee154e_vars.ackReceived->payload[0]; ! byte1 = ieee154e_vars.ackReceived->payload[1]; ! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_TIMER_WIDTH)byte1<<8 | (PORT_TIMER_WIDTH)byte0); ! timeCorrection /= US_PER_TICK; ! timeCorrection = -timeCorrection; ! synchronizeAck(timeCorrection); } // inform schedule of successful transmission schedule_indicateTx(&ieee154e_vars.asn,TRUE); --- 1234,1251 ---- // break from the do-while loop and execute the clean-up code below break; } + //hanlde IEs --xv poipoi + if (ieee802514_header.ieListPresent==FALSE){ + break; //ack should contain IEs. + } ! if (ieee154e_processIEs(ieee154e_vars.ackReceived,&lenIE)==FALSE){ ! //invalid IEs on ACK. ! break; } + + // toss the IEs including ACK -- xv poipoi + packetfunctions_tossHeader(ieee154e_vars.ackReceived,lenIE); // inform schedule of successful transmission schedule_indicateTx(&ieee154e_vars.asn,TRUE); *************** *** 1108,1114 **** //======= RX ! port_INLINE void activity_ri2() { // change state changeState(S_RXDATAPREPARE); --- 1269,1275 ---- //======= RX ! port_INLINE void activity_ri2(void) { // change state changeState(S_RXDATAPREPARE); *************** *** 1116,1127 **** ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); // configure the radio for that frequency - //radio_setFrequency(frequency); radio_setFrequency(ieee154e_vars.freq); // enable the radio in Rx mode. The radio does not actively listen yet. radio_rxEnable(); ! // arm rt2 radiotimer_schedule(DURATION_rt2); --- 1277,1288 ---- ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); // configure the radio for that frequency radio_setFrequency(ieee154e_vars.freq); // enable the radio in Rx mode. The radio does not actively listen yet. radio_rxEnable(); ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; // arm rt2 radiotimer_schedule(DURATION_rt2); *************** *** 1130,1136 **** changeState(S_RXDATAREADY); } ! port_INLINE void activity_rie1() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXDATAPREPARE_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 1291,1297 ---- changeState(S_RXDATAREADY); } ! port_INLINE void activity_rie1(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXDATAPREPARE_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 1140,1146 **** endSlot(); } ! port_INLINE void activity_ri3() { // change state changeState(S_RXDATALISTEN); --- 1301,1307 ---- endSlot(); } ! port_INLINE void activity_ri3(void) { // change state changeState(S_RXDATALISTEN); *************** *** 1151,1162 **** radiotimer_schedule(DURATION_rt3); } ! port_INLINE void activity_rie2() { // abort endSlot(); } ! port_INLINE void activity_ri4(PORT_TIMER_WIDTH capturedTime) { // change state changeState(S_RXDATA); --- 1312,1324 ---- radiotimer_schedule(DURATION_rt3); } ! port_INLINE void activity_rie2(void) { // abort endSlot(); } ! port_INLINE void activity_ri4(PORT_RADIOTIMER_WIDTH capturedTime) { ! // change state changeState(S_RXDATA); *************** *** 1168,1179 **** // record the captured time to sync ieee154e_vars.syncCapturedTime = capturedTime; ! ! // arm rt4 radiotimer_schedule(DURATION_rt4); } ! port_INLINE void activity_rie3() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 1330,1341 ---- // record the captured time to sync ieee154e_vars.syncCapturedTime = capturedTime; ! radiotimer_schedule(DURATION_rt4); } ! port_INLINE void activity_rie3(void) { ! // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 1183,1200 **** endSlot(); } ! port_INLINE void activity_ri5(PORT_TIMER_WIDTH capturedTime) { ieee802154_header_iht ieee802514_header; // change state changeState(S_TXACKOFFSET); // cancel rt4 radiotimer_cancel(); ! // turn off the radio ! radio_rfOff(); ! // get a buffer to put the (received) data in ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); if (ieee154e_vars.dataReceived==NULL) { --- 1345,1363 ---- endSlot(); } ! port_INLINE void activity_ri5(PORT_RADIOTIMER_WIDTH capturedTime) { ieee802154_header_iht ieee802514_header; + uint16_t lenIE=0; // change state changeState(S_TXACKOFFSET); // cancel rt4 radiotimer_cancel(); ! // turn off the radio ! //radio_rfOff(); ! ieee154e_vars.radioOnTics+=radio_getTimerValue()-ieee154e_vars.radioOnInit; // get a buffer to put the (received) data in ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); if (ieee154e_vars.dataReceived==NULL) { *************** *** 1230,1236 **** sizeof(ieee154e_vars.dataReceived->packet), &ieee154e_vars.dataReceived->l1_rssi, &ieee154e_vars.dataReceived->l1_lqi, ! &ieee154e_vars.dataReceived->l1_crc); // break if wrong length if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX ) { --- 1393,1399 ---- sizeof(ieee154e_vars.dataReceived->packet), &ieee154e_vars.dataReceived->l1_rssi, &ieee154e_vars.dataReceived->l1_lqi, ! (uint8_t*)&ieee154e_vars.dataReceived->l1_crc); // break if wrong length if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX ) { *************** *** 1267,1281 **** // toss the IEEE802.15.4 header packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); ! // if I just received a valid ADV, record the ASN and toss the ADV payload ! if (isValidAdv(&ieee802514_header)==TRUE) { ! if (idmanager_getIsDAGroot()==FALSE) { ! asnStoreFromAdv(ieee154e_vars.dataReceived); ! } ! // toss the ADV payload ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ADV_PAYLOAD_LENGTH); } // record the captured time ieee154e_vars.lastCapturedTime = capturedTime; --- 1430,1448 ---- // toss the IEEE802.15.4 header packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); ! // handle IEs xv poipoi ! //reset join priority ! ! if ((ieee802514_header.valid==TRUE && ! ieee802514_header.ieListPresent==TRUE && ! packetfunctions_sameAddress(&ieee802514_header.panid,idmanager_getMyID(ADDR_PANID)) && ! ieee154e_processIEs(ieee154e_vars.dataReceived,&lenIE))==FALSE) { ! //log that the packet is not carrying IEs } + // toss the IEs including Synch + packetfunctions_tossHeader(ieee154e_vars.dataReceived,lenIE); + // record the captured time ieee154e_vars.lastCapturedTime = capturedTime; *************** *** 1317,1324 **** endSlot(); } ! port_INLINE void activity_ri6() { PORT_SIGNED_INT_WIDTH timeCorrection; // change state changeState(S_TXACKPREPARE); --- 1484,1492 ---- endSlot(); } ! port_INLINE void activity_ri6(void) { PORT_SIGNED_INT_WIDTH timeCorrection; + header_IE_descriptor_t header_desc; // change state changeState(S_TXACKPREPARE); *************** *** 1345,1363 **** // calculate the time timeCorrection (this is the time when the packet arrive w.r.t the time it should be. timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)ieee154e_vars.syncCapturedTime-(PORT_SIGNED_INT_WIDTH)TsTxOffset); ! // add the payload to the ACK (i.e. the timeCorrection) ! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(IEEE802154E_ACK_ht)); timeCorrection = -timeCorrection; timeCorrection *= US_PER_TICK; ! ieee154e_vars.ackToSend->payload[0] = (uint8_t)((((PORT_TIMER_WIDTH)timeCorrection) ) & 0xff); ! ieee154e_vars.ackToSend->payload[1] = (uint8_t)((((PORT_TIMER_WIDTH)timeCorrection)>>8) & 0xff); // prepend the IEEE802.15.4 header to the ACK ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; ieee154e_vars.ackToSend->l2_dsn = ieee154e_vars.dataReceived->l2_dsn; ieee802154_prependHeader(ieee154e_vars.ackToSend, ieee154e_vars.ackToSend->l2_frameType, IEEE154_SEC_NO_SECURITY, ieee154e_vars.dataReceived->l2_dsn, &(ieee154e_vars.dataReceived->l2_nextORpreviousHop) --- 1513,1541 ---- // calculate the time timeCorrection (this is the time when the packet arrive w.r.t the time it should be. timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)ieee154e_vars.syncCapturedTime-(PORT_SIGNED_INT_WIDTH)TsTxOffset); ! // add the payload to the ACK (i.e. the timeCorrection) ! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(ack_timecorrection_IE_t)); timeCorrection = -timeCorrection; timeCorrection *= US_PER_TICK; ! ieee154e_vars.ackToSend->payload[0] = (uint8_t)((((PORT_RADIOTIMER_WIDTH)timeCorrection) ) & 0xff); ! ieee154e_vars.ackToSend->payload[1] = (uint8_t)((((PORT_RADIOTIMER_WIDTH)timeCorrection)>>8) & 0xff); ! ! // add header IE header -- xv poipoi -- pkt is filled in reverse order.. ! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(header_IE_descriptor_t)); ! //create the header for ack IE ! header_desc.length_elementid_type=(sizeof(ack_timecorrection_IE_t)<< IEEE802154E_DESC_LEN_HEADER_IE_SHIFT)| ! (IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID << IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT)| ! IEEE802154E_DESC_TYPE_SHORT; ! memcpy(ieee154e_vars.ackToSend->payload,&header_desc,sizeof(header_IE_descriptor_t)); // prepend the IEEE802.15.4 header to the ACK ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; ieee154e_vars.ackToSend->l2_dsn = ieee154e_vars.dataReceived->l2_dsn; ieee802154_prependHeader(ieee154e_vars.ackToSend, ieee154e_vars.ackToSend->l2_frameType, + IEEE154_IELIST_YES,//ie in ack + IEEE154_FRAMEVERSION,//enhanced ack IEEE154_SEC_NO_SECURITY, ieee154e_vars.dataReceived->l2_dsn, &(ieee154e_vars.dataReceived->l2_nextORpreviousHop) *************** *** 1370,1376 **** ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); // configure the radio for that frequency - //radio_setFrequency(frequency); radio_setFrequency(ieee154e_vars.freq); // load the packet in the radio's Tx buffer --- 1548,1553 ---- *************** *** 1379,1385 **** // enable the radio in Tx mode. This does not send that packet. radio_txEnable(); ! // arm rt6 radiotimer_schedule(DURATION_rt6); --- 1556,1563 ---- // enable the radio in Tx mode. This does not send that packet. radio_txEnable(); ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; // arm rt6 radiotimer_schedule(DURATION_rt6); *************** *** 1387,1393 **** changeState(S_TXACKREADY); } ! port_INLINE void activity_rie4() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXACKPREPARE_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 1565,1571 ---- changeState(S_TXACKREADY); } ! port_INLINE void activity_rie4(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXACKPREPARE_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 1397,1403 **** endSlot(); } ! port_INLINE void activity_ri7() { // change state changeState(S_TXACKDELAY); --- 1575,1581 ---- endSlot(); } ! port_INLINE void activity_ri7(void) { // change state changeState(S_TXACKDELAY); *************** *** 1405,1414 **** radiotimer_schedule(DURATION_rt7); // give the 'go' to transmit ! radio_txNow(); } ! port_INLINE void activity_rie5() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIOTX_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 1583,1592 ---- radiotimer_schedule(DURATION_rt7); // give the 'go' to transmit ! radio_txNow(); } ! port_INLINE void activity_rie5(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIOTX_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 1418,1424 **** endSlot(); } ! port_INLINE void activity_ri8(PORT_TIMER_WIDTH capturedTime) { // change state changeState(S_TXACK); --- 1596,1602 ---- endSlot(); } ! port_INLINE void activity_ri8(PORT_RADIOTIMER_WIDTH capturedTime) { // change state changeState(S_TXACK); *************** *** 1432,1438 **** radiotimer_schedule(DURATION_rt8); } ! port_INLINE void activity_rie6() { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDACKDURATION_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, --- 1610,1616 ---- radiotimer_schedule(DURATION_rt8); } ! port_INLINE void activity_rie6(void) { // log the error openserial_printError(COMPONENT_IEEE802154E,ERR_WDACKDURATION_OVERFLOWS, (errorparameter_t)ieee154e_vars.state, *************** *** 1442,1448 **** endSlot(); } ! port_INLINE void activity_ri9(PORT_TIMER_WIDTH capturedTime) { // change state changeState(S_RXPROC); --- 1620,1626 ---- endSlot(); } ! port_INLINE void activity_ri9(PORT_RADIOTIMER_WIDTH capturedTime) { // change state changeState(S_RXPROC); *************** *** 1476,1502 **** //======= frame validity check /** - \brief Decides whether the packet I just received is a valid ADV - - \param [in] ieee802514_header IEEE802.15.4 header of the packet I just - received. - - A valid ADV frame satisfies the following conditions: - - its IEEE802.15.4 header is well formatted - - it's a BEACON frame - - it's sent to the my PANid - - its payload length is the expected ADV payload length - - \returns TRUE if packet is a valid ADV, FALSE otherwise - */ - port_INLINE bool isValidAdv(ieee802154_header_iht* ieee802514_header) { - return ieee802514_header->valid==TRUE && \ - ieee802514_header->frameType==IEEE154_TYPE_BEACON && \ - packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ - ieee154e_vars.dataReceived->length==ADV_PAYLOAD_LENGTH; - } - - /** \brief Decides whether the packet I just received is valid received frame. A valid Rx frame satisfies the following constraints: --- 1654,1659 ---- *************** *** 1505,1511 **** - it's sent on the same PANid as mine - it's for me (unicast or broadcast) ! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just received \returns TRUE if packet is valid received frame, FALSE otherwise */ --- 1662,1668 ---- - it's sent on the same PANid as mine - it's for me (unicast or broadcast) ! \param[in] ieee802514_header IEEE802.15.4 header of the packet I just received \returns TRUE if packet is valid received frame, FALSE otherwise */ *************** *** 1533,1540 **** - the packet is unicast to me - the packet comes from the neighbor I sent the data to ! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just received ! \param [in] packetSent points to the packet I just sent \returns TRUE if packet is a valid ACK, FALSE otherwise. */ --- 1690,1697 ---- - the packet is unicast to me - the packet comes from the neighbor I sent the data to ! \param[in] ieee802514_header IEEE802.15.4 header of the packet I just received ! \param[in] packetSent points to the packet I just sent \returns TRUE if packet is a valid ACK, FALSE otherwise. */ *************** *** 1557,1563 **** //======= ASN handling ! port_INLINE void incrementAsnOffset() { // increment the asn ieee154e_vars.asn.bytes0and1++; if (ieee154e_vars.asn.bytes0and1==0) { --- 1714,1720 ---- //======= ASN handling ! port_INLINE void incrementAsnOffset(void) { // increment the asn ieee154e_vars.asn.bytes0and1++; if (ieee154e_vars.asn.bytes0and1==0) { *************** *** 1571,1610 **** ieee154e_vars.asnOffset = (ieee154e_vars.asnOffset+1)%16; } ! port_INLINE void asnWriteToAdv(OpenQueueEntry_t* advFrame) { ! advFrame->l2_payload[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); ! advFrame->l2_payload[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); ! advFrame->l2_payload[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); ! advFrame->l2_payload[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); ! advFrame->l2_payload[4] = ieee154e_vars.asn.byte4; } ! //from upper layer that want to send the ASN to compute timming or latency ! void asnWriteToPkt(OpenQueueEntry_t* frame) { ! frame->payload[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); ! frame->payload[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); ! frame->payload[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); ! frame->payload[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); ! frame->payload[4] = ieee154e_vars.asn.byte4; } - void asnWriteToSerial(uint8_t* array) { - array[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); - array[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); - array[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); - array[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); - array[4] = ieee154e_vars.asn.byte4; - } ! ! port_INLINE void asnStoreFromAdv(OpenQueueEntry_t* advFrame) { // store the ASN ! ieee154e_vars.asn.bytes0and1 = ieee154e_vars.dataReceived->payload[0]+ ! 256*ieee154e_vars.dataReceived->payload[1]; ! ieee154e_vars.asn.bytes2and3 = ieee154e_vars.dataReceived->payload[2]+ ! 256*ieee154e_vars.dataReceived->payload[3]; ! ieee154e_vars.asn.byte4 = ieee154e_vars.dataReceived->payload[4]; // determine the current slotOffset /* --- 1728,1756 ---- ieee154e_vars.asnOffset = (ieee154e_vars.asnOffset+1)%16; } ! //from upper layer that want to send the ASN to compute timing or latency ! port_INLINE void ieee154e_getAsn(uint8_t* array) { ! array[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); ! array[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); ! array[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); ! array[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); ! array[4] = ieee154e_vars.asn.byte4; } ! port_INLINE void joinPriorityStoreFromAdv(uint8_t jp){ ! ieee154e_vars.dataReceived->l2_joinPriority = jp; ! ieee154e_vars.dataReceived->l2_joinPriorityPresent = TRUE; } ! port_INLINE void asnStoreFromAdv(uint8_t* asn) { // store the ASN ! ieee154e_vars.asn.bytes0and1 = asn[0]+ ! 256*asn[1]; ! ieee154e_vars.asn.bytes2and3 = asn[2]+ ! 256*asn[3]; ! ieee154e_vars.asn.byte4 = asn[4]; // determine the current slotOffset /* *************** *** 1624,1634 **** //======= synchronization ! void synchronizePacket(PORT_TIMER_WIDTH timeReceived) { PORT_SIGNED_INT_WIDTH timeCorrection; ! PORT_TIMER_WIDTH newPeriod; ! PORT_TIMER_WIDTH currentValue; ! PORT_TIMER_WIDTH currentPeriod; // record the current timer value and period currentValue = radio_getTimerValue(); currentPeriod = radio_getTimerPeriod(); --- 1770,1780 ---- //======= synchronization ! void synchronizePacket(PORT_RADIOTIMER_WIDTH timeReceived) { PORT_SIGNED_INT_WIDTH timeCorrection; ! PORT_RADIOTIMER_WIDTH newPeriod; ! PORT_RADIOTIMER_WIDTH currentValue; ! PORT_RADIOTIMER_WIDTH currentPeriod; // record the current timer value and period currentValue = radio_getTimerValue(); currentPeriod = radio_getTimerPeriod(); *************** *** 1641,1647 **** newPeriod += TsSlotDuration; incrementAsnOffset(); } ! newPeriod = (PORT_TIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)newPeriod+timeCorrection); // resynchronize by applying the new period radio_setTimerPeriod(newPeriod); // reset the de-synchronization timeout --- 1787,1793 ---- newPeriod += TsSlotDuration; incrementAsnOffset(); } ! newPeriod = (PORT_RADIOTIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)newPeriod+timeCorrection); // resynchronize by applying the new period radio_setTimerPeriod(newPeriod); // reset the de-synchronization timeout *************** *** 1664,1674 **** } void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection) { ! PORT_TIMER_WIDTH newPeriod; ! PORT_TIMER_WIDTH currentPeriod; // calculate new period currentPeriod = radio_getTimerPeriod(); ! newPeriod = (PORT_TIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)currentPeriod-timeCorrection); // resynchronize by applying the new period radio_setTimerPeriod(newPeriod); // reset the de-synchronization timeout --- 1810,1821 ---- } void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection) { ! PORT_RADIOTIMER_WIDTH newPeriod; ! PORT_RADIOTIMER_WIDTH currentPeriod; // calculate new period currentPeriod = radio_getTimerPeriod(); ! newPeriod = (PORT_RADIOTIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)currentPeriod-timeCorrection); ! // resynchronize by applying the new period radio_setTimerPeriod(newPeriod); // reset the de-synchronization timeout *************** *** 1704,1710 **** //======= notifying upper layer ! void notif_sendDone(OpenQueueEntry_t* packetSent, error_t error) { // record the outcome of the trasmission attempt packetSent->l2_sendDoneError = error; // record the current ASN --- 1851,1857 ---- //======= notifying upper layer ! void notif_sendDone(OpenQueueEntry_t* packetSent, owerror_t error) { // record the outcome of the trasmission attempt packetSent->l2_sendDoneError = error; // record the current ASN *************** *** 1714,1719 **** --- 1861,1869 ---- packetSent->owner = COMPONENT_IEEE802154E_TO_RES; // post RES's sendDone task scheduler_push_task(task_resNotifSendDone,TASKPRIO_RESNOTIF_TXDONE); + /*thread_create(openwsn_ieee802154e_send_stack, KERNEL_CONF_STACKSIZE_MAIN, + PRIORITY_OPENWSN_IEEE802154E, CREATE_STACKTEST, + task_resNotifSendDone, "task resNotifSendDone");*/ // wake up the scheduler SCHEDULER_WAKEUP(); } *************** *** 1726,1744 **** // associate this packet with the virtual component // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it packetReceived->owner = COMPONENT_IEEE802154E_TO_RES; // post RES's Receive task scheduler_push_task(task_resNotifReceive,TASKPRIO_RESNOTIF_RX); // wake up the scheduler SCHEDULER_WAKEUP(); } //======= stats ! port_INLINE void resetStats() { ieee154e_stats.numSyncPkt = 0; ieee154e_stats.numSyncAck = 0; ieee154e_stats.minCorrection = 127; ieee154e_stats.maxCorrection = -127; // do not reset the number of de-synchronizations } --- 1876,1899 ---- // associate this packet with the virtual component // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it packetReceived->owner = COMPONENT_IEEE802154E_TO_RES; + // post RES's Receive task scheduler_push_task(task_resNotifReceive,TASKPRIO_RESNOTIF_RX); + /*thread_create(openwsn_ieee802154e_rec_stack, KERNEL_CONF_STACKSIZE_MAIN, + PRIORITY_OPENWSN_IEEE802154E, CREATE_STACKTEST, + task_resNotifSendDone, "task resNotifSendDone");*/ // wake up the scheduler SCHEDULER_WAKEUP(); } //======= stats ! port_INLINE void resetStats(void) { ieee154e_stats.numSyncPkt = 0; ieee154e_stats.numSyncAck = 0; ieee154e_stats.minCorrection = 127; ieee154e_stats.maxCorrection = -127; + ieee154e_stats.dutyCycle = 0; // do not reset the number of de-synchronizations } *************** *** 1769,1775 **** to use a single-channel sniffer; but you can not schedule two links on two different channel offsets in the same slot. ! \param [in] channelOffset channel offset for the current slot \returns The calculated frequency channel, an integer between 11 and 26. */ --- 1924,1930 ---- to use a single-channel sniffer; but you can not schedule two links on two different channel offsets in the same slot. ! \param[in] channelOffset channel offset for the current slot \returns The calculated frequency channel, an integer between 11 and 26. */ *************** *** 1785,1791 **** Besides simply updating the state global variable, this function toggles the FSM debug pin. ! \param [in] newstate The state the IEEE802.15.4e FSM is now in. */ void changeState(ieee154e_state_t newstate) { // update the state --- 1940,1946 ---- Besides simply updating the state global variable, this function toggles the FSM debug pin. ! \param[in] newstate The state the IEEE802.15.4e FSM is now in. */ void changeState(ieee154e_state_t newstate) { // update the state *************** *** 1839,1848 **** function should already have been done. If this is not the case, this function will do that for you, but assume that something went wrong. */ ! void endSlot() { // turn off the radio radio_rfOff(); ! // clear any pending timer radiotimer_cancel(); --- 1994,2008 ---- function should already have been done. If this is not the case, this function will do that for you, but assume that something went wrong. */ ! void endSlot(void) { ! ! float aux; //duty cycle helper. // turn off the radio radio_rfOff(); ! // compute the duty cycle if radio has been turned on ! if (ieee154e_vars.radioOnThisSlot==TRUE){ ! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); ! } // clear any pending timer radiotimer_cancel(); *************** *** 1850,1855 **** --- 2010,2022 ---- ieee154e_vars.lastCapturedTime = 0; ieee154e_vars.syncCapturedTime = 0; + //instant duty cycle.. average is computed at debugprint_macstats. + aux=(float)ieee154e_vars.radioOnTics/(float)radio_getTimerPeriod(); + ieee154e_stats.dutyCycle+=aux;//accumulate and avg will be done on serial print + //clear vars for duty cycle on this slot + ieee154e_vars.radioOnTics=0; + ieee154e_vars.radioOnThisSlot=FALSE; + // clean up dataToSend if (ieee154e_vars.dataToSend!=NULL) { // if everything went well, dataToSend was set to NULL in ti9 *************** *** 1899,1908 **** ieee154e_vars.ackReceived = NULL; } // change state changeState(S_SLEEP); } ! bool ieee154e_isSynch(){ return ieee154e_vars.isSync; ! } \ No newline at end of file --- 2066,2076 ---- ieee154e_vars.ackReceived = NULL; } + // change state changeState(S_SLEEP); } ! bool ieee154e_isSynch(void){ return ieee154e_vars.isSync; ! }