[mac] add feature to transmit out of band 15.4 frames (#2488)

This commit is contained in:
pvanhorn
2018-01-18 22:48:30 +00:00
committed by Jonathan Hui
parent 0acba9909c
commit 9339230acd
4 changed files with 104 additions and 5 deletions
+12
View File
@@ -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.
*
+7
View File
@@ -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
View File
@@ -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;
+16
View File
@@ -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;