diff --git a/examples/platforms/posix/radio.c b/examples/platforms/posix/radio.c index 47f82b847..ccdcb2aca 100644 --- a/examples/platforms/posix/radio.c +++ b/examples/platforms/posix/radio.c @@ -39,6 +39,7 @@ #include #include "utils/code_utils.h" +#include "utils/mac_frame.h" #include "utils/soft_source_match_table.h" // The IPv4 group for receiving packets of radio simulation @@ -46,44 +47,11 @@ enum { - IEEE802154_MIN_LENGTH = 5, - IEEE802154_MAX_LENGTH = 127, IEEE802154_ACK_LENGTH = 5, - IEEE802154_BROADCAST = 0xffff, + IEEE802154_FRAME_TYPE_ACK = 2 << 0, - IEEE802154_FRAME_TYPE_ACK = 2 << 0, - IEEE802154_FRAME_TYPE_MACCMD = 3 << 0, - IEEE802154_FRAME_TYPE_MASK = 7 << 0, - - IEEE802154_SECURITY_ENABLED = 1 << 3, - IEEE802154_FRAME_PENDING = 1 << 4, - IEEE802154_ACK_REQUEST = 1 << 5, - IEEE802154_PANID_COMPRESSION = 1 << 6, - - IEEE802154_DST_ADDR_NONE = 0 << 2, - IEEE802154_DST_ADDR_SHORT = 2 << 2, - IEEE802154_DST_ADDR_EXT = 3 << 2, - IEEE802154_DST_ADDR_MASK = 3 << 2, - - IEEE802154_SRC_ADDR_NONE = 0 << 6, - IEEE802154_SRC_ADDR_SHORT = 2 << 6, - IEEE802154_SRC_ADDR_EXT = 3 << 6, - IEEE802154_SRC_ADDR_MASK = 3 << 6, - - IEEE802154_DSN_OFFSET = 2, - IEEE802154_DSTPAN_OFFSET = 3, - IEEE802154_DSTADDR_OFFSET = 5, - - IEEE802154_SEC_LEVEL_MASK = 7 << 0, - - IEEE802154_KEY_ID_MODE_0 = 0 << 3, - IEEE802154_KEY_ID_MODE_1 = 1 << 3, - IEEE802154_KEY_ID_MODE_2 = 2 << 3, - IEEE802154_KEY_ID_MODE_3 = 3 << 3, - IEEE802154_KEY_ID_MODE_MASK = 3 << 3, - - IEEE802154_MACCMD_DATA_REQ = 4, + IEEE802154_FRAME_PENDING = 1 << 4, }; enum @@ -102,6 +70,7 @@ extern uint16_t sPortOffset; static int sTxFd = -1; static int sRxFd = -1; static uint16_t sPortOffset = 0; +static uint16_t sPort = 0; #endif enum @@ -134,12 +103,12 @@ static otRadioFrame sAckFrame; static otRadioIeInfo sTransmitIeInfo; #endif -static uint8_t sExtendedAddress[OT_EXT_ADDRESS_SIZE]; -static uint16_t sShortAddress; -static uint16_t sPanid; -static bool sPromiscuous = false; -static bool sTxWait = false; -static int8_t sTxPower = 0; +static otExtAddress sExtAddress; +static otShortAddress sShortAddress; +static otPanId sPanid; +static bool sPromiscuous = false; +static bool sTxWait = false; +static int8_t sTxPower = 0; static bool sSrcMatchEnabled = false; @@ -147,153 +116,42 @@ static bool sSrcMatchEnabled = false; static bool sRadioCoexEnabled = true; #endif -static inline bool isFrameTypeAck(const uint8_t *aFrame) +static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin) { - return (aFrame[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK; -} - -static inline bool isFrameTypeMacCmd(const uint8_t *aFrame) -{ - return (aFrame[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_MACCMD; -} - -static inline bool isSecurityEnabled(const uint8_t *aFrame) -{ - return (aFrame[0] & IEEE802154_SECURITY_ENABLED) != 0; -} - -static inline bool isAckRequested(const uint8_t *aFrame) -{ - return (aFrame[0] & IEEE802154_ACK_REQUEST) != 0; -} - -static inline bool isPanIdCompressed(const uint8_t *aFrame) -{ - return (aFrame[0] & IEEE802154_PANID_COMPRESSION) != 0; -} - -static inline bool isDataRequestAndHasFramePending(const uint8_t *aFrame) -{ - const uint8_t *cur = aFrame; - uint8_t securityControl; - bool isDataRequest = false; - bool hasFramePending = true; - - // FCF + DSN - cur += 2 + 1; - - otEXPECT(isFrameTypeMacCmd(aFrame)); - - // Destination PAN + Address - switch (aFrame[1] & IEEE802154_DST_ADDR_MASK) + for (size_t i = 0; i < sizeof(*aReversed); i++) { - case IEEE802154_DST_ADDR_SHORT: - cur += sizeof(otPanId) + sizeof(otShortAddress); - break; + aReversed->m8[i] = aOrigin->m8[sizeof(*aOrigin) - 1 - i]; + } +} - case IEEE802154_DST_ADDR_EXT: - cur += sizeof(otPanId) + sizeof(otExtAddress); - break; +static bool isDataRequestAndHasFramePending(const otRadioFrame *aFrame) +{ + bool rval = false; + otMacAddress src; + otEXPECT(otMacFrameIsDataRequest(aFrame)); + otEXPECT_ACTION(sSrcMatchEnabled, rval = true); + otEXPECT(otMacFrameGetSrcAddr(aFrame, &src) == OT_ERROR_NONE); + + switch (src.mType) + { + case OT_MAC_ADDRESS_TYPE_SHORT: + rval = utilsSoftSrcMatchShortFindEntry(src.mAddress.mShortAddress) >= 0; + break; + case OT_MAC_ADDRESS_TYPE_EXTENDED: + { + otExtAddress extAddr; + + ReverseExtAddress(&extAddr, &src.mAddress.mExtAddress); + rval = utilsSoftSrcMatchExtFindEntry(&extAddr) >= 0; + break; + } default: - goto exit; - } - - // Source PAN + Address - switch (aFrame[1] & IEEE802154_SRC_ADDR_MASK) - { - case IEEE802154_SRC_ADDR_SHORT: - if (!isPanIdCompressed(aFrame)) - { - cur += sizeof(otPanId); - } - - if (sSrcMatchEnabled) - { - hasFramePending = utilsSoftSrcMatchShortFindEntry((uint16_t)(cur[1] << 8 | cur[0])) >= 0; - } - - cur += sizeof(otShortAddress); break; - - case IEEE802154_SRC_ADDR_EXT: - if (!isPanIdCompressed(aFrame)) - { - cur += sizeof(otPanId); - } - - if (sSrcMatchEnabled) - { - hasFramePending = utilsSoftSrcMatchExtFindEntry((const otExtAddress *)cur) >= 0; - } - - cur += sizeof(otExtAddress); - break; - - default: - goto exit; } - // Security Control + Frame Counter + Key Identifier - if (isSecurityEnabled(aFrame)) - { - securityControl = *cur; - - if (securityControl & IEEE802154_SEC_LEVEL_MASK) - { - cur += 1 + 4; - } - - switch (securityControl & IEEE802154_KEY_ID_MODE_MASK) - { - case IEEE802154_KEY_ID_MODE_0: - cur += 0; - break; - - case IEEE802154_KEY_ID_MODE_1: - cur += 1; - break; - - case IEEE802154_KEY_ID_MODE_2: - cur += 5; - break; - - case IEEE802154_KEY_ID_MODE_3: - cur += 9; - break; - } - } - - // Command ID - isDataRequest = cur[0] == IEEE802154_MACCMD_DATA_REQ; - exit: - return isDataRequest && hasFramePending; -} - -static inline uint8_t getDsn(const uint8_t *aFrame) -{ - return aFrame[IEEE802154_DSN_OFFSET]; -} - -static inline otPanId getDstPan(const uint8_t *aFrame) -{ - return (otPanId)((aFrame[IEEE802154_DSTPAN_OFFSET + 1] << 8) | aFrame[IEEE802154_DSTPAN_OFFSET]); -} - -static inline otShortAddress getShortAddress(const uint8_t *aFrame) -{ - return (otShortAddress)((aFrame[IEEE802154_DSTADDR_OFFSET + 1] << 8) | aFrame[IEEE802154_DSTADDR_OFFSET]); -} - -static inline void getExtAddress(const uint8_t *aFrame, otExtAddress *aAddress) -{ - size_t i; - - for (i = 0; i < sizeof(otExtAddress); i++) - { - aAddress->m8[i] = aFrame[IEEE802154_DSTADDR_OFFSET + (sizeof(otExtAddress) - 1 - i)]; - } + return rval; } static uint16_t crc16_citt(uint16_t aFcs, uint8_t aByte) @@ -338,7 +196,7 @@ void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) aIeeeEui64[7] = gNodeId & 0xff; } -void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanid) +void otPlatRadioSetPanId(otInstance *aInstance, otPanId aPanid) { assert(aInstance != NULL); @@ -350,13 +208,10 @@ void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aE { assert(aInstance != NULL); - for (size_t i = 0; i < sizeof(sExtendedAddress); i++) - { - sExtendedAddress[i] = aExtAddress->m8[sizeof(sExtendedAddress) - 1 - i]; - } + ReverseExtAddress(&sExtAddress, aExtAddress); } -void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress) +void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aAddress) { assert(aInstance != NULL); @@ -381,8 +236,9 @@ static void initFds(void) otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sTxFd)")); + sPort = (uint16_t)(9000 + sPortOffset + gNodeId); sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons((uint16_t)(9000 + sPortOffset + gNodeId)); + sockaddr.sin_port = htons(sPort); sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); otEXPECT_ACTION(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &sockaddr.sin_addr, sizeof(sockaddr.sin_addr)) != -1, @@ -598,7 +454,7 @@ bool otPlatRadioGetPromiscuous(otInstance *aInstance) static void radioReceive(otInstance *aInstance) { bool isTxDone = false; - bool isAck = isFrameTypeAck(sReceiveFrame.mPsdu); + bool isAck = otMacFrameIsAck(&sReceiveFrame); otEXPECT(sReceiveFrame.mChannel == sReceiveMessage.mChannel); otEXPECT(sState == OT_RADIO_STATE_RECEIVE || sState == OT_RADIO_STATE_TRANSMIT); @@ -608,9 +464,9 @@ static void radioReceive(otInstance *aInstance) if (sTxWait) { - if (isAckRequested(sTransmitFrame.mPsdu)) + if (otMacFrameIsAckRequested(&sTransmitFrame)) { - isTxDone = isAck && getDsn(sReceiveFrame.mPsdu) == getDsn(sTransmitFrame.mPsdu); + isTxDone = isAck && otMacFrameGetSequence(&sReceiveFrame) == otMacFrameGetSequence(&sTransmitFrame); } #if OPENTHREAD_POSIX_VIRTUAL_TIME // Simulate tx done when receiving the echo frame. @@ -699,7 +555,7 @@ void radioSendMessage(otInstance *aInstance) radioTransmit(&sTransmitMessage, &sTransmitFrame); #if OPENTHREAD_POSIX_VIRTUAL_TIME == 0 - sTxWait = isAckRequested(sTransmitFrame.mPsdu); + sTxWait = otMacFrameIsAckRequested(&sTransmitFrame); if (!sTxWait) { @@ -786,13 +642,22 @@ void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const #if OPENTHREAD_POSIX_VIRTUAL_TIME == 0 if (FD_ISSET(sRxFd, aReadFdSet)) { - ssize_t rval = recvfrom(sRxFd, (char *)&sReceiveMessage, sizeof(sReceiveMessage), 0, NULL, NULL); + struct sockaddr_in sockaddr; + socklen_t len = sizeof(sockaddr); + ssize_t rval; + + memset(&sockaddr, 0, sizeof(sockaddr)); + rval = + recvfrom(sRxFd, (char *)&sReceiveMessage, sizeof(sReceiveMessage), 0, (struct sockaddr *)&sockaddr, &len); if (rval > 0) { - sReceiveFrame.mLength = (uint8_t)(rval - 1); + if (sockaddr.sin_port != htons(sPort)) + { + sReceiveFrame.mLength = (uint16_t)(rval - 1); - radioReceive(aInstance); + radioReceive(aInstance); + } } else if (rval == 0) { @@ -849,14 +714,14 @@ void radioSendAck(void) sAckFrame.mLength = IEEE802154_ACK_LENGTH; sAckMessage.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK; - if (isDataRequestAndHasFramePending(sReceiveFrame.mPsdu)) + if (isDataRequestAndHasFramePending(&sReceiveFrame)) { sAckMessage.mPsdu[0] |= IEEE802154_FRAME_PENDING; sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true; } sAckMessage.mPsdu[1] = 0; - sAckMessage.mPsdu[2] = getDsn(sReceiveFrame.mPsdu); + sAckMessage.mPsdu[2] = otMacFrameGetSequence(&sReceiveFrame); sAckMessage.mChannel = sReceiveFrame.mChannel; @@ -866,45 +731,20 @@ void radioSendAck(void) void radioProcessFrame(otInstance *aInstance) { - otError error = OT_ERROR_NONE; - otPanId dstpan; - otShortAddress short_address; - otExtAddress ext_address; - - otEXPECT_ACTION(sPromiscuous == false, error = OT_ERROR_NONE); - - switch (sReceiveFrame.mPsdu[1] & IEEE802154_DST_ADDR_MASK) - { - case IEEE802154_DST_ADDR_NONE: - break; - - case IEEE802154_DST_ADDR_SHORT: - dstpan = getDstPan(sReceiveFrame.mPsdu); - short_address = getShortAddress(sReceiveFrame.mPsdu); - otEXPECT_ACTION((dstpan == IEEE802154_BROADCAST || dstpan == sPanid) && - (short_address == IEEE802154_BROADCAST || short_address == sShortAddress), - error = OT_ERROR_ABORT); - break; - - case IEEE802154_DST_ADDR_EXT: - dstpan = getDstPan(sReceiveFrame.mPsdu); - getExtAddress(sReceiveFrame.mPsdu, &ext_address); - otEXPECT_ACTION((dstpan == IEEE802154_BROADCAST || dstpan == sPanid) && - memcmp(&ext_address, sExtendedAddress, sizeof(ext_address)) == 0, - error = OT_ERROR_ABORT); - break; - - default: - error = OT_ERROR_ABORT; - goto exit; - } + otError error = OT_ERROR_NONE; sReceiveFrame.mInfo.mRxInfo.mRssi = -20; sReceiveFrame.mInfo.mRxInfo.mLqi = OT_RADIO_LQI_NONE; sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = false; + + otEXPECT(sPromiscuous == false); + + otEXPECT_ACTION(otMacFrameDoesAddrMatch(&sReceiveFrame, sPanid, sShortAddress, &sExtAddress), + error = OT_ERROR_ABORT); + // generate acknowledgment - if (isAckRequested(sReceiveFrame.mPsdu)) + if (otMacFrameIsAckRequested(&sReceiveFrame)) { radioSendAck(); } diff --git a/examples/platforms/utils/Makefile.am b/examples/platforms/utils/Makefile.am index 62c2beaf1..a073d185d 100644 --- a/examples/platforms/utils/Makefile.am +++ b/examples/platforms/utils/Makefile.am @@ -43,6 +43,8 @@ libopenthread_platform_utils_a_SOURCES = \ flash.h \ logging_rtt.c \ logging_rtt.h \ + mac_frame.cpp \ + mac_frame.h \ settings_ram.c \ settings_flash.c \ soft_source_match_table.c \ diff --git a/examples/platforms/utils/mac_frame.cpp b/examples/platforms/utils/mac_frame.cpp new file mode 100644 index 000000000..99ddddff7 --- /dev/null +++ b/examples/platforms/utils/mac_frame.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mac_frame.h" + +#include "mac/mac_frame.hpp" + +using namespace ot; + +bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame, + otPanId aPanId, + otShortAddress aShortAddress, + const otExtAddress *aExtAddress) +{ + const Mac::Frame &frame = *static_cast(aFrame); + bool rval = false; + Mac::Address dst; + Mac::PanId panid; + + SuccessOrExit(frame.GetDstAddr(dst)); + + switch (dst.GetType()) + { + case Mac::Address::kTypeShort: + SuccessOrExit(frame.GetDstPanId(panid)); + rval = (panid == Mac::kPanIdBroadcast || panid == aPanId) && + (dst.GetShort() == Mac::kShortAddrBroadcast || dst.GetShort() == aShortAddress); + break; + + case Mac::Address::kTypeExtended: + SuccessOrExit(frame.GetDstPanId(panid)); + rval = (panid == Mac::kPanIdBroadcast || panid == aPanId) && + dst.GetExtended() == *static_cast(aExtAddress); + break; + + case Mac::Address::kTypeNone: + rval = true; + break; + } + +exit: + return rval; +} + +bool otMacFrameIsAck(const otRadioFrame *aFrame) +{ + return static_cast(aFrame)->GetType() == Mac::Frame::kFcfFrameAck; +} + +bool otMacFrameIsDataRequest(const otRadioFrame *aFrame) +{ + return static_cast(aFrame)->IsDataRequestCommand(); +} + +bool otMacFrameIsAckRequested(const otRadioFrame *aFrame) +{ + return static_cast(aFrame)->GetAckRequest(); +} + +otError otMacFrameGetSrcAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress) +{ + otError error; + Mac::Address address; + + error = static_cast(aFrame)->GetSrcAddr(address); + SuccessOrExit(error); + + switch (address.GetType()) + { + case Mac::Address::kTypeNone: + aMacAddress->mType = OT_MAC_ADDRESS_TYPE_NONE; + break; + + case Mac::Address::kTypeShort: + aMacAddress->mType = OT_MAC_ADDRESS_TYPE_SHORT; + aMacAddress->mAddress.mShortAddress = address.GetShort(); + break; + + case Mac::Address::kTypeExtended: + aMacAddress->mType = OT_MAC_ADDRESS_TYPE_EXTENDED; + aMacAddress->mAddress.mExtAddress = address.GetExtended(); + break; + } + +exit: + return error; +} + +uint8_t otMacFrameGetSequence(const otRadioFrame *aFrame) +{ + return static_cast(aFrame)->GetSequence(); +} diff --git a/examples/platforms/utils/mac_frame.h b/examples/platforms/utils/mac_frame.h new file mode 100644 index 000000000..79343bd4d --- /dev/null +++ b/examples/platforms/utils/mac_frame.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief + * This file defines the mac frame interface for OpenThread platform radio drivers. + * + */ + +#ifndef OPENTHREAD_UTILS_MAC_FRAME_H +#define OPENTHREAD_UTILS_MAC_FRAME_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This enumeration specifies the IEEE 802.15.4 Address type. + * + */ +typedef enum +{ + OT_MAC_ADDRESS_TYPE_NONE, ///< No address. + OT_MAC_ADDRESS_TYPE_SHORT, ///< IEEE 802.15.4 Short Address. + OT_MAC_ADDRESS_TYPE_EXTENDED, ///< IEEE 802.15.4 Extended Address. +} otMacAddressType; + +/** + * This structure represents an IEEE 802.15.4 short or extended Address. + * + */ +typedef struct otMacAddress +{ + union + { + otShortAddress mShortAddress; ///< The IEEE 802.15.4 Short Address. + otExtAddress mExtAddress; ///< The IEEE 802.15.4 Extended Address. + } mAddress; + + otMacAddressType mType; ///< The address type (short, extended, or none). +} otMacAddress; + +/** + * Check if @p aFrame is an Ack frame. + * + * @param[in] aFrame A pointer to the frame. + * + * @retval true It is an ACK frame. + * @retval false It is not an ACK frame. + * + */ +bool otMacFrameIsAck(const otRadioFrame *aFrame); + +/** + * Check if @p aFrame is an Data Request Command. + * + * @param[in] aFrame A pointer to the frame. + * + * @retval true It is a Data Request Command frame. + * @retval false It is not a Data Request Command frame. + * + */ +bool otMacFrameIsDataRequest(const otRadioFrame *aFrame); + +/** + * Check if @p aFrame requests ACK. + * + * @param[in] aFrame A pointer to the frame. + * + * @retval true It requests ACK. + * @retval false It does not request ACK. + * + */ +bool otMacFrameIsAckRequested(const otRadioFrame *aFrame); + +/** + * Check if @p aFrame matches the @p aPandId and @p aShortAddress or @p aExtAddress. + * + * @param[in] aFrame A pointer to the frame. + * @param[in] aPanId The PAN id to match with. + * @param[in] aShortAddress The short address to match with. + * @param[in] aExtAddress The extended address to match with. + * + * @retval true It is a broadcast or matches with the PAN id and one of the addresses. + * @retval false It doesn't match. + * + */ +bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame, + otPanId aPanId, + otShortAddress aShortAddress, + const otExtAddress *aExtAddress); + +/** + * Get source MAC address. + * + * @param[in] aFrame A pointer to the frame. + * @param[out] aMacAddress A pointer to MAC address. + * + * @retval OT_ERROR_NONE Successfully got the source MAC address. + * @retval OT_ERROR_PARSE Failed to parse the source MAC address. + * + */ +otError otMacFrameGetSrcAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress); + +/** + * Get the sequence of @p aFrame. + * + * @param[in] aFrame A pointer to the frame. + * + * @returns The sequence of the frame. + * + */ +uint8_t otMacFrameGetSequence(const otRadioFrame *aFrame); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // OPENTHREAD_UTILS_MAC_FRAME_H diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 74cf6be90..a3cfa3275 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -959,6 +959,7 @@ public: * @param[out] aPanId The Destination PAN Identifier. * * @retval OT_ERROR_NONE Successfully retrieved the Destination PAN Identifier. + * @retval OT_ERROR_PARSE Failed to parse the PAN Identifier. * */ otError GetDstPanId(PanId &aPanId) const;