/** \brief Calculated how many slots have elapsed since last synchronized. \param[in] timeCorrection time to be corrected \param[in] timesource The address of neighbor. \return the number of slots */ void adaptive_sync_preprocess(int16_t timeCorrection, open_addr_t timesource){ uint8_t array[5]; // stop calculating compensation period when compensateThreshold exceeds KATIMEOUT and drift is not changed if( adaptive_sync_vars.compensateThreshold > MAXKAPERIOD && adaptive_sync_vars.driftChanged == FALSE ) { if(timeCorrection > LIMITLARGETIMECORRECTION) { //once I get a large time correction, it means previous calcluated drift is not accurate yet. The clock drift is changed. adaptive_sync_driftChanged(); } return; } // check whether I am synchronized and also check whether it's the same neighbor synchronized to last time? if( adaptive_sync_vars.driftChanged == FALSE && ieee154e_isSynch() && packetfunctions_sameAddress(×ource, &(adaptive_sync_vars.compensationInfo_vars.neighborID)) ) { // only calcluate when asnDiff > compensateThresholdThreshold. (this is used for guaranteeing accuracy ) if(ieee154e_asnDiff(&adaptive_sync_vars.oldASN) > adaptive_sync_vars.compensateThreshold) { // calculate compensation interval adaptive_sync_calculateCompensatedSlots(timeCorrection); // reset compensationtTicks and sumOfTC after calculation adaptive_sync_vars.compensateTicks = 0; adaptive_sync_vars.sumOfTC = 0; // update threshold adaptive_sync_vars.compensateThreshold *= 2; sixtop_setKaPeriod(adaptive_sync_vars.compensateThreshold); // update oldASN ieee154e_getAsn(array); adaptive_sync_vars.oldASN.bytes0and1 = ((uint16_t) array[1] << 8) | ((uint16_t) array[0]); adaptive_sync_vars.oldASN.bytes2and3 = ((uint16_t) array[3] << 8) | ((uint16_t) array[2]); adaptive_sync_vars.oldASN.byte4 = array[4]; } else { // record the timeCorrection, if not calculate. adaptive_sync_vars.sumOfTC += timeCorrection; } } else { adaptive_sync_vars.compensateThreshold = BASIC_COMPENSATION_THRESHOLD; sixtop_setKaPeriod(adaptive_sync_vars.compensateThreshold); // when I joined the network, or changed my time parent, reset adaptive_sync relative variables adaptive_sync_vars.clockState = S_NONE; adaptive_sync_vars.elapsedSlots = 0; adaptive_sync_vars.compensationTimeout = 0; adaptive_sync_vars.compensateTicks = 0; adaptive_sync_vars.sumOfTC = 0; // update oldASN ieee154e_getAsn(array); adaptive_sync_vars.oldASN.bytes0and1 = ((uint16_t) array[1] << 8) | ((uint16_t) array[0]); adaptive_sync_vars.oldASN.bytes2and3 = ((uint16_t) array[3] << 8) | ((uint16_t) array[2]); adaptive_sync_vars.oldASN.byte4 = array[4]; // record this neighbor as my time source memcpy(&(adaptive_sync_vars.compensationInfo_vars.neighborID), ×ource, sizeof(open_addr_t)); } }
void openserial_handleCommands(void){ uint8_t input_buffer[20]; uint8_t numDataBytes; uint8_t commandId; uint8_t commandLen; uint8_t comandParam_8; uint16_t comandParam_16; uint8_t code,cellOptions,numCell,listOffset,maxListLen; uint8_t ptr; cellInfo_ht celllist_add[CELLLIST_MAX_LEN]; cellInfo_ht celllist_delete[CELLLIST_MAX_LEN]; open_addr_t neighbor; bool foundNeighbor; ptr = 0; memset(celllist_add,0,CELLLIST_MAX_LEN*sizeof(cellInfo_ht)); memset(celllist_delete,0,CELLLIST_MAX_LEN*sizeof(cellInfo_ht)); numDataBytes = openserial_getInputBufferFillLevel(); //copying the buffer openserial_getInputBuffer(&(input_buffer[ptr]),numDataBytes); ptr++; commandId = openserial_vars.inputBuf[ptr]; ptr++; commandLen = openserial_vars.inputBuf[ptr]; ptr++; switch(commandId) { case COMMAND_SET_EBPERIOD: comandParam_8 = openserial_vars.inputBuf[ptr]; sixtop_setEBPeriod(comandParam_8); // one byte, in seconds break; case COMMAND_SET_CHANNEL: comandParam_8 = openserial_vars.inputBuf[ptr]; // set communication channel for protocol stack ieee154e_setSingleChannel(comandParam_8); // one byte break; case COMMAND_SET_KAPERIOD: // two bytes, in slots comandParam_16 = (openserial_vars.inputBuf[ptr] & 0x00ff) | \ ((openserial_vars.inputBuf[ptr+1]<<8) & 0xff00); sixtop_setKaPeriod(comandParam_16); break; case COMMAND_SET_DIOPERIOD: // two bytes, in mili-seconds comandParam_16 = (openserial_vars.inputBuf[ptr] & 0x00ff) | \ ((openserial_vars.inputBuf[ptr+1]<<8) & 0xff00); icmpv6rpl_setDIOPeriod(comandParam_16); break; case COMMAND_SET_DAOPERIOD: // two bytes, in mili-seconds comandParam_16 = (openserial_vars.inputBuf[ptr] & 0x00ff) | \ ((openserial_vars.inputBuf[ptr+1]<<8) & 0xff00); icmpv6rpl_setDAOPeriod(comandParam_16); break; case COMMAND_SET_DAGRANK: // two bytes comandParam_16 = (openserial_vars.inputBuf[ptr] & 0x00ff) | \ ((openserial_vars.inputBuf[ptr+1]<<8) & 0xff00); icmpv6rpl_setMyDAGrank(comandParam_16); break; case COMMAND_SET_SECURITY_STATUS: // one byte comandParam_8 = openserial_vars.inputBuf[ptr]; ieee154e_setIsSecurityEnabled(comandParam_8); break; case COMMAND_SET_SLOTFRAMELENGTH: // two bytes comandParam_16 = (openserial_vars.inputBuf[ptr] & 0x00ff) | \ ((openserial_vars.inputBuf[ptr+1]<<8) & 0xff00); schedule_setFrameLength(comandParam_16); break; case COMMAND_SET_ACK_STATUS: comandParam_8 = openserial_vars.inputBuf[ptr]; ieee154e_setIsAckEnabled(comandParam_8); break; case COMMAND_SET_6P_ADD: case COMMAND_SET_6P_DELETE: case COMMAND_SET_6P_RELOCATE: case COMMAND_SET_6P_COUNT: case COMMAND_SET_6P_LIST: case COMMAND_SET_6P_CLEAR: // get preferred parent foundNeighbor =icmpv6rpl_getPreferredParentEui64(&neighbor); if (foundNeighbor==FALSE) { break; } // the following sequence of bytes are, slotframe, cellOption, numCell, celllist openserial_get6pInfo(commandId,&code,&cellOptions,&numCell,celllist_add,celllist_delete,&listOffset,&maxListLen,ptr,commandLen); sixtop_request( code, // code &neighbor, // neighbor numCell, // number cells cellOptions, // cellOptions celllist_add, // celllist to add celllist_delete, // celllist to delete (not used) msf_getsfid(), // sfid listOffset, // list command offset (not used) maxListLen // list command maximum celllist (not used) ); break; case COMMAND_SET_SLOTDURATION: comandParam_16 = (openserial_vars.inputBuf[ptr] & 0x00ff) | \ ((openserial_vars.inputBuf[ptr+1]<<8) & 0xff00); ieee154e_setSlotDuration(comandParam_16); break; case COMMAND_SET_6PRESPONSE: comandParam_8 = openserial_vars.inputBuf[ptr]; if (comandParam_8 ==1) { sixtop_setIsResponseEnabled(TRUE); } else { if (comandParam_8 == 0) { sixtop_setIsResponseEnabled(FALSE); } else { // security only can be 1 or 0 break; } } break; case COMMAND_SET_UINJECTPERIOD: comandParam_8 = openserial_vars.inputBuf[ptr]; msf_appPktPeriod(comandParam_8); break; case COMMAND_SET_ECHO_REPLY_STATUS: comandParam_8 = openserial_vars.inputBuf[ptr]; if (comandParam_8 == 1) { icmpv6echo_setIsReplyEnabled(TRUE); } else { if (comandParam_8 == 0) { icmpv6echo_setIsReplyEnabled(FALSE); } else { // ack reply break; } } break; case COMMAND_SET_JOIN_KEY: if (commandLen != 16) { break; } idmanager_setJoinKey(&openserial_vars.inputBuf[ptr]); break; default: // wrong command ID break; } }