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,