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)
{
}