interface Init as Reset;
interface MLME_START;
interface WriteBeaconField as SuperframeSpecWrite;
- interface Get<bool> as IsSendingBeacons;
+ interface GetNow<bool> as IsSendingBeacons;
interface GetNow<uint32_t> as CapStart;
interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
interface GetNow<uint32_t> as CapLen;
interface Alarm<TSymbolIEEE802154,uint32_t> as BeaconTxAlarm;
interface Timer<TSymbolIEEE802154> as BeaconPayloadUpdateTimer;
interface RadioOff;
- interface Get<bool> as IsBeaconEnabledPAN;
+ interface GetNow<bool> as IsBeaconEnabledPAN;
interface RadioTx as BeaconTx;
interface MLME_GET;
interface MLME_SET;
interface Resource as Token;
+ interface ResourceTransferred as TokenTransferred;
interface ResourceTransfer as TokenToBroadcast;
+ interface GetNow<bool> as IsTokenRequested;
interface FrameTx as RealignmentBeaconEnabledTx;
interface FrameTx as RealignmentNonBeaconEnabledTx;
interface FrameRx as BeaconRequestRx;
uint16_t m_updatePANId;
uint8_t m_updateLogicalChannel;
uint32_t m_updateStartTime;
- uint8_t m_updateBeaconOrder;
+ norace uint8_t m_updateBeaconOrder;
uint8_t m_updateSuperframeOrder;
bool m_updatePANCoordinator;
bool m_updateBatteryLifeExtension;
status = IEEE154_INVALID_PARAMETER;
else if (m_requests & (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF))
status = IEEE154_TRANSACTION_OVERFLOW;
- else if ((call IsBeaconEnabledPAN.get() && beaconOrder > 14) ||
- (!call IsBeaconEnabledPAN.get() && beaconOrder < 15))
+ else if ((call IsBeaconEnabledPAN.getNow() && beaconOrder == 15) ||
+ (!call IsBeaconEnabledPAN.getNow() && beaconOrder < 15))
status = IEEE154_INVALID_PARAMETER;
else {
// new configuration *will* be put in operation
status = IEEE154_SUCCESS;
if (panCoordinator)
startTime = 0; // start immediately
- call Debug.log(LEVEL_INFO, StartP_REQUEST, logicalChannel, beaconOrder, superframeOrder);
+ call Debug.log(DEBUG_LEVEL_INFO, 0, logicalChannel, beaconOrder, superframeOrder);
if (beaconOrder == 15){
// beaconless PAN
superframeOrder = 15;
m_requests = (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF); // lock
if (coordRealignment)
m_requests |= REQUEST_REALIGNMENT;
- if (!call IsSendingBeacons.get())
- call Token.request();
+ if (m_beaconOrder == 15) // only request token if we're not already transmitting beacons
+ call Token.request(); // otherwise we'll get it eventually and update the superframe then
}
return status;
}
*((nxle_uint16_t*) &realignmentFrame->payload[6]) = 0xFFFF;
realignmentFrame->payloadLen = 8;
- if (call IsSendingBeacons.get()){
+ if (m_beaconOrder < 15){
// we're already transmitting beacons; the realignment frame
// must be sent (broadcast) after the next beacon
if (call RealignmentBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS){
event void Token.granted()
{
call Debug.flush();
- call Debug.log(LEVEL_INFO, StartP_GOT_RESOURCE, m_lastBeaconTxTime, m_beaconInterval, m_requests);
+ call Debug.log(DEBUG_LEVEL_INFO, 1, m_lastBeaconTxTime, m_beaconInterval, m_requests);
if (m_requests & REQUEST_REALIGNMENT_DONE_PENDING){
// unlikely to occur: we have not yet received a done()
// event after sending out a realignment frame
if (m_requests & REQUEST_UPDATE_SF){
m_requests &= ~REQUEST_UPDATE_SF;
continueStartRequest();
- call Debug.log(LEVEL_INFO, StartP_UPDATE_STATE, 0, 0, 0);
+ call Debug.log(DEBUG_LEVEL_INFO, 2, 0, 0, 0);
}
if (call RadioOff.isOff())
prepareNextBeaconTransmission();
call RadioOff.off();
}
+ 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
+ post grantedTask();
+ }
+
async event void RadioOff.offDone()
{
prepareNextBeaconTransmission();
if (m_txState == S_TX_LOCKED){
// have not had time to finish processing the last sent beacon
post grantedTask();
- call Debug.log(LEVEL_CRITICAL, StartP_OWNER_TOO_FAST, 0, 0, 0);
+ call Debug.log(DEBUG_LEVEL_IMPORTANT, 3, 0, 0, 0);
return;
- } else if (m_beaconOrder > 14){
+ } else if (m_beaconOrder == 15){
call Token.release();
} else {
atomic {
// the usual case: next beacon tx time = last time + BI
m_dt = m_beaconInterval;
}
- while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)){ // missed sending a beacon
- call Debug.log(LEVEL_INFO, StartP_SKIPPED_BEACON, m_lastBeaconTxTime, m_dt, 0);
+ while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)){ // skipped a beacon
+ call Debug.log(DEBUG_LEVEL_IMPORTANT, 4, m_lastBeaconTxTime, m_dt, 0);
m_dt += m_beaconInterval;
}
if (m_dt < IEEE154_RADIO_TX_PREPARE_DELAY)
else
m_beaconFrame.header->mhr[MHR_INDEX_FC1] &= ~FC1_FRAME_PENDING;
m_beaconFrame.header->mhr[MHR_INDEX_SEQNO] = m_bsn; // update beacon seqno
- call Debug.log(LEVEL_INFO, StartP_PREPARE_TX, 0, m_lastBeaconTxTime, 0);
+ call Debug.log(DEBUG_LEVEL_INFO, 5, 0, m_lastBeaconTxTime, 0);
call BeaconTx.load(&m_beaconFrame);
break;
case S_TX_LOCKED:
- call Debug.log(LEVEL_INFO, StartP_TRANSMIT, m_lastBeaconTxTime, m_dt, ((uint32_t)m_lastBeaconTxRefTime));
- call BeaconTx.transmit(&m_lastBeaconTxRefTime, m_dt, 0, FALSE);
+ call Debug.log(DEBUG_LEVEL_INFO, 6, m_lastBeaconTxTime, m_dt, 0);
+ call BeaconTx.transmit(&m_lastBeaconTxRefTime, m_dt);
break;
}
}
async event void BeaconTx.loadDone()
{
atomic {
- call Debug.log(LEVEL_INFO, StartP_PREPARE_TXDONE, 0, m_lastBeaconTxTime, 0);
+ call Debug.log(DEBUG_LEVEL_INFO, 7, 0, m_lastBeaconTxTime, 0);
if (m_txOneBeaconImmediately){
m_txOneBeaconImmediately = FALSE;
- call BeaconTx.transmit(0, 0, 0, FALSE); // now!
+ call BeaconTx.transmit(NULL, 0); // now!
} else
call BeaconTxAlarm.startAt(m_lastBeaconTxTime, m_dt - IEEE154_RADIO_TX_SEND_DELAY);
}
}
-
- async event void BeaconTx.transmitDone(ieee154_txframe_t *frame,
- ieee154_reftime_t *referenceTime, bool pendingFlag, error_t error)
+ async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime)
{
// Coord CAP has just started...
uint8_t gtsFieldLength;
// Sec. 7.5.1.1: "start of slot 0 is defined as the point at which
// the first symbol of the beacon PPDU is transmitted"
- call Debug.log(LEVEL_INFO, StartP_BEACON_TRANSMITTED, frame->metadata->timestamp, m_lastBeaconTxTime, m_dt);
+ call Debug.log(DEBUG_LEVEL_INFO, 8, frame->metadata->timestamp, m_lastBeaconTxTime, m_dt);
m_lastBeaconTxTime = frame->metadata->timestamp;
- memcpy(&m_lastBeaconTxRefTime, referenceTime, sizeof(ieee154_reftime_t));
+ memcpy(&m_lastBeaconTxRefTime, txTime, sizeof(ieee154_reftime_t));
m_numGtsSlots = (frame->payload[2] & 0x07);
gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
m_finalCAPSlot = (frame->payload[1] & 0x0F);
if (frame->payload[1] & 0x10){
// BLE is active; calculate the time offset from slot0
m_BLELen = IEEE154_SHR_DURATION +
- (frame->headerLen + frame->payloadLen) * IEEE154_SYMBOLS_PER_OCTET;
- if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
+ (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET;
+ if (frame->headerLen + frame->payloadLen + 2 > IEEE154_aMaxSIFSFrameSize)
m_BLELen += IEEE154_MIN_LIFS_PERIOD;
else
m_BLELen += IEEE154_MIN_SIFS_PERIOD;
- m_BLELen += m_battLifeExtPeriods;
+ m_BLELen = m_BLELen + m_battLifeExtPeriods * 20;
} else
m_BLELen = 0;
- call Token.request(); // register another request, before ...
- call TokenToBroadcast.transfer(); // ... we let Broadcast module take over
+ call TokenToBroadcast.transfer(); // borrow Token to Broadcast/CAP/CFP module, we'll get it back afterwards
post txDoneTask();
}
atomic {
if (m_txState == S_TX_LOCKED)
{
- call Debug.log(LEVEL_INFO, StartP_BEACON_UPDATE, 0, 0, m_txState);
+ call Debug.log(DEBUG_LEVEL_IMPORTANT, 10, 0, 0, m_txState);
return; // too late !
}
if (m_payloadState & MODIFIED_PENDING_ADDR_FIELD){
atomic {
if (m_txState == S_TX_LOCKED)
{
- call Debug.log(LEVEL_INFO, StartP_BEACON_UPDATE_2, 0, 0, m_txState);
+ call Debug.log(DEBUG_LEVEL_INFO, 11, 0, 0, m_txState);
return; // too late !
}
if (m_payloadState & MODIFIED_BEACON_PAYLOAD){
event message_t* BeaconRequestRx.received(message_t* frame)
{
- if (!call IsSendingBeacons.get()){
+ if (m_beaconOrder == 15){
// transmit the beacon frame using unslotted CSMA-CA
// TODO
}
signal MLME_START.confirm(SUCCESS);
}
- command bool IsSendingBeacons.get(){ return m_beaconOrder < 15;}
+ async command bool IsSendingBeacons.getNow()
+ {
+ return (m_beaconOrder < 15) || ((m_requests & REQUEST_CONFIRM_PENDING) && m_updateBeaconOrder < 15);
+ }
async command uint32_t BeaconInterval.getNow() { return m_beaconInterval; }
async command uint32_t CapStart.getNow() { return m_lastBeaconTxTime; }
async command uint32_t SfSlotDuration.getNow() { return m_sfSlotDuration; }
async command uint8_t FinalCapSlot.getNow() { return m_finalCAPSlot; }
async command uint8_t NumGtsSlots.getNow() { return m_numGtsSlots; }
+ async event void BeaconTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
+ bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result){}
+ async event void BeaconTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
+ bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result){}
+
default event void MLME_START.confirm (
ieee154_status_t status