* not part of the MAC implementation but of the chip-specific radio driver.
*/
-#if IEEE154_BEACON_ENABLED_PAN
-#error "The IEEE154_BEACON_ENABLED_PAN macro MUST NOT be set when using this component!"
-#endif
-
module DispatchUnslottedCsmaP
{
provides
uses
{
interface Timer<TSymbolIEEE802154> as IndirectTxWaitTimer;
- interface Resource as Token;
- interface GetNow<bool> as IsTokenRequested;
+ interface TransferableResource as RadioToken;
+ interface ResourceRequested as RadioTokenRequested;
+ interface GetNow<token_requested_t> as IsRadioTokenRequested;
interface GetNow<bool> as IsRxEnableActive;
interface Set<ieee154_macSuperframeOrder_t> as SetMacSuperframeOrder;
interface Set<ieee154_macPanCoordinator_t> as SetMacPanCoordinator;
interface Get<ieee154_txframe_t*> as GetIndirectTxFrame;
interface Notify<bool> as RxEnableStateChange;
+ interface Notify<const void*> as PIBUpdateMacRxOnWhenIdle;
interface FrameUtility;
interface UnslottedCsmaCa;
interface RadioRx;
norace bool m_resume;
norace ieee154_txframe_t *m_currentFrame;
norace ieee154_txframe_t *m_lastFrame;
+ norace ieee154_macRxOnWhenIdle_t m_macRxOnWhenIdle;
/* variables for the unslotted CSMA-CA */
norace ieee154_csma_t m_csma;
norace ieee154_status_t m_txStatus;
norace uint32_t m_transactionTime;
norace bool m_indirectTxPending = FALSE;
- norace ieee154_macMaxFrameTotalWaitTime_t m_macMaxFrameTotalWaitTime;
/* function / task prototypes */
- next_state_t tryReceive(bool startIndirectTxTimer);
+ next_state_t tryReceive();
next_state_t tryTransmit();
next_state_t trySwitchOff();
void backupCurrentFrame();
call MLME_SET.macPANId(panID);
call MLME_SET.phyCurrentChannel(logicalChannel);
call MLME_SET.macBeaconOrder(beaconOrder);
- call SetMacSuperframeOrder.set(superframeOrder);
call SetMacPanCoordinator.set(panCoordinator);
//TODO: check realignment
post signalStartConfirmTask();
status = IEEE154_SUCCESS;
}
+ dbg_serial("DispatchUnslottedCsmaP", "MLME_START.request -> result: %lu\n", (uint32_t) status);
return status;
}
return IEEE154_TRANSACTION_OVERFLOW;
} else {
setCurrentFrame(frame);
- call Token.request();
+ if (call RadioToken.isOwner())
+ updateState();
+ else
+ call RadioToken.request();
return IEEE154_SUCCESS;
}
}
- event void Token.granted()
+ event void RadioToken.granted()
{
updateState();
}
// m_transactionTime += call MLME_GET.macMinLIFSPeriod();
// else
// m_transactionTime += call MLME_GET.macMinSIFSPeriod();
- m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
m_currentFrame = frame;
}
// long atomics are bad... but in this block, once the
// current state has been determined only one branch will
// be taken (there are no loops)
- if (m_lock || !call Token.isOwner())
+ if (m_lock || !call RadioToken.isOwner())
return;
m_lock = TRUE; // lock
// Check 1: was an indirect transmission successfully started
// and are we now waiting for a frame from the coordinator?
if (m_indirectTxPending) {
- next = tryReceive(TRUE);
+ next = tryReceive();
}
// Check 2: is some other operation (like MLME-SCAN or MLME-RESET) pending?
- else if (call IsTokenRequested.getNow()) {
+ else if (call IsRadioTokenRequested.getNow()) {
if (call RadioOff.isOff()) {
// nothing more to do... just release the Token
- m_lock = FALSE; // unlock
dbg_serial("DispatchUnslottedCsmaP", "Token requested: releasing it.\n");
- call Token.release();
+ call RadioToken.request(); // we want it back afterwards ...
+ m_lock = FALSE; // unlock
+ call RadioToken.release();
return;
} else
next = SWITCH_OFF;
}
// Check 4: should we be in receive mode?
- else if (call IsRxEnableActive.getNow()) {
- next = tryReceive(FALSE);
+ else if (call IsRxEnableActive.getNow() || m_macRxOnWhenIdle) {
+ next = tryReceive();
if (next == DO_NOTHING) {
- // this means there is an active MLME_RX_ENABLE.request
- // and the radio was just switched to Rx mode - signal
- // a notify event to inform the next higher layer
+ // if there was an active MLME_RX_ENABLE.request then we'll
+ // inform the next higher layer that radio is now in Rx mode
post wasRxEnabledTask();
}
}
- // Check 6: just make sure the radio is switched off
+ // Check 5: just make sure the radio is switched off
else {
next = trySwitchOff();
if (next == DO_NOTHING) {
// nothing more to do... just release the Token
m_lock = FALSE; // unlock
dbg_serial("DispatchUnslottedCsmaP", "Releasing token\n");
- call Token.release();
+ call RadioToken.release();
return;
}
}
return next;
}
- next_state_t tryReceive(bool startIndirectTxTimer)
+ next_state_t tryReceive()
{
next_state_t next;
if (call RadioRx.isReceiving())
next = SWITCH_OFF;
else {
call RadioRx.enableRx(0, 0);
- if (startIndirectTxTimer)
- post startIndirectTxTimerTask();
next = WAIT_FOR_RXDONE;
}
return next;
return next;
}
- async event void RadioOff.offDone() { m_lock = FALSE; updateState();}
- async event void RadioRx.enableRxDone() { m_lock = FALSE; updateState();}
- event void RxEnableStateChange.notify(bool whatever) { updateState();}
+ async event void RadioOff.offDone()
+ {
+ m_lock = FALSE;
+ updateState();
+ }
+
+ async event void RadioRx.enableRxDone()
+ {
+ if (m_indirectTxPending) // indirect transmission, now waiting for data
+ post startIndirectTxTimerTask();
+ m_lock = FALSE;
+ updateState();
+ }
+
+ event void RxEnableStateChange.notify(bool whatever)
+ {
+ if (!call RadioToken.isOwner())
+ call RadioToken.request();
+ else
+ updateState();
+ }
+
+ event void PIBUpdateMacRxOnWhenIdle.notify( const void* val )
+ {
+ atomic m_macRxOnWhenIdle = *((ieee154_macRxOnWhenIdle_t*) val);
+ signal RxEnableStateChange.notify(TRUE);
+ }
event void IndirectTxWaitTimer.fired()
{
task void startIndirectTxTimerTask()
{
- call IndirectTxWaitTimer.startOneShot(m_macMaxFrameTotalWaitTime);
+ call IndirectTxWaitTimer.startOneShot(call MLME_GET.macMaxFrameTotalWaitTime());
}
async event void UnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame,
uint8_t *payload = (uint8_t *) frame->data;
uint8_t *mhr = MHR(frame);
uint8_t frameType = mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK;
+
if (frameType == FC1_FRAMETYPE_CMD)
frameType += payload[0];
+ dbg("DispatchUnslottedCsmaP", "Received frame, DSN: %lu, type: 0x%lu\n",
+ (uint32_t) mhr[MHR_INDEX_SEQNO], (uint32_t) frameType);
atomic {
if (m_indirectTxPending) {
message_t* frameBuf;
command error_t WasRxEnabled.enable() {return FAIL;}
command error_t WasRxEnabled.disable() {return FAIL;}
default event void MLME_START.confirm(ieee154_status_t status) {}
+ async event void RadioToken.transferredFrom(uint8_t fromClientID) {ASSERT(0);}
+ async event void RadioTokenRequested.requested(){ updateState(); }
+ async event void RadioTokenRequested.immediateRequested(){ updateState(); }
}