📄 dispatchunslottedcsmap.nc
字号:
// 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
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
next = SWITCH_OFF;
}
// Check 3: is there a frame ready to transmit?
else if (m_currentFrame != NULL) {
next = tryTransmit();
}
// Check 4: should we be in receive mode?
else if (call IsRxEnableActive.getNow() || m_macRxOnWhenIdle) {
next = tryReceive();
if (next == DO_NOTHING) {
// 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 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 RadioToken.release();
return;
}
}
// if there is nothing to do, then we must clear the lock
if (next == DO_NOTHING)
m_lock = FALSE;
} // atomic
// put next state in operation (possibly keeping the lock)
switch (next)
{
case SWITCH_OFF: ASSERT(call RadioOff.off() == SUCCESS); break;
case WAIT_FOR_RXDONE: break;
case WAIT_FOR_TXDONE: break;
case DO_NOTHING: break;
}
}
next_state_t tryTransmit()
{
// tries to transmit m_currentFrame
next_state_t next;
if (!call RadioOff.isOff())
next = SWITCH_OFF;
else {
error_t res;
res = call UnslottedCsmaCa.transmit(m_currentFrame, &m_csma);
dbg("DispatchUnslottedCsmaP", "UnslottedCsmaCa.transmit() -> %lu\n", (uint32_t) res);
next = WAIT_FOR_TXDONE; // this will NOT clear the lock
}
return next;
}
next_state_t tryReceive()
{
next_state_t next;
if (call RadioRx.isReceiving())
next = DO_NOTHING;
else if (!call RadioOff.isOff())
next = SWITCH_OFF;
else {
call RadioRx.enableRx(0, 0);
next = WAIT_FOR_RXDONE;
}
return next;
}
next_state_t trySwitchOff()
{
next_state_t next;
if (call RadioOff.isOff())
next = DO_NOTHING;
else
next = SWITCH_OFF;
return next;
}
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 {
if (m_indirectTxPending) {
m_indirectTxPending = FALSE;
post signalTxDoneTask();
}
}
}
task void startIndirectTxTimerTask()
{
call IndirectTxWaitTimer.startOneShot(call MLME_GET.macMaxFrameTotalWaitTime());
}
async event void UnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame,
ieee154_csma_t *csma, bool ackPendingFlag, error_t result)
{
bool done = TRUE;
dbg("DispatchUnslottedCsmaP", "UnslottedCsmaCa.transmitDone() -> %lu\n", (uint32_t) result);
m_resume = FALSE;
switch (result)
{
case SUCCESS:
// frame was successfully transmitted, if ACK was requested
// then a matching ACK was successfully received as well
m_txStatus = IEEE154_SUCCESS;
if (frame->payload[0] == CMD_FRAME_DATA_REQUEST &&
((frame->header->mhr[MHR_INDEX_FC1]) & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD) {
// this was a data request frame
m_txStatus = IEEE154_NO_DATA; // pessimistic
if (ackPendingFlag) {
// the coordinator has data for us; switch to Rx
// to complete the indirect transmission
m_indirectTxPending = TRUE;
m_lastFrame = m_currentFrame;
m_currentFrame = NULL;
ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS);
return;
}
}
break;
case FAIL:
// The CSMA-CA algorithm failed: the frame was not transmitted,
// because channel was never idle
m_txStatus = IEEE154_CHANNEL_ACCESS_FAILURE;
break;
case ENOACK:
// frame was transmitted, but we didn't receive an ACK (although
// we requested an one). note: coordinator never retransmits an
// indirect transmission (see above)
if (m_macMaxFrameRetries > 0) {
// retransmit: reinitialize CSMA-CA parameters
done = FALSE;
m_csma.NB = 0;
m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs;
m_csma.macMaxBE = m_macMaxBE;
m_csma.BE = m_BE;
m_macMaxFrameRetries -= 1;
} else
m_txStatus = IEEE154_NO_ACK;
break;
default:
ASSERT(0);
break;
}
if (done) {
m_lastFrame = m_currentFrame;
m_currentFrame = NULL;
post signalTxDoneTask();
}
m_lock = FALSE;
updateState();
}
task void signalTxDoneTask()
{
ieee154_txframe_t *lastFrame = m_lastFrame;
ieee154_status_t status = m_txStatus;
m_indirectTxPending = FALSE;
m_lastFrame = NULL; // only now the next transmission can begin
if (lastFrame) {
dbg("DispatchUnslottedCsmaP", "Transmit done, DSN: %lu, result: 0x%lx\n",
(uint32_t) MHR(lastFrame)[MHR_INDEX_SEQNO], (uint32_t) status);
signal FrameTx.transmitDone(lastFrame, status);
}
updateState();
}
event message_t* RadioRx.received(message_t* frame, const ieee154_timestamp_t *timestamp)
{
// received a frame -> find out frame type and
// signal it to responsible client component
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;
call IndirectTxWaitTimer.stop();
// TODO: check!
//if (frame->payloadLen)
// is this frame from our coordinator? hmm... we cannot say
// with certainty, because we might only know either the
// coordinator extended or short address (and the frame could
// have been sent with the other addressing mode) ??
m_txStatus = IEEE154_SUCCESS;
frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame);
signal IndirectTxWaitTimer.fired();
return frameBuf;
} else
return signal FrameRx.received[frameType](frame);
}
}
task void wasRxEnabledTask()
{
signal WasRxEnabled.notify(TRUE);
}
default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status) {}
default event message_t* FrameRx.received[uint8_t client](message_t* data) {return data;}
default async command bool IsRxEnableActive.getNow() {return FALSE;}
default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame) {return msg;}
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(); }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -