From d0763e7283d2ad9ecf84607278fc8cca43b5850e Mon Sep 17 00:00:00 2001 From: Robert Quattlebaum Date: Wed, 28 Sep 2016 17:05:51 -0700 Subject: [PATCH] ncp-spinel: Update raw stream to support new metadata format (#717) This commit updates the raw packet reporting mechanism to use the [new Spinel metadata format][1] with `PROP_STREAM_RAW`. To do this, a new boolean was needed for the `RadioPacket` structure to allow us to differentiate packets that we received over the air versus packets we have transmitted. Since the format of the 802.15.4-PHY-specific metadata hasn't yet been defined, that field (Along with the vendor data field) is left unspecified. [1]: https://cdn.rawgit.com/darconeous/openthread/5b887f3a4e7df5c0c806ca1ba80fb1d9619cf8f2/doc/draft-spinel-protocol.html#frame-metadata-format --- include/platform/radio.h | 15 +++++++------ src/core/mac/mac.cpp | 2 ++ src/ncp/ncp_base.cpp | 47 ++++++++++++++++++++++++++++------------ src/ncp/spinel.h | 9 ++++++++ 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/include/platform/radio.h b/include/platform/radio.h index 03c83919f..97aabbf32 100644 --- a/include/platform/radio.h +++ b/include/platform/radio.h @@ -96,13 +96,14 @@ typedef enum otRadioCaps */ typedef struct RadioPacket { - uint8_t *mPsdu; ///< The PSDU. - uint8_t mLength; ///< Length of the PSDU. - uint8_t mChannel; ///< Channel used to transmit/receive the frame. - int8_t mPower; ///< Transmit/receive power in dBm. - uint8_t mLqi; ///< Link Quality Indicator for received frames. - bool mSecurityValid; ///< Security Enabled flag is set and frame passes security checks. - uint16_t mFcs; ///< Final checksum (optional) + uint8_t *mPsdu; ///< The PSDU. + uint8_t mLength; ///< Length of the PSDU. + uint8_t mChannel; ///< Channel used to transmit/receive the frame. + int8_t mPower; ///< Transmit/receive power in dBm. + uint8_t mLqi; ///< Link Quality Indicator for received frames. + bool mSecurityValid: 1; ///< Security Enabled flag is set and frame passes security checks. + bool mDidTX: 1; ///< Set to true if this packet sent from the radio. Ignored by radio driver. + uint16_t mFcs; ///< Final checksum (optional) } RadioPacket; /** diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index accd40f86..e554ed806 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -657,6 +657,7 @@ void Mac::HandleBeginTransmit(void) if (mPcapCallback) { + sendFrame.mDidTX = true; mPcapCallback(&sendFrame, mPcapCallbackContext); } @@ -1040,6 +1041,7 @@ void Mac::ReceiveDoneTask(Frame *aFrame, ThreadError aError) if (mPcapCallback) { + aFrame->mDidTX = false; mPcapCallback(aFrame, mPcapCallbackContext); } diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 8c9dcdc2d..4a9db1504 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -523,6 +523,7 @@ void NcpBase::HandleRawFrame(const RadioPacket *aFrame, void *aContext) void NcpBase::HandleRawFrame(const RadioPacket *aFrame) { ThreadError errorCode = kThreadError_None; + uint16_t flags = 0; if (!mIsRawStreamEnabled) { @@ -531,20 +532,32 @@ void NcpBase::HandleRawFrame(const RadioPacket *aFrame) SuccessOrExit(errorCode = OutboundFrameBegin()); - // Append frame header and frame length + if (aFrame->mFcs != 0x0000) + { + flags |= SPINEL_MD_FLAG_HAS_FCS; + } + if (aFrame->mDidTX) + { + flags |= SPINEL_MD_FLAG_TX; + } + + // Append frame header and frame length SuccessOrExit( errorCode = OutboundFrameFeedPacked( "CiiS", SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_STREAM_RAW, - aFrame->mLength + 2 // +2 for FCS + aFrame->mLength + ( + ((flags & SPINEL_MD_FLAG_HAS_FCS) == SPINEL_MD_FLAG_HAS_FCS) + ? 2 // +2 if we are appending the FCS + : 0 // +0 if we aren't appending the FCS + ) ) ); // Append the frame contents - SuccessOrExit( errorCode = OutboundFrameFeedData( aFrame->mPsdu, @@ -552,21 +565,27 @@ void NcpBase::HandleRawFrame(const RadioPacket *aFrame) ) ); - // Append the FCS - SuccessOrExit( - errorCode = OutboundFrameFeedPacked( - "CC", - (aFrame->mFcs >> 0) & 0xFF, - (aFrame->mFcs >> 8) & 0xFF - ) - ); + if ((flags & SPINEL_MD_FLAG_HAS_FCS) == SPINEL_MD_FLAG_HAS_FCS) + { + // Append the FCS + SuccessOrExit( + errorCode = OutboundFrameFeedPacked( + "CC", + (aFrame->mFcs >> 0) & 0xFF, + (aFrame->mFcs >> 8) & 0xFF + ) + ); + } // Append metadata (rssi, etc) - SuccessOrExit( errorCode = OutboundFrameFeedPacked( - "c", - aFrame->mPower + "ccS", + aFrame->mPower, // TX Power + -128, // Noise Floor (Currently unused) + flags // Flags + + // Skip PHY and Vendor data for now ) ); diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 2e0cbf1b9..7949a8fa1 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -244,6 +244,15 @@ typedef unsigned int spinel_size_t; typedef uint8_t spinel_tid_t; typedef unsigned int spinel_cid_t; +enum +{ + SPINEL_MD_FLAG_TX = 0x0001, + SPINEL_MD_FLAG_HAS_FCS = 0x0002, + SPINEL_MD_FLAG_BAD_FCS = 0x0004, + SPINEL_MD_FLAG_DUPE = 0x0008, + SPINEL_MD_FLAG_RESERVED = 0xFFF0, +}; + enum { SPINEL_CMD_NOOP = 0,