[ncp] decode meta-data (CSMA/retry counts) in STREAM_RAW property set (#3727)

This commit adds logic to decode and use the optional meta-data fields
in a `VALUE_SET` command (frame tx request) for `PROP_STREAM_RAW` in
raw-link or radio only (RCP) mode. The optional meta-data fields map
to definitions in `otRadioFrame` to specify number of CSMA backoffs
attempts, frame retry attempts, whether to enable CSMA-CA for this
frame or not. If any optional field is not included, default value
is used instead. This aligns the implementation with specification
of `PROP_STREAM_RAW` in `spinel.h`.
This commit is contained in:
Abtin Keshavarzian
2019-04-03 17:03:27 -07:00
committed by Jonathan Hui
parent 8c0fed1c22
commit a4614ac795
2 changed files with 42 additions and 16 deletions
+1
View File
@@ -409,6 +409,7 @@ protected:
#endif // OPENTHREAD_FTD
#if OPENTHREAD_RADIO || OPENTHREAD_ENABLE_RAW_LINK_API
otError DecodeStreamRawTxRequest(otRadioFrame &aFrame);
otError HandlePropertySet_SPINEL_PROP_STREAM_RAW(uint8_t aHeader);
#endif
+41 -16
View File
@@ -336,33 +336,58 @@ exit:
return error;
}
otError NcpBase::DecodeStreamRawTxRequest(otRadioFrame &aFrame)
{
otError error;
const uint8_t *payloadPtr;
uint16_t payloadLen;
bool csmaEnable;
SuccessOrExit(error = mDecoder.ReadDataWithLen(payloadPtr, payloadLen));
VerifyOrExit(payloadLen <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_PARSE);
aFrame.mLength = static_cast<uint8_t>(payloadLen);
memcpy(aFrame.mPsdu, payloadPtr, aFrame.mLength);
// Parse the meta data
// Channel is a required parameter in meta data.
SuccessOrExit(error = mDecoder.ReadUint8(aFrame.mChannel));
// Set the default value for all optional parameters.
aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs = OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT;
aFrame.mInfo.mTxInfo.mMaxFrameRetries = OPENTHREAD_CONFIG_MAC_MAX_FRAME_RETRIES_DIRECT;
aFrame.mInfo.mTxInfo.mCsmaCaEnabled = true;
// All the next parameters are optional. Note that even if the
// decoder fails to parse any of optional parameters we still want to
// return `OT_ERROR_NONE` (so `error` is not updated after this
// point).
SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs));
SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxFrameRetries));
SuccessOrExit(mDecoder.ReadBool(csmaEnable));
aFrame.mInfo.mTxInfo.mCsmaCaEnabled = csmaEnable;
exit:
return error;
}
otError NcpBase::HandlePropertySet_SPINEL_PROP_STREAM_RAW(uint8_t aHeader)
{
const uint8_t *frameBuffer = NULL;
otRadioFrame * frame;
uint16_t frameLen = 0;
otError error = OT_ERROR_NONE;
otError error = OT_ERROR_NONE;
otRadioFrame *frame;
VerifyOrExit(otLinkRawIsEnabled(mInstance), error = OT_ERROR_INVALID_STATE);
frame = otLinkRawGetTransmitBuffer(mInstance);
VerifyOrExit(frame != NULL, error = OT_ERROR_NO_BUFS);
SuccessOrExit(error = mDecoder.ReadDataWithLen(frameBuffer, frameLen));
SuccessOrExit(error = mDecoder.ReadUint8(frame->mChannel));
VerifyOrExit(frameLen <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_PARSE);
SuccessOrExit(error = DecodeStreamRawTxRequest(*frame));
// Cache the transaction ID for async response
mCurTransmitTID = SPINEL_HEADER_GET_TID(aHeader);
// Update frame buffer and length
frame->mLength = static_cast<uint8_t>(frameLen);
memcpy(frame->mPsdu, frameBuffer, frame->mLength);
// TODO: This should be later added in the STREAM_RAW argument to allow user to directly specify it.
frame->mInfo.mTxInfo.mMaxCsmaBackoffs = OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT;
frame->mInfo.mTxInfo.mMaxFrameRetries = OPENTHREAD_CONFIG_MAC_MAX_FRAME_RETRIES_DIRECT;
// Pass frame to the radio layer. Note, this fails if we
// haven't enabled raw stream or are already transmitting.
error = otLinkRawTransmit(mInstance, &NcpBase::LinkRawTransmitDone);