示例#1
0
/**
\brief Find neighbor to which to send KA.

This function iterates through the neighbor table and identifies the neighbor
we need to send a KA to, if any. This neighbor satisfies the following
conditions:
- it is one of our preferred parents
- we haven't heard it for over 

\return A pointer to te neighbor's address, or NULL if no KA is needed.
*/
open_addr_t* neighbors_KaNeighbor() {
   uint8_t      i;
   uint16_t     timeSinceHeard;
   open_addr_t* addrPreferred;
   open_addr_t* addrOther;
   // initialize
   addrPreferred = NULL;
   addrOther     = NULL;
   // scan through the neighbor table, and populate addrPreferred and addrOther
   for (i=0;i<MAXNUMNEIGHBORS;i++) {
      if (neighbors_vars.neighbors[i].used==1) {
         timeSinceHeard = ieee154e_asnDiff(&neighbors_vars.neighbors[i].asn);
         if (timeSinceHeard>KATIMEOUT) {
            // this neighbor needs to be KA'ed
            if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) {
               // its a preferred parent
               addrPreferred = &(neighbors_vars.neighbors[i].addr_64b);
            } else {
               // its not a preferred parent
               // poipoi: don't KA to non-preferred parent
               //addrOther =     &(neighbors_vars.neighbors[i].addr_64b);
            }
         }
      }
   }
   // return the addr of the most urgent KA to send
   if        (addrPreferred!=NULL) {
      return addrPreferred;
   } else if (addrOther!=NULL) {
      return addrOther;
   } else {
      return NULL;
   }
}
示例#2
0
/**
\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(&timesource, &(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), &timesource, sizeof(open_addr_t));
   }
}
示例#3
0
/**
\brief Calculate the compensation interval, in number of slots.

\param[in] timeCorrection time to be corrected

\returns compensationSlots the number of slots. 
*/
void adaptive_sync_calculateCompensatedSlots(int16_t timeCorrection) {
   bool     isFirstSync;              // is this the first sync after joining network?
   uint16_t totalTimeCorrectionTicks; // how much error in ticks since last synchronization.
   
   if(adaptive_sync_vars.clockState == S_NONE) {
      isFirstSync = TRUE;
   } else {
      isFirstSync = FALSE;
   }
   adaptive_sync_vars.elapsedSlots = ieee154e_asnDiff(&adaptive_sync_vars.oldASN);
   
   if(isFirstSync) {
      if(timeCorrection > 1) {
         adaptive_sync_vars.clockState = S_FASTER;
         adaptive_sync_vars.compensationInfo_vars.compensationSlots       = SYNC_ACCURACY*adaptive_sync_vars.elapsedSlots;
         adaptive_sync_vars.compensationInfo_vars.compensationSlots      /= timeCorrection;
      } else {
         if(timeCorrection < -1) {
            adaptive_sync_vars.clockState = S_SLOWER;
            adaptive_sync_vars.compensationInfo_vars.compensationSlots    = SYNC_ACCURACY*adaptive_sync_vars.elapsedSlots;
            adaptive_sync_vars.compensationInfo_vars.compensationSlots   /= (-timeCorrection);
         } else {
            //timeCorrection = {-1,1}, it's not accurate when timeCorrection belongs to {-1,1}
            //nothing is needed to do with this case.
         }
      }
   } else {
      if(adaptive_sync_vars.clockState == S_SLOWER) {
         totalTimeCorrectionTicks                                    = adaptive_sync_vars.compensateTicks;
         totalTimeCorrectionTicks                                   -= timeCorrection+adaptive_sync_vars.sumOfTC;
      } else {
         totalTimeCorrectionTicks                                    = adaptive_sync_vars.compensateTicks;
         totalTimeCorrectionTicks                                   += timeCorrection+adaptive_sync_vars.sumOfTC;
      }
      if(totalTimeCorrectionTicks == 0) {
         // totalTimeCorrectionTicks should be always positive if drift of clock is constant. if totalTimeCorrectionTIcks become zero, it means the drift changed for some reasons. 
         adaptive_sync_driftChanged();
      } else {
         adaptive_sync_vars.compensationInfo_vars.compensationSlots  = SYNC_ACCURACY*adaptive_sync_vars.elapsedSlots;
         adaptive_sync_vars.compensationInfo_vars.compensationSlots /= totalTimeCorrectionTicks;
      }
   }
   
   adaptive_sync_vars.compensationTimeout = adaptive_sync_vars.compensationInfo_vars.compensationSlots;
}
示例#4
0
/**
\brief Find neighbor to which to send KA.

This function iterates through the neighbor table and identifies the neighbor
we need to send a KA to, if any. This neighbor satisfies the following
conditions:
- it is one of our preferred parents
- we haven't heard it for over kaPeriod

\param[in] kaPeriod The maximum number of slots I'm allowed not to have heard
   it.

\returns A pointer to the neighbor's address, or NULL if no KA is needed.
*/
open_addr_t* neighbors_getKANeighbor(uint16_t kaPeriod) {
   uint8_t         i;
   uint16_t        timeSinceHeard;
   open_addr_t*    addrPreferred;
   open_addr_t*    addrOther;
   
   // initialize
   addrPreferred = NULL;
   addrOther     = NULL;
   
   // scan through the neighbor table, and populate addrPreferred and addrOther
   for (i=0;i<MAXNUMNEIGHBORS;i++) {
      if (neighbors_vars.neighbors[i].used==1) {
         timeSinceHeard = ieee154e_asnDiff(&neighbors_vars.neighbors[i].asn);
         if (timeSinceHeard>kaPeriod) {
            // this neighbor needs to be KA'ed to
            if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) {
               // its a preferred parent
               addrPreferred = &(neighbors_vars.neighbors[i].addr_64b);
            } else {
               // its not a preferred parent
               // Note: commented out since policy is not to KA to non-preferred parents
               // addrOther =     &(neighbors_vars.neighbors[i].addr_64b);
            }
         }
      }
   }
   
   // return the EUI64 of the most urgent KA to send:
   // - if available, preferred parent
   // - if not, non-preferred parent
   if        (addrPreferred!=NULL) {
      return addrPreferred;
   } else if (addrOther!=NULL) {
      return addrOther;
   } else {
      return NULL;
   }
}
void light_trigger_SENSOR(void) {
   bool                 iShouldSend;
   uint8_t              pktId;
#ifdef LIGHT_FAKESEND
   uint16_t             numAsnSinceLastEvent;
#else
   callbackRead_cbt     light_read_cb;
#endif
   
#ifdef LIGHT_FAKESEND
   // how many cells since the last time I transmitted?
   numAsnSinceLastEvent = ieee154e_asnDiff(&light_vars.lastEventAsn);
   
   // set light_reading to fake high/low value to trigger packets
   if (numAsnSinceLastEvent>LIGHT_FAKESEND_PERIOD) {
      if (light_vars.light_reading<LUX_THRESHOLD) {
         light_vars.light_reading=2*LUX_THRESHOLD;
      } else {
         light_vars.light_reading=0;
      }
   }
#else
   // current light reading
   light_read_cb             = sensors_getCallbackRead(SENSOR_LIGHT);
   light_vars.light_reading  = light_read_cb();
#endif
   
   // detect light state switches
   if (       light_vars.light_state==FALSE && (light_vars.light_reading >= (LUX_THRESHOLD + LUX_HYSTERESIS))) {
      // light was just turned on
      
      light_vars.light_state = TRUE;
      debugpins_light_set();
      leds_light_on();
      iShouldSend = TRUE;
   } else if (light_vars.light_state==TRUE  && (light_vars.light_reading <  (LUX_THRESHOLD - LUX_HYSTERESIS))) {
      // light was just turned off
      
      light_vars.light_state = FALSE;
      debugpins_light_clr();
      leds_light_off();
      iShouldSend = TRUE;
   } else {
      // light stays in same state
      
      iShouldSend = FALSE;
   }
   
   // abort if no packet to send
   if (iShouldSend==FALSE) {
      return;
   }
   
   //=== if I get here, I send a packet
   
   // remember the current ASN
   ieee154e_getAsnStruct(&light_vars.lastEventAsn);
   
   // increment the burstId
   light_vars.burstId = (light_vars.burstId+1)%16;
   
   // send burst of LIGHT_BURSTSIZE packets
   for (pktId=0;pktId<LIGHT_BURSTSIZE;pktId++) {
      light_send_one_packet(pktId);
   }
}