From 67dbbfc4024fb129ad58b8b9cda7cf4a8509f60d Mon Sep 17 00:00:00 2001 From: pvanhorn Date: Tue, 8 Nov 2016 12:21:28 -0800 Subject: [PATCH] Fix scanning behavior. Change logic around otPlatRadioGetTransmitBuffer. (#942) * Fix scanning behavior with default channel. Change logic around otPlatRadioGetTransmitBuffer so that the buffer becomes the property of OT post call. The MAC will keep a pointer to the tx buffer and pass it into otPlatRadioTransmit. This change should make the notion of retrying the transmit operation with the same buffer more intuitive. --- examples/drivers/windows/otLwf/radio.c | 14 ++++++++------ examples/platforms/cc2538/radio.c | 20 +++++++++++--------- examples/platforms/posix/radio.c | 11 ++++++----- include/platform/radio.h | 11 ++++++++--- src/core/mac/mac.cpp | 16 ++++++++++------ src/core/mac/mac.hpp | 2 ++ src/diag/diag_process.cpp | 19 +++++++++++-------- src/diag/diag_process.hpp | 1 + tests/unit/test_diag.cpp | 3 ++- tests/unit/test_fuzz.cpp | 2 +- tests/unit/test_platform.cpp | 6 ++++-- 11 files changed, 64 insertions(+), 41 deletions(-) diff --git a/examples/drivers/windows/otLwf/radio.c b/examples/drivers/windows/otLwf/radio.c index 709e383fd..8fb575d44 100644 --- a/examples/drivers/windows/otLwf/radio.c +++ b/examples/drivers/windows/otLwf/radio.c @@ -476,12 +476,14 @@ otLwfRadioReceiveFrame( LogFuncExit(DRIVER_DATA_PATH); } -ThreadError otPlatRadioTransmit(_In_ otInstance *otCtx) +ThreadError otPlatRadioTransmit(_In_ otInstance *otCtx, _In_ RadioPacket *aPacket) { NT_ASSERT(otCtx); PMS_FILTER pFilter = otCtxToFilter(otCtx); ThreadError error = kThreadError_Busy; - + + UNREFERENCED_PARAMETER(aPacket); + LogFuncEntryMsg(DRIVER_DATA_PATH, "Filter: %p", pFilter); NT_ASSERT(pFilter->otPhyState == kStateReceive); @@ -576,19 +578,19 @@ otLwfRadioTransmitFrameDone( POT_NBL_CONTEXT SendNblContext = GetNBLContext(pFilter->SendNetBufferList); BOOLEAN FramePending = (SendNblContext->Flags & OT_NBL_FLAG_ACK_FRAME_PENDING) != 0 || pFilter->CountPendingRecvNBLs != 0; - otPlatRadioTransmitDone(pFilter->otCtx, FramePending, kThreadError_None); + otPlatRadioTransmitDone(pFilter->otCtx, &pFilter->otTransmitFrame, FramePending, kThreadError_None); } else if (STATUS_DEVICE_BUSY == pFilter->SendNetBufferList->Status) { - otPlatRadioTransmitDone(pFilter->otCtx, false, kThreadError_ChannelAccessFailure); + otPlatRadioTransmitDone(pFilter->otCtx, &pFilter->otTransmitFrame, false, kThreadError_ChannelAccessFailure); } else if (STATUS_TIMEOUT == pFilter->SendNetBufferList->Status) { - otPlatRadioTransmitDone(pFilter->otCtx, false, kThreadError_NoAck); + otPlatRadioTransmitDone(pFilter->otCtx, &pFilter->otTransmitFrame, false, kThreadError_NoAck); } else { - otPlatRadioTransmitDone(pFilter->otCtx, false, kThreadError_Abort); + otPlatRadioTransmitDone(pFilter->otCtx, &pFilter->otTransmitFrame, false, kThreadError_Abort); } LogFuncExit(DRIVER_DATA_PATH); diff --git a/examples/platforms/cc2538/radio.c b/examples/platforms/cc2538/radio.c index ee2c8ebbd..bec34e8d4 100644 --- a/examples/platforms/cc2538/radio.c +++ b/examples/platforms/cc2538/radio.c @@ -251,7 +251,7 @@ ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) return error; } -ThreadError otPlatRadioTransmit(otInstance *aInstance) +ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket) { ThreadError error = kThreadError_InvalidState; (void)aInstance; @@ -271,15 +271,15 @@ ThreadError otPlatRadioTransmit(otInstance *aInstance) HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_FLUSHTX; // frame length - HWREG(RFCORE_SFR_RFDATA) = sTransmitFrame.mLength; + HWREG(RFCORE_SFR_RFDATA) = aPacket->mLength; // frame data - for (i = 0; i < sTransmitFrame.mLength; i++) + for (i = 0; i < aPacket->mLength; i++) { - HWREG(RFCORE_SFR_RFDATA) = sTransmitFrame.mPsdu[i]; + HWREG(RFCORE_SFR_RFDATA) = aPacket->mPsdu[i]; } - setChannel(sTransmitFrame.mChannel); + setChannel(aPacket->mChannel); while ((HWREG(RFCORE_XREG_FSMSTAT1) & 1) == 0); @@ -406,12 +406,12 @@ void cc2538RadioProcess(otInstance *aInstance) if (otPlatDiagModeGet()) { - otPlatDiagRadioTransmitDone(aInstance, false, sTransmitError); + otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, false, sTransmitError); } else #endif { - otPlatRadioTransmitDone(aInstance, false, sTransmitError); + otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, sTransmitError); } } else if (sReceiveFrame.mLength == IEEE802154_ACK_LENGTH && @@ -424,12 +424,14 @@ void cc2538RadioProcess(otInstance *aInstance) if (otPlatDiagModeGet()) { - otPlatDiagRadioTransmitDone(aInstance, (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0, sTransmitError); + otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0, + sTransmitError); } else #endif { - otPlatRadioTransmitDone(aInstance, (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0, sTransmitError); + otPlatRadioTransmitDone(aInstance, &sTransmitFrame, (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0, + sTransmitError); } } } diff --git a/examples/platforms/posix/radio.c b/examples/platforms/posix/radio.c index 8007e6a3d..9d082dd11 100644 --- a/examples/platforms/posix/radio.c +++ b/examples/platforms/posix/radio.c @@ -427,10 +427,11 @@ ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) return error; } -ThreadError otPlatRadioTransmit(otInstance *aInstance) +ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket) { ThreadError error = kThreadError_InvalidState; (void)aInstance; + (void)aPacket; if (sState == kStateReceive) { @@ -489,12 +490,12 @@ void radioReceive(otInstance *aInstance) if (otPlatDiagModeGet()) { - otPlatDiagRadioTransmitDone(aInstance, isFramePending(sReceiveFrame.mPsdu), kThreadError_None); + otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, isFramePending(sReceiveFrame.mPsdu), kThreadError_None); } else #endif { - otPlatRadioTransmitDone(aInstance, isFramePending(sReceiveFrame.mPsdu), kThreadError_None); + otPlatRadioTransmitDone(aInstance, &sTransmitFrame, isFramePending(sReceiveFrame.mPsdu), kThreadError_None); } } else if ((sState == kStateReceive || sState == kStateTransmit) && @@ -520,12 +521,12 @@ void radioSendMessage(otInstance *aInstance) if (otPlatDiagModeGet()) { - otPlatDiagRadioTransmitDone(aInstance, false, kThreadError_None); + otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, false, kThreadError_None); } else #endif { - otPlatRadioTransmitDone(aInstance, false, kThreadError_None); + otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, kThreadError_None); } } } diff --git a/include/platform/radio.h b/include/platform/radio.h index 70ec3152a..50c215b7a 100644 --- a/include/platform/radio.h +++ b/include/platform/radio.h @@ -354,16 +354,18 @@ RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance); * 2. Transmits the psdu on the given channel and at the given transmit power. * * @param[in] aInstance The OpenThread instance structure. + * @param[in] aPacket A pointer to the packet that will be transmitted. * * @retval ::kThreadError_None Successfully transitioned to Transmit. * @retval ::kThreadError_InvalidState The radio was not in the Receive state. */ -ThreadError otPlatRadioTransmit(otInstance *aInstance); +ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket); /** * The radio driver calls this method to notify OpenThread that the transmission has completed. * * @param[in] aInstance The OpenThread instance structure. + * @param[in] aPacket A pointer to the packet that was transmitted. * @param[in] aFramePending TRUE if an ACK frame was received and the Frame Pending bit was set. * @param[in] aError ::kThreadError_None when the frame was transmitted, ::kThreadError_NoAck when the frame was * transmitted but no ACK was received, ::kThreadError_ChannelAccessFailure when the transmission @@ -371,7 +373,8 @@ ThreadError otPlatRadioTransmit(otInstance *aInstance); * aborted for other reasons. * */ -extern void otPlatRadioTransmitDone(otInstance *aInstance, bool aFramePending, ThreadError aError); +extern void otPlatRadioTransmitDone(otInstance *aInstance, RadioPacket *aPacket, bool aFramePending, + ThreadError aError); /** * Get the most recent RSSI measurement. @@ -413,6 +416,7 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable); * The radio driver calls this method to notify OpenThread diagnostics module that the transmission has completed. * * @param[in] aInstance The OpenThread instance structure. + * @param[in] aPacket A pointer to the packet that was transmitted. * @param[in] aFramePending TRUE if an ACK frame was received and the Frame Pending bit was set. * @param[in] aError ::kThreadError_None when the frame was transmitted, ::kThreadError_NoAck when the frame was * transmitted but no ACK was received, ::kThreadError_ChannelAccessFailure when the transmission @@ -420,7 +424,8 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable); * aborted for other reasons. * */ -extern void otPlatDiagRadioTransmitDone(otInstance *aInstance, bool aFramePending, ThreadError aError); +extern void otPlatDiagRadioTransmitDone(otInstance *aInstance, RadioPacket *aPacket, bool aFramePending, + ThreadError aError); /** * The radio driver calls this method to notify OpenThread diagnostics module of a received packet. diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index d32b02900..5d494f173 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -162,6 +162,7 @@ Mac::Mac(ThreadNetif &aThreadNetif): mPcapCallbackContext = NULL; otPlatRadioEnable(mNetif.GetInstance()); + mTxFrame = static_cast(otPlatRadioGetTransmitBuffer(mNetif.GetInstance())); } ThreadError Mac::ActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler, void *aContext) @@ -288,6 +289,7 @@ void Mac::EnergyScanDone(int8_t aEnergyScanMaxRssi) // and start the next transmission task if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel) { + otPlatRadioReceive(mNetif.GetInstance(), mChannel); mEnergyScanHandler(mScanContext, NULL); ScheduleNextTransmission(); ExitNow(); @@ -717,7 +719,7 @@ exit: void Mac::HandleBeginTransmit(void) { - Frame &sendFrame(*static_cast(otPlatRadioGetTransmitBuffer(mNetif.GetInstance()))); + Frame &sendFrame(*mTxFrame); ThreadError error = kThreadError_None; if (mCsmaAttempts == 0 && mTransmitAttempts == 0) @@ -761,7 +763,7 @@ void Mac::HandleBeginTransmit(void) error = otPlatRadioReceive(mNetif.GetInstance(), sendFrame.GetChannel()); assert(error == kThreadError_None); - error = otPlatRadioTransmit(mNetif.GetInstance()); + error = otPlatRadioTransmit(mNetif.GetInstance(), static_cast(&sendFrame)); assert(error == kThreadError_None); if (sendFrame.GetAckRequest() && !(otPlatRadioGetCaps(mNetif.GetInstance()) & kRadioCapsAckTimeout)) @@ -784,9 +786,11 @@ exit: } } -extern "C" void otPlatRadioTransmitDone(otInstance *aInstance, bool aRxPending, ThreadError aError) +extern "C" void otPlatRadioTransmitDone(otInstance *aInstance, RadioPacket *aPacket, bool aRxPending, + ThreadError aError) { otLogFuncEntryMsg("%!otError!, aRxPending=%u", aError, aRxPending ? 1 : 0); + (void)aPacket; aInstance->mThreadNetif.GetMac().TransmitDoneTask(aRxPending, aError); otLogFuncExit(); } @@ -842,8 +846,6 @@ void Mac::HandleMacTimer(void *aContext) void Mac::HandleMacTimer(void) { - otPlatRadioReceive(mNetif.GetInstance(), mChannel); - switch (mState) { case kStateActiveScan: @@ -854,6 +856,7 @@ void Mac::HandleMacTimer(void) if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel) { + otPlatRadioReceive(mNetif.GetInstance(), mChannel); otPlatRadioSetPanId(mNetif.GetInstance(), mPanId); mActiveScanHandler(mScanContext, NULL); ScheduleNextTransmission(); @@ -871,6 +874,7 @@ void Mac::HandleMacTimer(void) case kStateTransmitData: otLogDebgMac("ack timer fired"); + otPlatRadioReceive(mNetif.GetInstance(), mChannel); mCounters.mTxTotal++; SentFrame(kThreadError_NoAck); break; @@ -901,7 +905,7 @@ void Mac::HandleReceiveTimer(void) void Mac::SentFrame(ThreadError aError) { - Frame &sendFrame(*static_cast(otPlatRadioGetTransmitBuffer(mNetif.GetInstance()))); + Frame &sendFrame(*mTxFrame); Sender *sender; switch (aError) diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 89fe143e4..389b6a6ff 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -648,6 +648,8 @@ private: Whitelist mWhitelist; Blacklist mBlacklist; + Frame *mTxFrame; + otMacCounters mCounters; }; diff --git a/src/diag/diag_process.cpp b/src/diag/diag_process.cpp index c049bcc22..44e04a6bc 100644 --- a/src/diag/diag_process.cpp +++ b/src/diag/diag_process.cpp @@ -61,6 +61,8 @@ uint8_t Diag::sChannel; uint8_t Diag::sTxLen; uint32_t Diag::sTxPeriod; uint32_t Diag::sTxPackets; +RadioPacket * Diag::sTxPacket; + otInstance *Diag::sContext; void Diag::Init(otInstance *aInstance) @@ -72,6 +74,7 @@ void Diag::Init(otInstance *aInstance) sTxLen = 0; sTxPackets = 0; memset(&sStats, 0, sizeof(struct DiagStats)); + sTxPacket = otPlatRadioGetTransmitBuffer(sContext); } char *Diag::ProcessCmd(int argc, char *argv[]) @@ -174,23 +177,21 @@ ThreadError Diag::ParseLong(char *argv, long &value) void Diag::TxPacket() { - RadioPacket *packet = otPlatRadioGetTransmitBuffer(sContext); - if (sTxPackets > 0) { sTxPackets--; } - packet->mLength = sTxLen; - packet->mChannel = sChannel; - packet->mPower = sTxPower; + sTxPacket->mLength = sTxLen; + sTxPacket->mChannel = sChannel; + sTxPacket->mPower = sTxPower; for (uint8_t i = 0; i < sTxLen; i++) { - packet->mPsdu[i] = i; + sTxPacket->mPsdu[i] = i; } - otPlatRadioTransmit(sContext); + otPlatRadioTransmit(sContext, sTxPacket); } void Diag::ProcessChannel(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen) @@ -375,8 +376,10 @@ extern "C" void otPlatDiagAlarmFired(otInstance *aInstance) Diag::AlarmFired(aInstance); } -extern "C" void otPlatDiagRadioTransmitDone(otInstance *aInstance, bool aRxPending, ThreadError aError) +extern "C" void otPlatDiagRadioTransmitDone(otInstance *aInstance, RadioPacket *aPacket, bool aRxPending, ThreadError aError) { + (void)aPacket; + Diag::DiagTransmitDone(aInstance, aRxPending, aError); } diff --git a/src/diag/diag_process.hpp b/src/diag/diag_process.hpp index e13084ebf..bacaf294e 100644 --- a/src/diag/diag_process.hpp +++ b/src/diag/diag_process.hpp @@ -92,6 +92,7 @@ private: static uint8_t sTxLen; static uint32_t sTxPeriod; static uint32_t sTxPackets; + static RadioPacket *sTxPacket; static otInstance *sContext; }; diff --git a/tests/unit/test_diag.cpp b/tests/unit/test_diag.cpp index 269ab6409..fcb0123ea 100644 --- a/tests/unit/test_diag.cpp +++ b/tests/unit/test_diag.cpp @@ -55,8 +55,9 @@ extern "C" void otPlatAlarmFired(otInstance *) { } -extern "C" void otPlatRadioTransmitDone(otInstance *, bool aRxPending, ThreadError aError) +extern "C" void otPlatRadioTransmitDone(otInstance *, RadioPacket *aFrame, bool aRxPending, ThreadError aError) { + (void)aFrame; (void)aRxPending; (void)aError; } diff --git a/tests/unit/test_fuzz.cpp b/tests/unit/test_fuzz.cpp index 5d6598d4f..589e5d4f4 100644 --- a/tests/unit/test_fuzz.cpp +++ b/tests/unit/test_fuzz.cpp @@ -145,7 +145,7 @@ void TestFuzz(uint32_t aSeconds) if (g_fTransmit) { g_fTransmit = false; - otPlatRadioTransmitDone(aInstance, true, kThreadError_None); + otPlatRadioTransmitDone(aInstance, &g_TransmitRadioPacket, true, kThreadError_None); #ifdef DBG_FUZZ Log("<== transmit"); #endif diff --git a/tests/unit/test_platform.cpp b/tests/unit/test_platform.cpp index a9f1508c6..7517ce984 100644 --- a/tests/unit/test_platform.cpp +++ b/tests/unit/test_platform.cpp @@ -203,8 +203,10 @@ extern "C" { } } - ThreadError otPlatRadioTransmit(otInstance *aInstance) + ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket) { + (void)aPacket; + if (g_testPlatRadioTransmit) { return g_testPlatRadioTransmit(aInstance); @@ -346,7 +348,7 @@ exit: { } - void otPlatDiagRadioTransmitDone(otInstance *, bool, ThreadError) + void otPlatDiagRadioTransmitDone(otInstance *, RadioPacket *, bool, ThreadError) { }