interface MLME_SYNC;
interface MLME_BEACON_NOTIFY;
interface MLME_SYNC_LOSS;
- interface Get<bool> as IsTrackingBeacons;
+ 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 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 Get<bool> as IsBeaconEnabledPAN;
+ interface GetNow<bool> as IsBeaconEnabledPAN;
interface DataRequest;
interface FrameRx as CoordRealignmentRx;
interface Resource as Token;
+ interface GetNow<bool> as IsTokenRequested;
+ interface ResourceTransferred as TokenTransferred;
interface ResourceTransfer as TokenToCap;
interface TimeCalc;
interface IEEE154Frame as Frame;
uint8_t m_updateLogicalChannel;
bool m_updateTrackBeacon;
bool m_stopTracking = FALSE;
+ bool m_internalRequest = FALSE;
norace uint8_t m_numBeaconsLost;
uint8_t m_coordAddress[8];
norace uint16_t m_BLELen;
norace bool m_broadcastPending;
uint8_t m_gtsField[1+1+3*7];
+
task void processBeaconTask();
+ void getNextBeacon();
+ task void signalGrantedTask();
command error_t Reset.init()
{
currentChannelBit <<= logicalChannel;
if (!(currentChannelBit & supportedChannels) || (call MLME_GET.macPANId() == 0xFFFF) ||
- (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !call IsBeaconEnabledPAN.get())
+ (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !call IsBeaconEnabledPAN.getNow())
return IEEE154_INVALID_PARAMETER;
call Debug.log(LEVEL_INFO,SyncP_REQUEST, logicalChannel, channelPage, trackBeacon);
m_stopTracking = FALSE;
m_updateLogicalChannel = logicalChannel;
m_updateTrackBeacon = trackBeacon;
- atomic m_updatePending = TRUE;
+ m_internalRequest = FALSE;
+ m_updatePending = TRUE;
call Debug.log(LEVEL_INFO,SyncP_RESOURCE_REQUEST, 0, 0, 0);
- call Token.request();
+ 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 )
+ {
+ if (!m_tracking && !m_updatePending){
+ // 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();
+ }
+ }
+
event void Token.granted()
{
- bool missed = FALSE;
call Debug.log(LEVEL_INFO,SyncP_GOT_RESOURCE, m_lastBeaconRxTime+m_beaconInterval,
m_beaconInterval, (m_updatePending<<1)+m_tracking);
if (m_updatePending){
m_numBeaconsLost = IEEE154_aMaxLostBeacons; // will be reset when beacon is received
call Debug.log(LEVEL_INFO,SyncP_UPDATING, call MLME_GET.macCoordShortAddress(),
call MLME_GET.macPANId(), m_updateLogicalChannel);
- } else {
+ }
+ getNextBeacon();
+ call Debug.flush();
+ }
+
+ void getNextBeacon()
+ {
+ bool missed = FALSE;
+ if (m_state != S_FIRST_SCAN){
+ // we have received at least one previous beacon
m_state = S_PREPARE;
if (!m_tracking){
+ // nothing to do, just give up the token
call Debug.log(LEVEL_INFO,SyncP_RELEASE_RESOURCE, 0, 0, 0);
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!
+ missed = TRUE;
call Debug.log(LEVEL_INFO,SyncP_BEACON_MISSED_1, m_lastBeaconRxTime, m_dt, missed);
m_dt += m_beaconInterval;
m_numBeaconsLost++;
- missed = TRUE;
}
if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons){
post processBeaconTask();
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();
+ }
+
+ task void signalGrantedTask()
+ {
+ signal Token.granted();
+ }
+
async event void TrackAlarm.fired()
{
- call Debug.log(LEVEL_IMPORTANT,SyncP_SWITCHOFF, 0,0,0);
+ call Debug.log(LEVEL_IMPORTANT,SyncP_TRACK_ALARM, m_state,m_lastBeaconRxTime,m_dt);
atomic {
switch (m_state)
{
call BeaconRx.prepare();
break;
case S_RADIO_OFF:
- call Debug.log(LEVEL_INFO, SyncP_SWITCHOFF, 0, 0,0);
call RadioOff.off();
break;
}
async event void BeaconRx.prepareDone()
{
+ error_t result;
if (m_state == S_FIRST_SCAN){
m_state = S_RADIO_OFF;
atomic {
}
} else {
m_state = S_RADIO_OFF;
- call BeaconRx.receive(&m_lastBeaconRxRefTime, m_dt-RX_LAG);
- call Debug.log(LEVEL_IMPORTANT,SyncP_RX_ON, call TrackAlarm.getNow(),m_lastBeaconRxTime+m_dt,RX_LAG);
+ result = call BeaconRx.receive(&m_lastBeaconRxRefTime, m_dt-RX_LAG);
+ call Debug.log(LEVEL_IMPORTANT,SyncP_RX_ON, m_lastBeaconRxTime, call TrackAlarm.getNow(), m_dt+RX_DURATION);
+ if (result != SUCCESS)
+ call Debug.log(LEVEL_IMPORTANT,SyncP_RADIO_BUSY, result, 0, 0);
call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt + RX_DURATION);
}
}
mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK,mhr[MHR_INDEX_SEQNO]);
if (!m_beaconSwapBufferReady || !call FrameUtility.isBeaconFromCoord(frame))
{
+ call Debug.log(LEVEL_IMPORTANT,SyncP_RX_GARBAGE, m_beaconSwapBufferReady, 0, 0);
return frame;
} else {
message_t *tmp = m_beaconBufferPtr;
task void processBeaconTask()
{
-
// valid beacon timestamp is pre-condition for slotted CSMA-CA
if (m_beaconSwapBufferReady || !call Frame.isTimestampValid(m_beaconBufferPtr)){
// missed a beacon!
+ m_sfSlotDuration = 0; // CAP len will be 0
m_numBeaconsLost++;
m_dt += m_beaconInterval;
call Debug.log(LEVEL_IMPORTANT, SyncP_BEACON_MISSED_3,m_numBeaconsLost,0,m_lastBeaconRxTime);
m_tracking = FALSE;
call Debug.log(LEVEL_IMPORTANT, SyncP_LOST_SYNC,0,0,0);
call Leds.led2Off();
- signal MLME_SYNC_LOSS.indication(
- IEEE154_BEACON_LOSS,
- call MLME_GET.macPANId(),
- call MLME_GET.phyCurrentChannel(),
- call MLME_GET.phyCurrentPage(),
- NULL // security
- );
+ if (m_internalRequest)
+ call TokenToCap.transfer();
+ else
+ signal MLME_SYNC_LOSS.indication(
+ IEEE154_BEACON_LOSS,
+ call MLME_GET.macPANId(),
+ call MLME_GET.phyCurrentChannel(),
+ call MLME_GET.phyCurrentPage(),
+ NULL // security
+ );
} else
call Token.request(); // make another request again (before giving the token up)
call Debug.log(LEVEL_INFO,SyncP_RELEASE_RESOURCE, 0, 0, 0);
call Debug.log(LEVEL_INFO, SyncP_BEACON_RX, m_lastBeaconRxTime, timestamp, mhr[2]);
m_numGtsSlots = (payload[2] & 7);
gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
- m_lastBeaconRxTime = timestamp + IEEE154_SYNC_SYMBOL_OFFSET - IEEE154_SYMBOLS_PER_OCTET - IEEE154_PREAMBLE_LENGTH;
+ m_lastBeaconRxTime = timestamp;
m_finalCapSlot = (payload[1] & 0x0F);
m_sfSlotDuration = (((uint32_t) 1) << ((payload[0] & 0xF0) >> 4)) * IEEE154_aBaseSlotDuration;
memcpy(m_gtsField, &payload[2], gtsFieldLength);
if (m_stopTracking){
m_tracking = FALSE;
call Debug.log(LEVEL_INFO,SyncP_RELEASE_RESOURCE, 0, 0, 0);
+ if (m_updatePending) // there is already a new request pending...
+ call Token.request();
call Token.release();
} else {
- error_t req = call Token.request();
- call Debug.log(LEVEL_INFO,SyncP_TRANSFER_RESOURCE, req, 0, 0);
- call TokenToCap.transfer();
+ call Debug.log(LEVEL_INFO,SyncP_TRANSFER_RESOURCE, 0, 0, 0);
+ call TokenToCap.transfer(); // borrow Token to CAP/CFP module, we'll get it back afterwards
}
if (pendAddrSpec & PENDING_ADDRESS_SHORT_MASK)
}
}
- command bool IsTrackingBeacons.get(){ return m_tracking;}
+ async command bool IsTrackingBeacons.getNow(){ return m_tracking;}
default event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame){return frame;}