* 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
{
interface Timer<TSymbolIEEE802154> as IndirectTxWaitTimer;
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();
// m_transactionTime += call MLME_GET.macMinLIFSPeriod();
// else
// m_transactionTime += call MLME_GET.macMinSIFSPeriod();
- m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
m_currentFrame = frame;
}
// 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 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 RadioToken.request(); // we want it back afterwards ...
+ m_lock = FALSE; // unlock
call RadioToken.release();
return;
} else
}
// 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();
}
}
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) {
+ 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()
{
atomic {
task void startIndirectTxTimerTask()
{
- call IndirectTxWaitTimer.startOneShot(m_macMaxFrameTotalWaitTime);
+ call IndirectTxWaitTimer.startOneShot(call MLME_GET.macMaxFrameTotalWaitTime());
}
async event void UnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame,
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(); }
}