mirror of
https://github.com/espressif/openthread.git
synced 2026-08-02 09:07:47 +00:00
[mac] add feature to transmit out of band 15.4 frames (#2488)
This commit is contained in:
@@ -150,6 +150,18 @@ OTAPI otError OTCALL otLinkSendDataRequest(otInstance *aInstance);
|
||||
*/
|
||||
OTAPI bool OTCALL otLinkIsInTransmitState(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function enqueues an IEEE 802.15.4 out of band Frame for transmission.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @parma[in] aOobFrame A pointer to the frame to transmit.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully enqueued an IEEE 802.15.4 Data Request message.
|
||||
* @retval OT_ERROR_ALREADY An IEEE 802.15.4 out of band frame is already enqueued.
|
||||
*
|
||||
*/
|
||||
OTAPI otError OTCALL otLinkOutOfBandTransmitRequest(otInstance *aInstance, otRadioFrame *aOobFrame);
|
||||
|
||||
/**
|
||||
* Get the IEEE 802.15.4 channel.
|
||||
*
|
||||
|
||||
@@ -358,3 +358,10 @@ bool otLinkIsInTransmitState(otInstance *aInstance)
|
||||
|
||||
return instance.GetThreadNetif().GetMac().IsInTransmitState();
|
||||
}
|
||||
|
||||
otError otLinkOutOfBandTransmitRequest(otInstance *aInstance, otRadioFrame *aOobFrame)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetThreadNetif().GetMac().SendOutOfBandFrameRequest(aOobFrame);
|
||||
}
|
||||
|
||||
+69
-5
@@ -83,6 +83,7 @@ Mac::Mac(Instance &aInstance):
|
||||
mPendingEnergyScan(false),
|
||||
mPendingTransmitBeacon(false),
|
||||
mPendingTransmitData(false),
|
||||
mPendingTransmitOobFrame(false),
|
||||
mPendingWaitingForData(false),
|
||||
mRxOnWhenIdle(false),
|
||||
mBeaconsEnabled(false),
|
||||
@@ -116,6 +117,7 @@ Mac::Mac(Instance &aInstance):
|
||||
mFilter(),
|
||||
#endif // OPENTHREAD_ENABLE_MAC_FILTER
|
||||
mTxFrame(static_cast<Frame *>(otPlatRadioGetTransmitBuffer(&aInstance))),
|
||||
mOobFrame(NULL),
|
||||
mKeyIdMode2FrameCounter(0)
|
||||
{
|
||||
GenerateExtAddress(&mExtAddress);
|
||||
@@ -184,7 +186,8 @@ bool Mac::IsEnergyScanInProgress(void)
|
||||
|
||||
bool Mac::IsInTransmitState(void)
|
||||
{
|
||||
return (mOperation == kOperationTransmitData) || (mOperation == kOperationTransmitBeacon);
|
||||
return (mOperation == kOperationTransmitData) ||
|
||||
(mOperation == kOperationTransmitBeacon) || (mOperation == kOperationTransmitOutOfBandFrame);
|
||||
}
|
||||
|
||||
otError Mac::ConvertBeaconToActiveScanResult(Frame *aBeaconFrame, otActiveScanResult &aResult)
|
||||
@@ -499,6 +502,20 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Mac::SendOutOfBandFrameRequest(otRadioFrame *aOobFrame)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(mOobFrame == NULL, error = OT_ERROR_ALREADY);
|
||||
|
||||
mOobFrame = static_cast<Frame *>(aOobFrame);
|
||||
|
||||
StartOperation(kOperationTransmitOutOfBandFrame);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Mac::UpdateIdleMode(void)
|
||||
{
|
||||
VerifyOrExit(mOperation == kOperationIdle);
|
||||
@@ -554,6 +571,10 @@ void Mac::StartOperation(Operation aOperation)
|
||||
case kOperationWaitingForData:
|
||||
mPendingWaitingForData = true;
|
||||
break;
|
||||
|
||||
case kOperationTransmitOutOfBandFrame:
|
||||
mPendingTransmitOobFrame = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mOperation == kOperationIdle)
|
||||
@@ -592,6 +613,12 @@ void Mac::PerformOperation(void)
|
||||
mOperation = kOperationWaitingForData;
|
||||
RadioReceive(mChannel);
|
||||
}
|
||||
else if (mPendingTransmitOobFrame)
|
||||
{
|
||||
mPendingTransmitOobFrame = false;
|
||||
mOperation = kOperationTransmitOutOfBandFrame;
|
||||
StartCsmaBackoff();
|
||||
}
|
||||
else if (mPendingActiveScan)
|
||||
{
|
||||
mPendingActiveScan = false;
|
||||
@@ -884,10 +911,31 @@ void Mac::HandleBeginTransmit(Timer &aTimer)
|
||||
aTimer.GetOwner<Mac>().HandleBeginTransmit();
|
||||
}
|
||||
|
||||
Frame *Mac::GetOperationFrame(void)
|
||||
{
|
||||
Frame *frame = NULL;
|
||||
|
||||
switch (mOperation)
|
||||
{
|
||||
case kOperationTransmitOutOfBandFrame:
|
||||
frame = mOobFrame;
|
||||
break;
|
||||
|
||||
default:
|
||||
frame = mTxFrame;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(frame != NULL);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
void Mac::HandleBeginTransmit(void)
|
||||
{
|
||||
Frame &sendFrame(*mTxFrame);
|
||||
otError error = OT_ERROR_NONE;
|
||||
bool applyTransmitSecurity = true;
|
||||
Frame &sendFrame(*GetOperationFrame());
|
||||
|
||||
#if OPENTHREAD_CONFIG_DISABLE_CCA_ON_LAST_ATTEMPT
|
||||
|
||||
@@ -933,13 +981,20 @@ void Mac::HandleBeginTransmit(void)
|
||||
|
||||
break;
|
||||
|
||||
case kOperationTransmitOutOfBandFrame:
|
||||
applyTransmitSecurity = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Security Processing
|
||||
ProcessTransmitSecurity(sendFrame);
|
||||
if (applyTransmitSecurity)
|
||||
{
|
||||
// Security Processing
|
||||
ProcessTransmitSecurity(sendFrame);
|
||||
}
|
||||
}
|
||||
|
||||
error = RadioReceive(sendFrame.GetChannel());
|
||||
@@ -958,7 +1013,7 @@ exit:
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
HandleTransmitDone(mTxFrame, NULL, OT_ERROR_ABORT);
|
||||
HandleTransmitDone(&sendFrame, NULL, OT_ERROR_ABORT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1177,6 +1232,11 @@ void Mac::HandleTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otEr
|
||||
break;
|
||||
}
|
||||
|
||||
case kOperationTransmitOutOfBandFrame:
|
||||
mOobFrame = NULL;
|
||||
FinishOperation();
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
@@ -1942,6 +2002,10 @@ const char *Mac::OperationToString(Operation aOperation)
|
||||
case kOperationWaitingForData:
|
||||
retval = "WaitingForData";
|
||||
break;
|
||||
|
||||
case kOperationTransmitOutOfBandFrame:
|
||||
retval = "TransmitOobFrame";
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
@@ -347,6 +347,18 @@ public:
|
||||
*/
|
||||
otError SendFrameRequest(Sender &aSender);
|
||||
|
||||
/**
|
||||
* This method registers a Out of Band frame for MAC Transmission.
|
||||
* An Out of Band frame is one that was generated outside of OpenThread.
|
||||
*
|
||||
* @param[in] aOobFrame A pointer to the frame.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully registered the frame.
|
||||
* @retval OT_ERROR_ALREADY MAC layer is busy sending a previously registered frame.
|
||||
*
|
||||
*/
|
||||
otError SendOutOfBandFrameRequest(otRadioFrame *aOobFrame);
|
||||
|
||||
/**
|
||||
* This method generates a random IEEE 802.15.4 Extended Address.
|
||||
*
|
||||
@@ -625,6 +637,7 @@ private:
|
||||
kOperationTransmitBeacon,
|
||||
kOperationTransmitData,
|
||||
kOperationWaitingForData,
|
||||
kOperationTransmitOutOfBandFrame,
|
||||
};
|
||||
|
||||
void GenerateNonce(const ExtAddress &aAddress, uint32_t aFrameCounter, uint8_t aSecurityLevel, uint8_t *aNonce);
|
||||
@@ -637,6 +650,7 @@ private:
|
||||
void SendBeacon(Frame &aFrame);
|
||||
void StartBackoff(void);
|
||||
otError HandleMacCommand(Frame &aFrame);
|
||||
Frame *GetOperationFrame(void);
|
||||
|
||||
static void HandleMacTimer(Timer &aTimer);
|
||||
void HandleMacTimer(void);
|
||||
@@ -668,6 +682,7 @@ private:
|
||||
bool mPendingEnergyScan : 1;
|
||||
bool mPendingTransmitBeacon : 1;
|
||||
bool mPendingTransmitData : 1;
|
||||
bool mPendingTransmitOobFrame : 1;
|
||||
bool mPendingWaitingForData : 1;
|
||||
bool mRxOnWhenIdle : 1;
|
||||
bool mBeaconsEnabled : 1;
|
||||
@@ -720,6 +735,7 @@ private:
|
||||
#endif // OPENTHREAD_ENABLE_MAC_FILTER
|
||||
|
||||
Frame *mTxFrame;
|
||||
Frame *mOobFrame;
|
||||
|
||||
otMacCounters mCounters;
|
||||
uint32_t mKeyIdMode2FrameCounter;
|
||||
|
||||
Reference in New Issue
Block a user