* ========================================================================
*/
+/**
+ * This module is responsible for periodic beacon tracking in a
+ * beacon-enabled PAN.
+ */
#include "TKN154_MAC.h"
-#include "TKN154_DEBUG.h"
module BeaconSynchronizeP
{
interface MLME_SYNC;
interface MLME_BEACON_NOTIFY;
interface MLME_SYNC_LOSS;
+ interface SuperframeStructure as IncomingSF;
interface GetNow<bool> as IsTrackingBeacons;
- interface GetNow<uint32_t> as CapStart;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint32_t> as CapLen;
- interface GetNow<uint32_t> as CapEnd;
- interface GetNow<uint32_t> as CfpEnd;
- interface GetNow<uint32_t> as CfpLen;
- interface GetNow<uint32_t> as BeaconInterval;
- interface GetNow<bool> as IsBLEActive;
- interface GetNow<uint16_t> as BLELen;
- interface GetNow<uint8_t*> as GtsField;
- interface GetNow<uint32_t> as SfSlotDuration;
- interface GetNow<uint8_t> as FinalCapSlot;
- interface GetNow<uint8_t> as NumGtsSlots;
- interface GetNow<bool> as IsRxBroadcastPending;
+ interface StdControl as TrackSingleBeacon;
}
uses
{
interface MLME_GET;
interface MLME_SET;
interface FrameUtility;
- interface Notify<bool> as FindBeacon;
interface IEEE154BeaconFrame as BeaconFrame;
interface Alarm<TSymbolIEEE802154,uint32_t> as TrackAlarm;
interface RadioRx as BeaconRx;
interface RadioOff;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface DataRequest;
interface FrameRx as CoordRealignmentRx;
interface Resource as Token;
interface TimeCalc;
interface IEEE154Frame as Frame;
interface Leds;
- interface Ieee802154Debug as Debug;
}
}
implementation
{
+ /* state variables */
+ norace bool m_tracking;
+ bool m_stopTracking ;
+ norace uint8_t m_numBeaconsLost;
+ norace uint8_t m_state;
+ norace bool m_bufferBusy;
- enum {
- S_PREPARE = 0,
- S_RXNOW = 1,
- S_RADIO_OFF = 2,
- S_FIRST_SCAN= 3,
-
- RX_DURATION = 1000, // listen for a beacon for RX_DURATION symbols
- RX_LAG = 100, // start to listen for a RX_LAG before expected arrival
- };
-
- norace bool m_tracking = FALSE;
- norace bool m_updatePending = FALSE;
+ /* buffers for the parameters of the MLME-SYNC request */
+ norace bool m_updatePending;
uint8_t m_updateLogicalChannel;
bool m_updateTrackBeacon;
- bool m_stopTracking = FALSE;
- bool m_internalRequest = FALSE;
- norace uint8_t m_numBeaconsLost;
- message_t m_beaconBuffer;
- norace message_t *m_beaconBufferPtr = &m_beaconBuffer;
- norace bool m_beaconSwapBufferReady = TRUE;
+ /* variables that describe the current configuration */
norace uint32_t m_beaconInterval;
norace uint32_t m_dt;
norace uint32_t m_lastBeaconRxTime;
- norace ieee154_reftime_t m_lastBeaconRxRefTime;
- norace uint8_t m_state;
+ norace ieee154_timestamp_t m_lastBeaconRxRefTime;
norace uint8_t m_beaconOrder;
+ message_t m_beacon;
+ norace message_t *m_beaconPtr = &m_beacon;
+
+ /* variables that describe the latest superframe */
norace uint32_t m_sfSlotDuration;
- norace uint8_t m_finalCapSlot;
+ norace bool m_framePendingBit;
+ norace uint8_t m_numCapSlots;
norace uint8_t m_numGtsSlots;
- norace uint16_t m_BLELen;
- norace bool m_broadcastPending;
+ norace uint16_t m_battLifeExtDuration;
uint8_t m_gtsField[1+1+3*7];
+
+ enum {
+ S_PREPARE = 0,
+ S_RECEIVING = 1,
+ S_RADIO_OFF = 2,
+ S_INITIAL_SCAN= 3,
+
+ };
+
+ /* function/task prototypes */
task void processBeaconTask();
- void getNextBeacon();
+ void trackNextBeacon();
task void signalGrantedTask();
command error_t Reset.init()
{
- if (call Token.isOwner()){
- call Leds.led0On(); // internal error
- return FAIL;
- }
+ // reset this component. will only be called
+ // while we're not owning the token
if (m_tracking || m_updatePending)
signal MLME_SYNC_LOSS.indication(
IEEE154_BEACON_LOSS,
return SUCCESS;
}
-/* ----------------------- MLME-SYNC ----------------------- */
-/*
- * Allows to synchronize with a coordinator.
- */
+ /* ----------------------- MLME-SYNC ----------------------- */
+ /*
+ * Allows to synchronize with the beacons from a coordinator.
+ */
command ieee154_status_t MLME_SYNC.request (
uint8_t logicalChannel,
uint8_t channelPage,
bool trackBeacon)
{
+ error_t status = IEEE154_SUCCESS;
uint32_t supportedChannels = IEEE154_SUPPORTED_CHANNELS;
uint32_t currentChannelBit = 1;
currentChannelBit <<= logicalChannel;
if (!(currentChannelBit & supportedChannels) || (call MLME_GET.macPANId() == 0xFFFF) ||
- (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !call IsBeaconEnabledPAN.getNow())
- return IEEE154_INVALID_PARAMETER;
-
- call Debug.log(DEBUG_LEVEL_INFO,0, logicalChannel, channelPage, trackBeacon);
- if (!trackBeacon && m_tracking){
- // stop tracking after next received beacon
- m_stopTracking = TRUE;
- } else {
- m_stopTracking = FALSE;
- m_updateLogicalChannel = logicalChannel;
- m_updateTrackBeacon = trackBeacon;
- m_internalRequest = FALSE;
- m_updatePending = TRUE;
- call Debug.log(DEBUG_LEVEL_INFO,1, 0, 0, 0);
- atomic {
- // if we are tracking then we'll get the Token automatically,
- // otherwise request it now
- if (!m_tracking && !call Token.isOwner())
- call Token.request();
+ (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !IEEE154_BEACON_ENABLED_PAN)
+ status = IEEE154_INVALID_PARAMETER;
+ else {
+ if (!trackBeacon && m_tracking) {
+ // stop tracking after next received beacon
+ m_stopTracking = TRUE;
+ } else {
+ m_stopTracking = FALSE;
+ m_updateLogicalChannel = logicalChannel;
+ m_updateTrackBeacon = trackBeacon;
+ m_updatePending = TRUE;
+ atomic {
+ // if we are tracking then we'll get the Token automatically,
+ // otherwise request it now
+ if (!m_tracking && !call Token.isOwner())
+ call Token.request();
+ }
}
}
- call Debug.flush();
- return IEEE154_SUCCESS;
- }
-
- event void FindBeacon.notify( bool val )
- {
- call Debug.log(DEBUG_LEVEL_IMPORTANT,20, m_tracking, m_updatePending, 0);
- if (!m_tracking && !m_updatePending && !call Token.isOwner()){
- // find a single beacon now (treat this like a user request)
- m_updateLogicalChannel = call MLME_GET.phyCurrentChannel();
- m_updateTrackBeacon = FALSE;
- m_updatePending = TRUE;
- m_internalRequest = TRUE;
- call Token.request();
- }
+ dbg_serial("BeaconSynchronizeP", "MLME_SYNC.request -> result: %lu\n", (uint32_t) status);
+ return status;
}
event void Token.granted()
{
- call Debug.log(DEBUG_LEVEL_INFO,2, m_lastBeaconRxTime+m_beaconInterval,
- m_beaconInterval, (m_updatePending<<1)+m_tracking);
- if (m_updatePending){
- m_state = S_FIRST_SCAN;
+ dbg_serial("BeaconSynchronizeP","Got token, expecting beacon in %lu\n",
+ (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow()));
+ if (m_updatePending) {
+ dbg_serial("BeaconSynchronizeP", "Preparing initial scan\n");
+ m_state = S_INITIAL_SCAN;
m_updatePending = FALSE;
m_beaconOrder = call MLME_GET.macBeaconOrder();
if (m_beaconOrder >= 15)
m_beaconInterval = ((uint32_t) 1 << m_beaconOrder) * (uint32_t) IEEE154_aBaseSuperframeDuration;
m_dt = m_beaconInterval;
m_numBeaconsLost = IEEE154_aMaxLostBeacons; // will be reset when beacon is received
- call Debug.log(DEBUG_LEVEL_INFO,3, call MLME_GET.macCoordShortAddress(),
- call MLME_GET.macPANId(), m_updateLogicalChannel);
}
- getNextBeacon();
- call Debug.flush();
+ trackNextBeacon();
+ }
+
+ async event void TokenTransferred.transferred()
+ {
+ dbg_serial("BeaconSynchronizeP","Token.transferred(), expecting beacon in %lu symbols.\n",
+ (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow()));
+ if (call IsTokenRequested.getNow()) {
+ // some other component needs the token - we give it up for now,
+ // but make another request to get it back later
+ dbg_serial("BeaconSynchronizeP", "Token is requested, releasing it now.\n");
+ call Token.request();
+ call Token.release();
+ } else if (m_updatePending)
+ post signalGrantedTask();
+ else
+ trackNextBeacon();
}
- void getNextBeacon()
+
+ task void signalGrantedTask()
+ {
+ signal Token.granted();
+ }
+
+ void trackNextBeacon()
{
bool missed = FALSE;
- if (m_state != S_FIRST_SCAN){
+
+ if (m_state != S_INITIAL_SCAN) {
// we have received at least one previous beacon
m_state = S_PREPARE;
- if (!m_tracking){
+ if (!m_tracking) {
// nothing to do, just give up the token
- call Debug.log(DEBUG_LEVEL_INFO,4, 0, 0, 0);
+ dbg_serial("BeaconSynchronizeP", "Stop tracking.\n");
call Token.release();
return;
}
- while (call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt)){ // missed a beacon!
+ while (call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt)) { // missed a beacon!
+ dbg_serial("BeaconSynchronizeP", "Missed a beacon, expected it: %lu, now: %lu\n",
+ m_lastBeaconRxTime + m_dt, call TrackAlarm.getNow());
missed = TRUE;
- call Debug.log(DEBUG_LEVEL_IMPORTANT,5, m_lastBeaconRxTime, m_dt, missed);
m_dt += m_beaconInterval;
m_numBeaconsLost++;
}
- if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons){
- call Debug.log(DEBUG_LEVEL_IMPORTANT,19, m_numBeaconsLost, m_dt, missed);
+ if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons) {
+ dbg_serial("BeaconSynchronizeP", "Missed too many beacons.\n");
post processBeaconTask();
return;
}
- if (missed){
+ if (missed) {
+ // let other components get a chance to use the radio
call Token.request();
- call Debug.log(DEBUG_LEVEL_IMPORTANT,6, m_lastBeaconRxTime, m_dt, missed);
+ dbg_serial("BeaconSynchronizeP", "Allowing other components to get the token.\n");
call Token.release();
return;
}
}
- if (!call RadioOff.isOff())
- call RadioOff.off();
- else
+ if (call RadioOff.isOff())
signal RadioOff.offDone();
- }
-
- async event void TokenTransferred.transferred()
- {
- if (call IsTokenRequested.getNow()){
- // some other component needs the token - we give it up for now,
- // but make another request to get it back later
- call Token.request();
- call Token.release();
- } else if (m_updatePending)
- post signalGrantedTask();
else
- getNextBeacon();
+ ASSERT(call RadioOff.off() == SUCCESS);
}
- task void signalGrantedTask()
+ async event void RadioOff.offDone()
{
- signal Token.granted();
+ uint32_t delay = IEEE154_RADIO_RX_DELAY + IEEE154_MAX_BEACON_JITTER(m_beaconOrder);
+
+ if (m_state == S_INITIAL_SCAN) {
+ // initial scan
+ call BeaconRx.enableRx(0, 0);
+ } else if (m_state == S_PREPARE) {
+ if (!call TimeCalc.hasExpired(m_lastBeaconRxTime - delay, m_dt))
+ call TrackAlarm.startAt(m_lastBeaconRxTime - delay, m_dt);
+ else
+ signal TrackAlarm.fired();
+ } else {
+ post processBeaconTask();
+ }
}
- async event void TrackAlarm.fired()
+ async event void BeaconRx.enableRxDone()
{
- call Debug.log(DEBUG_LEVEL_INFO,7, m_state,m_lastBeaconRxTime,m_dt);
switch (m_state)
{
+ case S_INITIAL_SCAN:
+ m_state = S_RECEIVING;
+ call TrackAlarm.start((((uint32_t) 1 << m_beaconOrder) + (uint32_t) 1) *
+ (uint32_t) IEEE154_aBaseSuperframeDuration * (uint32_t) IEEE154_aMaxLostBeacons);
+ break;
case S_PREPARE:
- call BeaconRx.prepare();
+ m_state = S_RECEIVING;
+ dbg_serial("BeaconSynchronizeP","Rx enabled, expecting beacon in %lu symbols.\n",
+ (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow()));
+ call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt + IEEE154_MAX_BEACON_LISTEN_TIME(m_beaconOrder));
break;
- case S_RADIO_OFF:
- call RadioOff.off();
+ default:
+ ASSERT(0);
break;
}
}
- async event void BeaconRx.prepareDone()
+ async event void TrackAlarm.fired()
{
- error_t result;
- if (m_state == S_FIRST_SCAN){
- m_state = S_RADIO_OFF;
- atomic {
- call BeaconRx.receive(NULL, 0);
- call TrackAlarm.start((((uint32_t) 1 << m_beaconOrder) + (uint32_t) 1) *
- (uint32_t) IEEE154_aBaseSuperframeDuration * (uint32_t) IEEE154_aMaxLostBeacons);
- }
+ if (m_state == S_PREPARE) {
+ uint32_t maxBeaconJitter = IEEE154_MAX_BEACON_JITTER(m_beaconOrder);
+ if (maxBeaconJitter > m_dt)
+ maxBeaconJitter = m_dt; // receive immediately
+ call BeaconRx.enableRx(m_lastBeaconRxTime, m_dt - maxBeaconJitter);
} else {
- m_state = S_RADIO_OFF;
- result = call BeaconRx.receive(&m_lastBeaconRxRefTime, m_dt-RX_LAG);
- //__nesc_enable_interrupt();
- call Debug.log(DEBUG_LEVEL_INFO,8, m_lastBeaconRxTime, 0,(m_lastBeaconRxTime+m_dt) - call TrackAlarm.getNow());
- if (result != SUCCESS)
- call Debug.log(DEBUG_LEVEL_CRITICAL,9, result, 0, 0);
- call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt + RX_DURATION);
+ ASSERT(m_state == S_RECEIVING && call RadioOff.off() == SUCCESS);
}
}
- event message_t* BeaconRx.received(message_t *frame, ieee154_reftime_t *timestamp)
+ event message_t* BeaconRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
{
- uint8_t *mhr = MHR(frame);
- call Debug.log(DEBUG_LEVEL_INFO,10,*((nxle_uint32_t*) &mhr[MHR_INDEX_ADDRESS]),
- mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK,mhr[MHR_INDEX_SEQNO]);
- if (!m_beaconSwapBufferReady || !call FrameUtility.isBeaconFromCoord(frame))
+ if (m_bufferBusy || !call FrameUtility.isBeaconFromCoord(frame))
{
- call Debug.log(DEBUG_LEVEL_IMPORTANT,11, m_beaconSwapBufferReady, 0, 0);
+ if (m_bufferBusy) {
+ dbg_serial("BeaconSynchronizeP", "Got another beacon, dropping it.\n");}
+ else
+ dbg_serial("BeaconSynchronizeP", "Got a beacon, but not from my coordinator.\n");
return frame;
} else {
- error_t resultOff;
- message_t *tmp = m_beaconBufferPtr;
- call TrackAlarm.stop();
- m_beaconSwapBufferReady = FALSE;
- m_beaconBufferPtr = frame;
- resultOff = call RadioOff.off();
- if (timestamp != NULL){
- memcpy(&m_lastBeaconRxRefTime, timestamp, sizeof(ieee154_reftime_t));
- call Debug.log(DEBUG_LEVEL_INFO,23,0, 0, resultOff);
+ message_t *tmp = m_beaconPtr;
+ m_bufferBusy = TRUE;
+ m_beaconPtr = frame;
+ if (timestamp != NULL)
+ memcpy(&m_lastBeaconRxRefTime, timestamp, sizeof(ieee154_timestamp_t));
+ if (m_state == S_RECEIVING) {
+ call TrackAlarm.stop(); // may fail
+ call RadioOff.off(); // may fail
}
return tmp;
}
}
- async event void RadioOff.offDone()
- {
- if (m_state == S_FIRST_SCAN)
- call BeaconRx.prepare();
- else if (m_state == S_PREPARE){
- if (!call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt - IEEE154_RADIO_RX_PREPARE_DELAY))
- call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt - IEEE154_RADIO_RX_PREPARE_DELAY);
- else
- signal TrackAlarm.fired();
- } else {
- post processBeaconTask();
- }
- }
-
task void processBeaconTask()
{
- // valid beacon timestamp is pre-condition for slotted CSMA-CA
- if (m_beaconSwapBufferReady || !call Frame.isTimestampValid(m_beaconBufferPtr)){
- // missed a beacon!
- if (!m_beaconSwapBufferReady)
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 21,m_numBeaconsLost,m_beaconSwapBufferReady,m_lastBeaconRxTime);
+ // if we received a beacon from our coordinator then it is processed now
+ if (!m_bufferBusy || !call Frame.isTimestampValid(m_beaconPtr)) {
+ // missed a beacon or received a beacon with invalid timestamp
+ if (!m_bufferBusy)
+ dbg_serial("BeaconSynchronizeP", "No beacon received!\n");
else
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 12,m_numBeaconsLost,m_beaconSwapBufferReady,m_lastBeaconRxTime);
- m_sfSlotDuration = 0; // CAP len will be 0
- m_numBeaconsLost++;
+ dbg_serial("BeaconSynchronizeP", "Beacon has invalid timestamp!\n");
+
+ m_numBeaconsLost += 1;
m_dt += m_beaconInterval;
- m_beaconSwapBufferReady = TRUE;
- if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons){
+ m_bufferBusy = FALSE;
+
+ if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons) {
+ // lost too many beacons, give up!
m_tracking = FALSE;
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 13,m_internalRequest,0,0);
- call Leds.led2Off();
- if (m_internalRequest){
- call TokenToCap.transfer();
- return;
- } else
- signal MLME_SYNC_LOSS.indication(
+ dbg_serial("BeaconSynchronizeP", "MLME_SYNC_LOSS!\n");
+ signal MLME_SYNC_LOSS.indication(
IEEE154_BEACON_LOSS,
call MLME_GET.macPANId(),
call MLME_GET.phyCurrentChannel(),
call MLME_GET.phyCurrentPage(),
- NULL // security
- );
+ NULL);
} else
call Token.request(); // make another request again (before giving the token up)
- call Debug.log(DEBUG_LEVEL_INFO,14, 0, 0, 0);
+
call Token.release();
} else {
// got the beacon!
- uint8_t *payload = (uint8_t *) m_beaconBufferPtr->data;
+ uint8_t *payload = (uint8_t *) m_beaconPtr->data;
ieee154_macAutoRequest_t autoRequest = call MLME_GET.macAutoRequest();
uint8_t pendAddrSpecOffset = 3 + (((payload[2] & 7) > 0) ? 1 + (payload[2] & 7) * 3: 0); // skip GTS
uint8_t pendAddrSpec = payload[pendAddrSpecOffset];
uint8_t *beaconPayload = payload + pendAddrSpecOffset + 1;
- uint8_t beaconPayloadSize = call BeaconFrame.getBeaconPayloadLength(m_beaconBufferPtr);
+ uint8_t beaconPayloadSize = call BeaconFrame.getBeaconPayloadLength(m_beaconPtr);
uint8_t pendingAddrMode = ADDR_MODE_NOT_PRESENT;
uint8_t coordBeaconOrder;
- uint8_t *mhr = MHR(m_beaconBufferPtr);
- uint8_t frameLen = ((uint8_t*) m_beaconBufferPtr)[0] & FRAMECTL_LENGTH_MASK;
+ uint8_t *mhr = MHR(m_beaconPtr);
+ uint8_t frameLen = ((uint8_t*) m_beaconPtr)[0] & FRAMECTL_LENGTH_MASK;
uint8_t gtsFieldLength;
- uint32_t timestamp = call Frame.getTimestamp(m_beaconBufferPtr);
+ uint32_t timestamp = call Frame.getTimestamp(m_beaconPtr);
+
+ dbg_serial("BeaconSynchronizeP", "Got beacon, timestamp: %lu, offset to previous: %lu\n",
+ (uint32_t) timestamp, (uint32_t) (timestamp - m_lastBeaconRxTime));
- call Debug.log(DEBUG_LEVEL_INFO, 15, m_lastBeaconRxTime, timestamp, mhr[2]);
m_numGtsSlots = (payload[2] & 7);
gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
m_lastBeaconRxTime = timestamp;
- m_finalCapSlot = (payload[1] & 0x0F);
+ m_numCapSlots = (payload[1] & 0x0F) + 1;
m_sfSlotDuration = (((uint32_t) 1) << ((payload[0] & 0xF0) >> 4)) * IEEE154_aBaseSlotDuration;
memcpy(m_gtsField, &payload[2], gtsFieldLength);
// check for battery life extension
- if (payload[1] & 0x10){
+ if (payload[1] & 0x10) {
// BLE is active; calculate the time offset from slot0
- m_BLELen = IEEE154_SHR_DURATION + frameLen * IEEE154_SYMBOLS_PER_OCTET;
+ m_battLifeExtDuration = IEEE154_SHR_DURATION + frameLen * IEEE154_SYMBOLS_PER_OCTET;
if (frameLen > IEEE154_aMaxSIFSFrameSize)
- m_BLELen += call MLME_GET.macMinLIFSPeriod();
+ m_battLifeExtDuration += call MLME_GET.macMinLIFSPeriod();
else
- m_BLELen += call MLME_GET.macMinSIFSPeriod();
- m_BLELen = m_BLELen + call MLME_GET.macBattLifeExtPeriods() * 20;
+ m_battLifeExtDuration += call MLME_GET.macMinSIFSPeriod();
+ m_battLifeExtDuration = m_battLifeExtDuration + call MLME_GET.macBattLifeExtPeriods() * 20;
} else
- m_BLELen = 0;
- m_broadcastPending = mhr[MHR_INDEX_FC1] & FC1_FRAME_PENDING ? TRUE : FALSE;
+ m_battLifeExtDuration = 0;
+
+ m_framePendingBit = mhr[MHR_INDEX_FC1] & FC1_FRAME_PENDING ? TRUE : FALSE;
coordBeaconOrder = (payload[0] & 0x0F);
m_dt = m_beaconInterval = ((uint32_t) 1 << coordBeaconOrder) * (uint32_t) IEEE154_aBaseSuperframeDuration;
- if (m_stopTracking){
+
+ if (m_stopTracking) {
m_tracking = FALSE;
- call Debug.log(DEBUG_LEVEL_INFO,16, 0, 0, 0);
- if (m_updatePending) // there is already a new request pending...
+ dbg_serial("BeaconSynchronizeP", "Stop tracking.\n");
+ if (m_updatePending) // there is already a new request ...
call Token.request();
call Token.release();
} else {
- call Debug.log(DEBUG_LEVEL_INFO,17, 0, 0, 0);
- call TokenToCap.transfer(); // borrow Token to CAP/CFP module, we'll get it back afterwards
+ dbg_serial("BeaconSynchronizeP", "Handing over to CAP.\n");
+ call TokenToCap.transfer();
}
if (pendAddrSpec & PENDING_ADDRESS_SHORT_MASK)
beaconPayload += (pendAddrSpec & PENDING_ADDRESS_SHORT_MASK) * 2;
if (pendAddrSpec & PENDING_ADDRESS_EXT_MASK)
beaconPayload += ((pendAddrSpec & PENDING_ADDRESS_EXT_MASK) >> 4) * 8;
+
// check for pending data (once we signal MLME_BEACON_NOTIFY we cannot
- // touch the frame anymore)
+ // touch this frame anymore!)
if (autoRequest)
- pendingAddrMode = call BeaconFrame.isLocalAddrPending(m_beaconBufferPtr);
- if (pendingAddrMode != ADDR_MODE_NOT_PRESENT){
+ pendingAddrMode = call BeaconFrame.isLocalAddrPending(m_beaconPtr);
+ if (pendingAddrMode != ADDR_MODE_NOT_PRESENT) {
// the coord has pending data
uint8_t CoordAddrMode;
uint16_t CoordPANId;
CoordPANId = *((nxle_uint16_t*) &(mhr[MHR_INDEX_ADDRESS]));
call DataRequest.poll(CoordAddrMode, CoordPANId, CoordAddress, SrcAddrMode);
}
+
// Beacon Tracking: update state
- call Debug.log(DEBUG_LEVEL_INFO, 18, m_lastBeaconRxTime, m_beaconInterval, 0);
m_numBeaconsLost = 0;
// TODO: check PAN ID conflict here?
if (!autoRequest || beaconPayloadSize)
- m_beaconBufferPtr = signal MLME_BEACON_NOTIFY.indication(m_beaconBufferPtr);
- m_beaconSwapBufferReady = TRUE;
+ m_beaconPtr = signal MLME_BEACON_NOTIFY.indication(m_beaconPtr);
+ m_bufferBusy = FALSE;
}
+ dbg_serial_flush();
}
- async command bool IsTrackingBeacons.getNow(){ return m_tracking;}
-
- default event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame){return frame;}
+ command error_t TrackSingleBeacon.start()
+ {
+ // Track a single beacon now
+ if (!m_tracking && !m_updatePending && !call Token.isOwner()) {
+ // find a single beacon now (treat this like a user request)
+ m_updateLogicalChannel = call MLME_GET.phyCurrentChannel();
+ m_updateTrackBeacon = FALSE;
+ m_stopTracking = TRUE;
+ m_updatePending = TRUE;
+ call Token.request();
+ }
+ return SUCCESS;
+ }
- default event void MLME_SYNC_LOSS.indication (
- ieee154_status_t lossReason,
- uint16_t panID,
- uint8_t logicalChannel,
- uint8_t channelPage,
- ieee154_security_t *security){}
+ command error_t TrackSingleBeacon.stop()
+ {
+ // will stop automatically after beacon was tracked/not found
+ return FAIL;
+ }
- event void DataRequest.pollDone(){}
-
- async command uint8_t* GtsField.getNow() { return m_gtsField; }
- async command uint32_t SfSlotDuration.getNow() { return m_sfSlotDuration; }
- async command uint8_t FinalCapSlot.getNow() { return m_finalCapSlot; }
- async command uint32_t CapStart.getNow() { return m_lastBeaconRxTime; }
- async command ieee154_reftime_t* CapStartRefTime.getNow() { return &m_lastBeaconRxRefTime; }
- async command uint32_t CapLen.getNow() { return call SfSlotDuration.getNow() * (call FinalCapSlot.getNow() + 1);}
- async command uint32_t CapEnd.getNow()
+ /* ----------------------- SF Structure, etc. ----------------------- */
+
+ async command uint32_t IncomingSF.sfStartTime()
+ {
+ return m_lastBeaconRxTime;
+ }
+
+ async command uint16_t IncomingSF.sfSlotDuration()
+ {
+ return m_sfSlotDuration;
+ }
+
+ async command uint8_t IncomingSF.numCapSlots()
{
- return call CapStart.getNow() + call CapLen.getNow();
+ return m_numCapSlots;
}
- async command uint32_t CfpEnd.getNow()
+
+ async command uint8_t IncomingSF.numGtsSlots()
{
- return call CapStart.getNow() + call SfSlotDuration.getNow() * IEEE154_aNumSuperframeSlots;
+ return m_numGtsSlots;
}
- async command uint32_t CfpLen.getNow()
+
+ async command uint16_t IncomingSF.battLifeExtDuration()
{
- return call SfSlotDuration.getNow() * (15 - call FinalCapSlot.getNow());
+ return m_battLifeExtDuration;
}
- async command uint32_t BeaconInterval.getNow()
+
+ async command const uint8_t* IncomingSF.gtsFields()
{
- return m_beaconInterval;
+ return m_gtsField;
}
- async command uint8_t NumGtsSlots.getNow() { return m_numGtsSlots; }
- async command bool IsBLEActive.getNow(){ return m_BLELen>0;}
- async command uint16_t BLELen.getNow(){ return m_BLELen;}
- async command bool IsRxBroadcastPending.getNow() { return m_broadcastPending; }
+
+ async command uint16_t IncomingSF.guardTime()
+ {
+ return IEEE154_MAX_BEACON_JITTER(m_beaconOrder) + IEEE154_RADIO_RX_DELAY;
+ }
+
+ async command const ieee154_timestamp_t* IncomingSF.sfStartTimeRef()
+ {
+ return &m_lastBeaconRxRefTime;
+ }
+
+ async command bool IncomingSF.isBroadcastPending()
+ {
+ return m_framePendingBit;
+ }
+
+ async command bool IsTrackingBeacons.getNow()
+ {
+ return m_tracking;
+ }
+
+ event void DataRequest.pollDone() {}
+
+ default event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame) {return frame;}
+ default event void MLME_SYNC_LOSS.indication (
+ ieee154_status_t lossReason,
+ uint16_t panID,
+ uint8_t logicalChannel,
+ uint8_t channelPage,
+ ieee154_security_t *security) {}
event message_t* CoordRealignmentRx.received(message_t* frame)
{
panID, // PANId
payload[5], // LogicalChannel,
call Frame.getPayloadLength(frame) == 9 ? payload[8] : call MLME_GET.phyCurrentPage(),
- NULL
- );
+ NULL);
return frame;
}
}