From 1f24fa44fab2a79438408069278e6898a3b4f4f7 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Fri, 13 May 2016 15:14:04 -0700 Subject: [PATCH] Add active scan to API and CLI. (#27) * Add active scan functions and definitions to core C api. * Add active scan command to CLI. * Add emulation of PHY channel isolation. --- examples/platform/posix/radio.cpp | 53 +++++++-- include/openthread-types.h | 43 +++++++ include/openthread.h | 124 +++++++++++++------- src/cli/README.md | 15 +++ src/cli/cli.cpp | 112 ++++++++++++++---- src/cli/cli.hpp | 2 + src/core/mac/mac.cpp | 157 +++++-------------------- src/core/mac/mac.hpp | 65 ++++------- src/core/mac/mac_frame.cpp | 12 +- src/core/mac/mac_frame.hpp | 165 +++++++++++++++++++++++++-- src/core/net/ip6_address.cpp | 2 +- src/core/openthread.cpp | 58 +++++++++- src/core/thread/address_resolver.cpp | 8 +- src/core/thread/mle.cpp | 8 +- 14 files changed, 546 insertions(+), 278 deletions(-) diff --git a/examples/platform/posix/radio.cpp b/examples/platform/posix/radio.cpp index 5aebbee21..40a9ffce4 100644 --- a/examples/platform/posix/radio.cpp +++ b/examples/platform/posix/radio.cpp @@ -61,8 +61,15 @@ enum PhyState kStateListen = 3, kStateReceive = 4, kStateTransmit = 5, + kStateAckWait = 6, }; +struct RadioMessage +{ + uint8_t mChannel; + uint8_t mPsdu[Mac::Frame::kMTU]; +} __attribute__((packed)); + static void *phy_receive_thread(void *arg); static PhyState s_state = kStateDisabled; @@ -171,6 +178,7 @@ ThreadError otPlatRadioIdle() case kStateListen: case kStateTransmit: + case kStateAckWait: s_state = kStateIdle; pthread_cond_signal(&s_condition_variable); break; @@ -205,6 +213,7 @@ ThreadError otPlatRadioTransmit(RadioPacket *packet) { ThreadError error = kThreadError_None; struct sockaddr_in sockaddr; + RadioMessage message; pthread_mutex_lock(&s_mutex); VerifyOrExit(s_state == kStateIdle, error = kThreadError_Busy); @@ -218,6 +227,9 @@ ThreadError otPlatRadioTransmit(RadioPacket *packet) sockaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr); + message.mChannel = s_transmit_frame->mChannel; + memcpy(message.mPsdu, s_transmit_frame->mPsdu, s_transmit_frame->mLength); + for (int i = 1; i < 34; i++) { if (args_info.nodeid_arg == i) @@ -226,11 +238,14 @@ ThreadError otPlatRadioTransmit(RadioPacket *packet) } sockaddr.sin_port = htons(9000 + i); - sendto(s_sockfd, s_transmit_frame->mPsdu, s_transmit_frame->mLength, 0, - (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + sendto(s_sockfd, &message, 1 + s_transmit_frame->mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); } - if (!reinterpret_cast(s_transmit_frame)->GetAckRequest()) + if (reinterpret_cast(s_transmit_frame)->GetAckRequest()) + { + s_state = kStateAckWait; + } + else { otPlatRadioSignalTransmitDone(); } @@ -249,7 +264,7 @@ ThreadError otPlatRadioHandleTransmitDone(bool *rxPending) { ThreadError error = kThreadError_None; - VerifyOrExit(s_state == kStateTransmit, error = kThreadError_InvalidState); + VerifyOrExit(s_state == kStateTransmit || s_state == kStateAckWait, error = kThreadError_InvalidState); pthread_mutex_lock(&s_mutex); s_state = kStateIdle; @@ -273,6 +288,7 @@ void *phy_receive_thread(void *arg) int length; uint8_t tx_sequence, rx_sequence; uint8_t command_id; + RadioMessage message; while (1) { @@ -288,7 +304,7 @@ void *phy_receive_thread(void *arg) pthread_mutex_lock(&s_mutex); - while (s_state == kStateIdle) + while (s_state == kStateIdle || s_state == kStateTransmit) { pthread_cond_wait(&s_condition_variable, &s_mutex); } @@ -302,7 +318,12 @@ void *phy_receive_thread(void *arg) break; case kStateTransmit: - length = recvfrom(s_sockfd, receive_frame.mPsdu, Mac::Frame::kMTU, 0, NULL, NULL); + break; + + case kStateAckWait: + length = recvfrom(s_sockfd, &message, sizeof(message), 0, NULL, NULL); + receive_frame.mLength = length - 1; + memcpy(receive_frame.mPsdu, message.mPsdu, receive_frame.mLength); if (length < 0) { @@ -337,7 +358,17 @@ void *phy_receive_thread(void *arg) break; case kStateListen: + length = recvfrom(s_sockfd, &message, sizeof(message), 0, NULL, NULL); + + if (s_receive_frame->mChannel != message.mChannel) + { + break; + } + s_state = kStateReceive; + s_receive_frame->mLength = length - 1; + memcpy(s_receive_frame->mPsdu, message.mPsdu, s_receive_frame->mLength); + otPlatRadioSignalReceiveDone(); while (s_state == kStateReceive) @@ -361,6 +392,7 @@ void *phy_receive_thread(void *arg) void send_ack() { Mac::Frame *ack_frame; + RadioMessage message; uint8_t sequence; struct sockaddr_in sockaddr; @@ -374,6 +406,9 @@ void send_ack() sockaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr); + message.mChannel = s_receive_frame->mChannel; + memcpy(message.mPsdu, m_ack_packet.mPsdu, m_ack_packet.mLength); + for (int i = 1; i < 34; i++) { if (args_info.nodeid_arg == i) @@ -382,8 +417,7 @@ void send_ack() } sockaddr.sin_port = htons(9000 + i); - sendto(s_sockfd, m_ack_packet.mPsdu, m_ack_packet.mLength, 0, - (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + sendto(s_sockfd, &message, 1 + m_ack_packet.mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); } } @@ -393,11 +427,9 @@ ThreadError otPlatRadioHandleReceiveDone() Mac::Frame *receive_frame; uint16_t dstpan; Mac::Address dstaddr; - int length; VerifyOrExit(s_state == kStateReceive, error = kThreadError_InvalidState); - length = recvfrom(s_sockfd, s_receive_frame->mPsdu, Mac::Frame::kMTU, 0, NULL, NULL); receive_frame = reinterpret_cast(s_receive_frame); receive_frame->GetDstAddr(dstaddr); @@ -425,7 +457,6 @@ ThreadError otPlatRadioHandleReceiveDone() ExitNow(error = kThreadError_Abort); } - s_receive_frame->mLength = length; s_receive_frame->mPower = -20; // generate acknowledgment diff --git a/include/openthread-types.h b/include/openthread-types.h index b4eba3953..792ef927a 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -65,6 +65,49 @@ typedef enum ThreadError kThreadError_Error = 255, } ThreadError; + +#define OT_EXT_ADDRESS_SIZE 8 ///< Size of an IEEE 802.15.4 Extended Address (bytes) +#define OT_EXT_PAN_ID_SIZE 8 ///< Size of a Thread PAN ID (bytes) +#define OT_NETWORK_NAME_SIZE 16 ///< Size of the Thread Network Name field (bytes) + +/** + * This type represents the IEEE 802.15.4 PAN ID. + * + */ +typedef uint16_t otPanId; + +/** + * This type represents the IEEE 802.15.4 Short Address. + * + */ +typedef uint16_t otShortAddress; + +/** + * This type represents the IEEE 802.15.4 Extended Address. + * + */ +typedef struct otExtAddress +{ + uint8_t m8[OT_EXT_ADDRESS_SIZE]; ///< IEEE 802.15.4 Extended Address bytes +} otExtAddress; + +/** + * This struct represents a received IEEE 802.15.4 Beacon. + * + */ +typedef struct otActiveScanResult +{ + otExtAddress mExtAddress; ///< IEEE 802.15.4 Extended Address + const char *mNetworkName; ///< Thread Network Name + const uint8_t *mExtPanId; ///< Thread Extended PAN ID + uint16_t mPanId; ///< IEEE 802.15.4 PAN ID + uint8_t mChannel; ///< IEEE 802.15.4 Channel + int8_t mRssi; ///< RSSI (dBm) + uint8_t mVersion : 4; ///< Version + bool mIsNative : 1; ///< Native Commissioner flag + bool mIsJoinable : 1; ///< Joining Permitted flag +} otActiveScanResult; + /** * @addtogroup config Configuration * diff --git a/include/openthread.h b/include/openthread.h index 98c937b70..0729507b7 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -51,6 +51,7 @@ extern "C" { * @{ * * @defgroup execution Execution + * @defgroup commands Commands * @defgroup config Configuration * @defgroup diags Diagnostics * @defgroup messages Message Buffers @@ -130,6 +131,57 @@ bool otAreTaskletsPending(void); */ extern void otSignalTaskletPending(void); +/** + * @} + * + */ + +/** + * @addtogroup commands Commands + * + * @brief + * This module includes functions for OpenThread commands. + * + * @{ + * + */ + +/** + * Enable the Thread interface. + * + * @retval kThreadErrorNone Successfully enabled the Thread interface. + */ +ThreadError otEnable(void); + +/** + * Disable the Thread interface. + * + * @retval kThreadErrorNone Successfully disabled the Thread interface. + */ +ThreadError otDisable(void); + +/** + * This function pointer is called during an IEEE 802.15.4 Active Scan when an IEEE 802.15.4 Beacon is received or + * the scan completes. + * + * @param[in] aResult A valid pointer to the beacon information or NULL when the active scan completes. + * + */ +typedef void (*otHandleActiveScanResult)(otActiveScanResult *aResult); + +/** + * This function starts an IEEE 802.15.4 Active Scan + * + * @param[in] aScanChannels A bit vector indicating which channels to scan. + * @param[in] aScanDuration The time in milliseconds to spend scanning each channel. + * @param[in] aCallback A pointer to a function that is called when a beacon is received or the scan completes. + * + * @retval kThreadError_None Accepted the Active Scan request. + * @retval kThreadError_Busy Already performing an Active Scan. + * + */ +ThreadError otActiveScan(uint16_t aScanChannels, uint16_t aScanDuration, otHandleActiveScanResult aCallback); + /** * @} * @@ -289,7 +341,7 @@ ThreadError otSetNetworkName(const char *aNetworkName); * * @sa otSetPanId */ -uint16_t otGetPanId(void); +otPanId otGetPanId(void); /** * Set the IEEE 802.15.4 PAN ID. @@ -301,7 +353,34 @@ uint16_t otGetPanId(void); * * @sa otGetPanId */ -ThreadError otSetPanId(uint16_t aPanId); +ThreadError otSetPanId(otPanId aPanId); + +/** + * Get the list of IPv6 addresses assigned to the Thread interface. + * + * @returns A pointer to the first Network Inteface Address. + */ +const otNetifAddress *otGetUnicastAddresses(); + +/** + * Add a Network Interface Address to the Thread interface. + * + * @param[in] aAddress A pointer to a Network Interface Address. + * + * @retval kThreadErrorNone Successfully added the Network Interface Address. + * @retval kThreadErrorBusy The Network Interface Address pointed to by @p aAddress is already added. + */ +ThreadError otAddUnicastAddress(otNetifAddress *aAddress); + +/** + * Remove a Network Interface Address from the Thread interface. + * + * @param[in] aAddress A pointer to a Network Interface Address. + * + * @retval kThreadErrorNone Successfully removed the Network Interface Address. + * @retval kThreadErrorNotFound The Network Interface Address point to by @p aAddress was not added. + */ +ThreadError otRemoveUnicastAddress(otNetifAddress *aAddress); /** * @} @@ -730,47 +809,6 @@ bool otIsIp6AddressEqual(const otIp6Address *a, const otIp6Address *b); */ ThreadError otIp6AddressFromString(const char *aString, otIp6Address *aAddress); -/** - * Get the list of IPv6 addresses assigned to the Thread interface. - * - * @returns A pointer to the first Network Inteface Address. - */ -const otNetifAddress *otGetUnicastAddresses(); - -/** - * Add a Network Interface Address to the Thread interface. - * - * @param[in] aAddress A pointer to a Network Interface Address. - * - * @retval kThreadErrorNone Successfully added the Network Interface Address. - * @retval kThreadErrorBusy The Network Interface Address pointed to by @p aAddress is already added. - */ -ThreadError otAddUnicastAddress(otNetifAddress *aAddress); - -/** - * Remove a Network Interface Address from the Thread interface. - * - * @param[in] aAddress A pointer to a Network Interface Address. - * - * @retval kThreadErrorNone Successfully removed the Network Interface Address. - * @retval kThreadErrorNotFound The Network Interface Address point to by @p aAddress was not added. - */ -ThreadError otRemoveUnicastAddress(otNetifAddress *aAddress); - -/** - * Enable the Thread interface. - * - * @retval kThreadErrorNone Successfully enabled the Thread interface. - */ -ThreadError otEnable(void); - -/** - * Disable the Thread interface. - * - * @retval kThreadErrorNone Successfully disabled the Thread interface. - */ -ThreadError otDisable(void); - /** * @addtogroup messages Message Buffers * diff --git a/src/cli/README.md b/src/cli/README.md index 080a71cc0..2063a1048 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -27,6 +27,7 @@ OpenThread test scripts use this CLI to execute test cases. * [rloc16](#rloc16) * [route](#route) * [routerupgradethreshold](#routerupgradethreshold) +* [scan](#scan) * [start](#start) * [state](#state) * [stop](#stop) @@ -396,6 +397,20 @@ $ routerupgradethreshold 16 Done ``` +### scan \[channel\] + +Perform an IEEE 802.15.4 Active Scan. + +* channel: The channel to scan on. If no channel is provided, the active scan will cover all valid channels. + +```bash +$ scan +| J | Network Name | Extended PAN | PAN | MAC Address | Ch | dBm | ++---+------------------+------------------+------+------------------+----+-----+ +| 0 | OpenThread | dead00beef00cafe | ffff | f1d92a82c8d8fe43 | 11 | -20 | +Done +``` + ### start Enable OpenThread. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 626c6dff0..10a6ac880 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -69,6 +69,7 @@ const struct Command Interpreter::sCommands[] = { "rloc16", &ProcessRloc16 }, { "route", &ProcessRoute }, { "routerupgradethreshold", &ProcessRouterUpgradeThreshold }, + { "scan", &ProcessScan }, { "shutdown", &ProcessShutdown }, { "start", &ProcessStart }, { "state", &ProcessState }, @@ -167,7 +168,7 @@ void Interpreter::ProcessChannel(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessChildTimeout(int argc, char *argv[]) @@ -187,7 +188,7 @@ void Interpreter::ProcessChildTimeout(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessContextIdReuseDelay(int argc, char *argv[]) @@ -207,7 +208,7 @@ void Interpreter::ProcessContextIdReuseDelay(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessExtAddress(int argc, char *argv[]) @@ -240,7 +241,7 @@ void Interpreter::ProcessExtPanId(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } ThreadError Interpreter::ProcessIpAddrAdd(int argc, char *argv[]) @@ -302,7 +303,7 @@ void Interpreter::ProcessIpAddr(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessKeySequence(int argc, char *argv[]) @@ -322,7 +323,7 @@ void Interpreter::ProcessKeySequence(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessLeaderWeight(int argc, char *argv[]) @@ -342,7 +343,7 @@ void Interpreter::ProcessLeaderWeight(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessMasterKey(int argc, char *argv[]) @@ -371,7 +372,7 @@ void Interpreter::ProcessMasterKey(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessMode(int argc, char *argv[]) @@ -437,7 +438,7 @@ void Interpreter::ProcessMode(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessNetworkDataRegister(int argc, char *argv[]) @@ -446,7 +447,7 @@ void Interpreter::ProcessNetworkDataRegister(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessNetworkIdTimeout(int argc, char *argv[]) @@ -466,7 +467,7 @@ void Interpreter::ProcessNetworkIdTimeout(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessNetworkName(int argc, char *argv[]) @@ -483,7 +484,7 @@ void Interpreter::ProcessNetworkName(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessPanId(int argc, char *argv[]) @@ -503,7 +504,7 @@ void Interpreter::ProcessPanId(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::HandleEchoResponse(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) @@ -544,7 +545,7 @@ void Interpreter::ProcessPing(int argc, char *argv[]) sResponse.Init(); exit: - {} + return; } ThreadError Interpreter::ProcessPrefixAdd(int argc, char *argv[]) @@ -685,7 +686,7 @@ void Interpreter::ProcessPrefix(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessReleaseRouterId(int argc, char *argv[]) @@ -700,7 +701,7 @@ void Interpreter::ProcessReleaseRouterId(int argc, char *argv[]) } exit: - {} + return; } void Interpreter::ProcessRloc16(int argc, char *argv[]) @@ -819,7 +820,7 @@ void Interpreter::ProcessRoute(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessRouterUpgradeThreshold(int argc, char *argv[]) @@ -839,7 +840,72 @@ void Interpreter::ProcessRouterUpgradeThreshold(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; +} + +void Interpreter::ProcessScan(int argc, char *argv[]) +{ + uint16_t scanChannels = 0; + long value; + + if (argc > 0) + { + SuccessOrExit(ParseLong(argv[0], value)); + scanChannels = 1 << (value - kPhyMinChannel); + } + + SuccessOrExit(otActiveScan(scanChannels, 0, &HandleActiveScanResult)); + sResponse.Append("| J | Network Name | Extended PAN | PAN | MAC Address | Ch | dBm |\r\n"); + sResponse.Append("+---+------------------+------------------+------+------------------+----+-----+\r\n"); + +exit: + return; +} + +void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult) +{ + const uint8_t *bytes; + + sResponse.Init(); + + if (aResult == NULL) + { + sResponse.Append("Done\r\n"); + ExitNow(); + } + + sResponse.Append("| %d ", aResult->mIsJoinable); + + if (aResult->mNetworkName != NULL) + { + sResponse.Append("| %-16s ", aResult->mNetworkName); + } + else + { + sResponse.Append("| ---------------- "); + } + + if (aResult->mExtPanId != NULL) + { + bytes = aResult->mExtPanId; + sResponse.Append("| %02x%02x%02x%02x%02x%02x%02x%02x ", + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]); + } + else + { + sResponse.Append("| ---------------- "); + } + + sResponse.Append("| %04x ", aResult->mPanId); + + bytes = aResult->mExtAddress.m8; + sResponse.Append("| %02x%02x%02x%02x%02x%02x%02x%02x ", + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]); + sResponse.Append("| %02d ", aResult->mChannel); + sResponse.Append("| %03d |\r\n", aResult->mRssi); + +exit: + sServer->Output(sResponse.GetResponse(), sResponse.GetResponseLength()); } void Interpreter::ProcessShutdown(int argc, char *argv[]) @@ -856,7 +922,7 @@ void Interpreter::ProcessStart(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessState(int argc, char *argv[]) @@ -913,7 +979,7 @@ void Interpreter::ProcessState(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessStop(int argc, char *argv[]) @@ -922,7 +988,7 @@ void Interpreter::ProcessStop(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessWhitelist(int argc, char *argv[]) @@ -973,7 +1039,7 @@ void Interpreter::ProcessWhitelist(int argc, char *argv[]) sResponse.Append("Done\r\n"); exit: - {} + return; } void Interpreter::ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer) @@ -1012,7 +1078,7 @@ void Interpreter::ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer) } exit: - {} + return; } } // namespace Cli diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index a34990d62..f7b78cb04 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -159,6 +159,7 @@ private: static ThreadError ProcessRouteRemove(int argc, char *argv[]); static void ProcessRouterUpgradeThreshold(int argc, char *argv[]); static void ProcessRloc16(int argc, char *argv[]); + static void ProcessScan(int argc, char *argv[]); static void ProcessShutdown(int argc, char *argv[]); static void ProcessStart(int argc, char *argv[]); static void ProcessState(int argc, char *argv[]); @@ -166,6 +167,7 @@ private: static void ProcessWhitelist(int argc, char *argv[]); static void HandleEchoResponse(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + static void HandleActiveScanResult(otActiveScanResult *aResult); static int Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength); static ThreadError ParseLong(char *argv, long &value); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 499db7bd7..f847db324 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -85,11 +85,12 @@ Mac::Mac(ThreadNetif &aThreadNetif): mRxOnWhenIdle = true; mCsmaAttempts = 0; mTransmitBeacon = false; + mBeacon.Init(); mActiveScanRequest = false; mScanChannel = kPhyMinChannel; - mScanChannelMask = 0xff; - mScanIntervalPerChannel = 0; + mScanChannels = 0xff; + mScanDuration = 0; mActiveScanHandler = NULL; mActiveScanContext = NULL; @@ -103,7 +104,7 @@ Mac::Mac(ThreadNetif &aThreadNetif): for (size_t i = 0; i < sizeof(mExtAddress); i++) { - mExtAddress.mBytes[i] = otPlatRandomGet(); + mExtAddress.m8[i] = otPlatRandomGet(); } SetExtendedPanId(sExtendedPanidInit); @@ -121,7 +122,7 @@ ThreadError Mac::Start(void) SuccessOrExit(error = otPlatRadioEnable()); - SetExtendedPanId(mExtendedPanid); + SetExtendedPanId(mBeacon.GetExtendedPanId()); otPlatRadioSetPanId(mPanId); otPlatRadioSetShortAddress(mShortAddress); { @@ -129,7 +130,7 @@ ThreadError Mac::Start(void) for (size_t i = 0; i < sizeof(buf); i++) { - buf[i] = mExtAddress.mBytes[7 - i]; + buf[i] = mExtAddress.m8[7 - i]; } otPlatRadioSetExtendedAddress(buf); @@ -174,8 +175,7 @@ exit: return error; } -ThreadError Mac::ActiveScan(uint16_t aIntervalPerChannel, uint16_t aChannelMask, - ActiveScanHandler aHandler, void *aContext) +ThreadError Mac::ActiveScan(uint16_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler, void *aContext) { ThreadError error = kThreadError_None; @@ -184,21 +184,21 @@ ThreadError Mac::ActiveScan(uint16_t aIntervalPerChannel, uint16_t aChannelMask, mActiveScanHandler = aHandler; mActiveScanContext = aContext; - mScanChannelMask = (aChannelMask == 0) ? kScanChannelMaskAll : aChannelMask; - mScanIntervalPerChannel = (aIntervalPerChannel == 0) ? kScanDefaultInterval : aIntervalPerChannel; + mScanChannels = (aScanChannels == 0) ? kScanChannelsAll : aScanChannels; + mScanDuration = (aScanDuration == 0) ? kScanDurationDefault : aScanDuration; mScanChannel = kPhyMinChannel; - while ((mScanChannelMask & 1) == 0) + while ((mScanChannels & 1) == 0) { - mScanChannelMask >>= 1; + mScanChannels >>= 1; mScanChannel++; } if (mState == kStateIdle) { mState = kStateActiveScan; - mBeginTransmit.Post(); + StartCsmaBackoff(); } else { @@ -266,22 +266,21 @@ ThreadError Mac::SetChannel(uint8_t aChannel) const char *Mac::GetNetworkName(void) const { - return mNetworkName; + return mBeacon.GetNetworkName(); } ThreadError Mac::SetNetworkName(const char *aNetworkName) { - memset(mNetworkName, 0, sizeof(mNetworkName)); - strncpy(mNetworkName, aNetworkName, sizeof(mNetworkName)); + mBeacon.SetNetworkName(aNetworkName); return kThreadError_None; } -uint16_t Mac::GetPanId(void) const +PanId Mac::GetPanId(void) const { return mPanId; } -ThreadError Mac::SetPanId(uint16_t aPanId) +ThreadError Mac::SetPanId(PanId aPanId) { mPanId = aPanId; return otPlatRadioSetPanId(mPanId); @@ -289,13 +288,13 @@ ThreadError Mac::SetPanId(uint16_t aPanId) const uint8_t *Mac::GetExtendedPanId(void) const { - return mExtendedPanid; + return mBeacon.GetExtendedPanId(); } ThreadError Mac::SetExtendedPanId(const uint8_t *aExtPanId) { - memcpy(mExtendedPanid, aExtPanId, sizeof(mExtendedPanid)); - mMle.SetMeshLocalPrefix(mExtendedPanid); + mBeacon.SetExtendedPanId(aExtPanId); + mMle.SetMeshLocalPrefix(aExtPanId); return kThreadError_None; } @@ -366,7 +365,6 @@ void Mac::ScheduleNextTransmission(void) else if (mTransmitBeacon) { mTransmitBeacon = false; - assert(false); mState = kStateTransmitBeacon; StartCsmaBackoff(); } @@ -386,7 +384,7 @@ void Mac::GenerateNonce(const ExtAddress &aAddress, uint32_t aFrameCounter, uint // source address for (int i = 0; i < 8; i++) { - aNonce[i] = aAddress.mBytes[i]; + aNonce[i] = aAddress.m8[i]; } aNonce += 8; @@ -416,7 +414,6 @@ void Mac::SendBeaconRequest(Frame &aFrame) void Mac::SendBeacon(Frame &aFrame) { - uint8_t *payload; uint16_t fcf; // initialize MAC header @@ -426,38 +423,8 @@ void Mac::SendBeacon(Frame &aFrame) aFrame.SetSrcAddr(mExtAddress); // write payload - payload = aFrame.GetPayload(); - - // Superframe Specification - payload[0] = 0xff; - payload[1] = 0x0f; - payload += 2; - - // GTS Fields - payload[0] = 0x00; - payload++; - - // Pending Address Fields - payload[0] = 0x00; - payload++; - - // Protocol ID - payload[0] = 0x03; - payload++; - - // Version and Flags - payload[0] = 0x1 << 4 | 0x1; - payload++; - - // Network Name - memcpy(payload, mNetworkName, sizeof(mNetworkName)); - payload += sizeof(mNetworkName); - - // Extended PAN - memcpy(payload, mExtendedPanid, sizeof(mExtendedPanid)); - payload += sizeof(mExtendedPanid); - - aFrame.SetPayloadLength(payload - aFrame.GetPayload()); + memcpy(aFrame.GetPayload(), &mBeacon, sizeof(mBeacon)); + aFrame.SetPayloadLength(sizeof(mBeacon)); otLogInfoMac("Sent Beacon\n"); } @@ -590,7 +557,7 @@ void Mac::TransmitDoneTask(void) switch (mState) { case kStateActiveScan: - mAckTimer.Start(mScanIntervalPerChannel); + mAckTimer.Start(mScanDuration); break; case kStateTransmitBeacon: @@ -634,17 +601,17 @@ void Mac::HandleAckTimer(void) case kStateActiveScan: do { - mScanChannelMask >>= 1; + mScanChannels >>= 1; mScanChannel++; - if (mScanChannelMask == 0 || mScanChannel > kPhyMaxChannel) + if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel) { mActiveScanHandler(mActiveScanContext, NULL); ScheduleNextTransmission(); ExitNow(); } } - while ((mScanChannelMask & 1) == 0); + while ((mScanChannels & 1) == 0); StartCsmaBackoff(); break; @@ -684,7 +651,7 @@ void Mac::SentFrame(bool aAcked) switch (mState) { case kStateActiveScan: - mAckTimer.Start(mScanIntervalPerChannel); + mAckTimer.Start(mScanDuration); break; case kStateTransmitBeacon: @@ -908,7 +875,7 @@ void Mac::ReceiveDoneTask(void) switch (mState) { case kStateActiveScan: - HandleBeaconFrame(); + mActiveScanHandler(mActiveScanContext, &mReceiveFrame); break; default: @@ -934,71 +901,6 @@ exit: NextOperation(); } -void Mac::HandleBeaconFrame(void) -{ - uint8_t *payload = mReceiveFrame.GetPayload(); - uint8_t payloadLength = mReceiveFrame.GetPayloadLength(); - ActiveScanResult result; - Address address; - - if (mReceiveFrame.GetType() != Frame::kFcfFrameBeacon) - { - ExitNow(); - } - -#if 0 - - // Superframe Specification, GTS fields, and Pending Address fields - if (payloadLength < 4 || payload[0] != 0xff || payload[1] != 0x0f || payload[2] != 0x00 || payload[3] != 0x00) - { - ExitNow(); - } - -#endif - payload += 4; - payloadLength -= 4; - -#if 0 - - // Protocol ID - if (payload[0] != 3) - { - ExitNow(); - } - -#endif - payload++; - - // skip Version and Flags - payload++; - - // network name - strncpy(result.mNetworkName, reinterpret_cast(payload), kNetworkNameSize); - payload += kNetworkNameSize; - - // extended panid - memcpy(result.mExtPanid, payload, kExtPanIdSize); - payload += kExtPanIdSize; - - // extended address - mReceiveFrame.GetSrcAddr(address); - memcpy(result.mExtAddr, &address.mExtAddress, sizeof(result.mExtAddr)); - - // panid - mReceiveFrame.GetSrcPanId(result.mPanId); - - // channel - result.mChannel = mReceiveFrame.GetChannel(); - - // rssi - result.mRssi = mReceiveFrame.GetPower(); - - mActiveScanHandler(mActiveScanContext, &result); - -exit: - {} -} - ThreadError Mac::HandleMacCommand(void) { ThreadError error = kThreadError_None; @@ -1012,10 +914,9 @@ ThreadError Mac::HandleMacCommand(void) if (mState == kStateIdle) { - assert(false); mState = kStateTransmitBeacon; mTransmitBeacon = false; - mBeginTransmit.Post(); + StartCsmaBackoff(); } ExitNow(error = kThreadError_Drop); diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index e6118c700..92150744b 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -65,36 +65,19 @@ namespace Mac { */ enum { - kMinBE = 3, ///< macMinBE (IEEE 802.15.4-2006) - kMaxBE = 6, ///< macMaxBE (IEEE 802.15.4-2006) - kMaxCSMABackoffs = 12, ///< macMaxCSMABackoffs (IEEE 802.15.4-2006) - kUnitBackoffPeriod = 20, ///< Number of symbols (IEEE 802.15.4-2006) + kMinBE = 3, ///< macMinBE (IEEE 802.15.4-2006) + kMaxBE = 6, ///< macMaxBE (IEEE 802.15.4-2006) + kMaxCSMABackoffs = 12, ///< macMaxCSMABackoffs (IEEE 802.15.4-2006) + kUnitBackoffPeriod = 20, ///< Number of symbols (IEEE 802.15.4-2006) - kMinBackoff = 16, ///< Minimum backoff (milliseconds). + kMinBackoff = 16, ///< Minimum backoff (milliseconds). - kAckTimeout = 16, ///< Timeout for waiting on an ACK (milliseconds). - kDataPollTimeout = 100, ///< Timeout for receivint Data Frame (milliseconds). - kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). + kAckTimeout = 16, ///< Timeout for waiting on an ACK (milliseconds). + kDataPollTimeout = 100, ///< Timeout for receivint Data Frame (milliseconds). + kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). - kScanChannelMaskAll = 0xffff, - kScanDefaultInterval = 128, ///< Default interval between channels (milliseconds). - - kNetworkNameSize = 16, ///< Size of Thread Network Name (bytes). - kExtPanIdSize = 8, ///< Size of Thread Extended PAN ID. -}; - -/** - * This structure represents an Active Scan result. - * - */ -struct ActiveScanResult -{ - char mNetworkName[kNetworkNameSize]; ///< The Thread Network Name. - uint8_t mExtPanid[kExtPanIdSize]; ///< The Thread Extended PAN ID. - uint8_t mExtAddr[ExtAddress::kLength]; ///< The IEEE 802.15.4 Extended Address. - uint16_t mPanId; ///< The IEEE 802.15.4 PAN ID. - uint8_t mChannel; ///< The IEEE 802.15.4 Channel. - int8_t mRssi; ///< The RSSI in dBm. + kScanChannelsAll = 0xffff, ///< All channels. + kScanDurationDefault = 200, ///< Default interval between channels (milliseconds). }; /** @@ -225,23 +208,22 @@ public: /** * This function pointer is called on receiving an IEEE 802.15.4 Beacon during an Active Scan. * - * @param[in] aContext A pointer to arbitrary context information. - * @param[in] aResult A reference to the Active Scan result. + * @param[in] aContext A pointer to arbitrary context information. + * @param[in] aBeaconFrame A pointer to the Beacon frame. * */ - typedef void (*ActiveScanHandler)(void *aContext, ActiveScanResult *aResult); + typedef void (*ActiveScanHandler)(void *aContext, Frame *aBeaconFrame); /** * This method starts an IEEE 802.15.4 Active Scan. * - * @param[in] aIntervalPerChannel The time in milliseconds to spend scanning each channel. - * @param[in] aChannelMask A bit vector indicating which channels to scan. - * @param[in] aHandler A pointer to a function that is called on receiving an IEEE 802.15.4 Beacon. - * @param[in] aContext A pointer to arbitrary context information. + * @param[in] aScanChannels A bit vector indicating which channels to scan. + * @param[in] aScanDuration The time in milliseconds to spend scanning each channel. + * @param[in] aHandler A pointer to a function that is called on receiving an IEEE 802.15.4 Beacon. + * @param[in] aContext A pointer to arbitrary context information. * */ - ThreadError ActiveScan(uint16_t aIntervalPerChannel, uint16_t aChannelMask, - ActiveScanHandler aHandler, void *aContext); + ThreadError ActiveScan(uint16_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler, void *aContext); /** * This method indicates whether or not rx-on-when-idle is enabled. @@ -413,7 +395,6 @@ private: void SendBeaconRequest(Frame &aFrame); void SendBeacon(Frame &aFrame); void StartBackoff(void); - void HandleBeaconFrame(void); ThreadError HandleMacCommand(void); static void HandleAckTimer(void *aContext); @@ -438,11 +419,11 @@ private: ExtAddress mExtAddress; ShortAddress mShortAddress; - uint16_t mPanId; - uint8_t mExtendedPanid[kExtPanIdSize]; - char mNetworkName[kNetworkNameSize]; + PanId mPanId; uint8_t mChannel; + Beacon mBeacon; + Frame mSendFrame; Frame mReceiveFrame; Sender *mSendHead, *mSendTail; @@ -466,8 +447,8 @@ private: bool mActiveScanRequest; uint8_t mScanChannel; - uint16_t mScanChannelMask; - uint16_t mScanIntervalPerChannel; + uint16_t mScanChannels; + uint16_t mScanDuration; ActiveScanHandler mActiveScanHandler; void *mActiveScanContext; diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index a766f946b..16b52711b 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -41,8 +41,8 @@ namespace Mac { void ExtAddress::Set(const Ip6::Address &aIpAddress) { - memcpy(mBytes, aIpAddress.GetIid(), kLength); - mBytes[0] ^= 0x02; + memcpy(m8, aIpAddress.GetIid(), sizeof(m8)); + m8[0] ^= 0x02; } ThreadError Frame::InitMacHeader(uint16_t aFcf, uint8_t aSecurityControl) @@ -287,7 +287,7 @@ ThreadError Frame::GetDstAddr(Address &aAddress) for (unsigned int i = 0; i < sizeof(ExtAddress); i++) { - aAddress.mExtAddress.mBytes[i] = buf[sizeof(ExtAddress) - 1 - i]; + aAddress.mExtAddress.m8[i] = buf[sizeof(ExtAddress) - 1 - i]; } break; @@ -329,7 +329,7 @@ ThreadError Frame::SetDstAddr(const ExtAddress &aExtAddress) for (unsigned int i = 0; i < sizeof(ExtAddress); i++) { - buf[i] = aExtAddress.mBytes[sizeof(ExtAddress) - 1 - i]; + buf[i] = aExtAddress.m8[sizeof(ExtAddress) - 1 - i]; } return kThreadError_None; @@ -444,7 +444,7 @@ ThreadError Frame::GetSrcAddr(Address &address) for (unsigned int i = 0; i < sizeof(ExtAddress); i++) { - address.mExtAddress.mBytes[i] = buf[sizeof(ExtAddress) - 1 - i]; + address.mExtAddress.m8[i] = buf[sizeof(ExtAddress) - 1 - i]; } break; @@ -486,7 +486,7 @@ ThreadError Frame::SetSrcAddr(const ExtAddress &aExtAddress) for (unsigned int i = 0; i < sizeof(aExtAddress); i++) { - buf[i] = aExtAddress.mBytes[sizeof(aExtAddress) - 1 - i]; + buf[i] = aExtAddress.m8[sizeof(aExtAddress) - 1 - i]; } return kThreadError_None; diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index e153619f9..a88c5f656 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -36,7 +36,9 @@ #include #include +#include +#include #include #include @@ -64,19 +66,19 @@ enum * This type represents the IEEE 802.15.4 PAN ID. * */ -typedef uint16_t PanId; +typedef otPanId PanId; /** * This type represents the IEEE 802.15.4 Short Address. * */ -typedef uint16_t ShortAddress; +typedef otShortAddress ShortAddress; /** * This structure represents an IEEE 802.15.4 Extended Address. * */ -class ExtAddress +class ExtAddress: public otExtAddress { public: /** @@ -86,12 +88,6 @@ public: * */ void Set(const Ip6::Address &aIpAddress); - - enum - { - kLength = 8, ///< Size of IEEE 802.15.4 Extended Address in bytes. - }; - uint8_t mBytes[kLength]; ///< The IEEE 802.15.4 Extended Address bytes. }; /** @@ -584,6 +580,157 @@ private: uint8_t *FindSecurityHeader(void); }; +/** + * This class implements IEEE 802.15.4 Beacon generation and parsing. + * + */ +class Beacon +{ +public: + enum + { + kSuperFrameSpec = 0x0fff, ///< Superframe Specification value. + kProtocolId = 3, ///< Thread Protocol ID. + kNetworkNameSize = 16, ///< Size of Thread Network Name (bytes). + kExtPanIdSize = 8, ///< Size of Thread Extended PAN ID. + }; + + enum + { + kProtocolVersion = 1, ///< Thread Protocol version. + kVersionOffset = 4, ///< Version field bit offset. + kVersionMask = 0xf << kVersionOffset, ///< Version field mask. + kNativeFlag = 1 << 3, ///< Native Commissioner flag. + kJoiningFlag = 1 << 0, ///< Joining Permitted flag. + }; + + /** + * This method initializes the Beacon message. + * + */ + void Init(void) { + mSuperframeSpec = Thread::Encoding::LittleEndian::HostSwap16(kSuperFrameSpec); + mGtsSpec = 0; + mPendingAddressSpec = 0; + mProtocolId = kProtocolId; + mFlags = kProtocolVersion << kVersionOffset; + } + + /** + * This method indicates whether or not the beacon appears to be a valid Thread Beacon message. + * + * @retval TRUE if the beacon appears to be a valid Thread Beacon message. + * @retval FALSE if the beacon does not appear to be a valid Thread Beacon message. + * + */ + bool IsValid(void) { + return (mSuperframeSpec == Thread::Encoding::LittleEndian::HostSwap16(kSuperFrameSpec)) && + (mGtsSpec == 0) && (mPendingAddressSpec == 0) && (mProtocolId == kProtocolId); + } + + /** + * This method returns the Protocol ID value.xs + * + * @returns the Protocol ID value. + * + */ + uint8_t GetProtocolId(void) const { return mProtocolId; } + + /** + * This method returns the Protocol Version value. + * + * @returns The Protocol Version value. + * + */ + uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; } + + /** + * This method indicates whether or not the Native Commissioner flag is set. + * + * @retval TRUE if the Native Commissioner flag is set. + * @retval FALSE if the Native Commissioner flag is not set. + * + */ + bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; } + + /** + * This method clears the Native Commissioner flag. + * + */ + void ClearNative(void) { mFlags &= ~kNativeFlag; } + + /** + * This method sets the Native Commissioner flag. + * + */ + void SetNative(void) { mFlags |= kNativeFlag; } + + /** + * This method indicates whether or not the Joining Permitted flag is set. + * + * @retval TRUE if the Joining Permitted flag is set. + * @retval FALSE if the Joining Permitted flag is not set. + * + */ + bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; } + + /** + * This method clears the Joining Permitted flag. + * + */ + void ClearJoiningPermitted(void) { mFlags &= ~kJoiningFlag; } + + /** + * This method sets the Joining Permitted flag. + * + */ + void SetJoiningPermitted(void) { mFlags |= kJoiningFlag; } + + /** + * This method returns a pointer to the Network Name field. + * + * @returns A pointer to the network name field. + * + */ + const char *GetNetworkName(void) const { return mNetworkName; } + + /** + * This method sets the Network Name field. + * + * @param[in] aNetworkName A pointer to the Network Name. + * + */ + void SetNetworkName(const char *aNetworkName) { + memset(mNetworkName, 0, sizeof(mNetworkName)); + strncpy(mNetworkName, aNetworkName, sizeof(mNetworkName)); + } + + /** + * This method returns a pointer to the Extended PAN ID field. + * + * @returns A pointer to the Extended PAN ID field. + * + */ + const uint8_t *GetExtendedPanId(void) const { return mExtendedPanId; } + + /** + * This method sets the Extended PAN ID field. + * + * @param[in] aExtPanId A pointer to the Extended PAN ID. + * + */ + void SetExtendedPanId(const uint8_t *aExtPanId) { memcpy(mExtendedPanId, aExtPanId, sizeof(mExtendedPanId)); } + +private: + uint16_t mSuperframeSpec; + uint8_t mGtsSpec; + uint8_t mPendingAddressSpec; + uint8_t mProtocolId; + uint8_t mFlags; + char mNetworkName[kNetworkNameSize]; + uint8_t mExtendedPanId[kExtPanIdSize]; +} __attribute__((packed)); + /** * @} * diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index 89f0324ae..273287e41 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -116,7 +116,7 @@ void Address::SetIid(const uint8_t *aIid) void Address::SetIid(const Mac::ExtAddress &aEui64) { - memcpy(m8 + kInterfaceIdentifierOffset, aEui64.mBytes, kInterfaceIdentifierSize); + memcpy(m8 + kInterfaceIdentifierOffset, aEui64.m8, kInterfaceIdentifierSize); m8[kInterfaceIdentifierOffset] ^= 0x02; } diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index a58d035b4..385ff8097 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -45,6 +45,10 @@ namespace Thread { +#ifdef __cplusplus +extern "C" { +#endif + // Allocate the structure using "raw" storage. #define otDEFINE_ALIGNED_VAR(name, size, align_type) \ align_type name[(((size) + (sizeof (align_type) - 1)) / sizeof (align_type))] @@ -53,9 +57,7 @@ static otDEFINE_ALIGNED_VAR(sThreadNetifRaw, sizeof(ThreadNetif), uint64_t); static ThreadNetif *sThreadNetif; -#ifdef __cplusplus -extern "C" { -#endif +static void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame); void otInit() { @@ -184,12 +186,12 @@ ThreadError otSetNetworkName(const char *aNetworkName) return sThreadNetif->GetMac().SetNetworkName(aNetworkName); } -uint16_t otGetPanId(void) +otPanId otGetPanId(void) { return sThreadNetif->GetMac().GetPanId(); } -ThreadError otSetPanId(uint16_t aPanId) +ThreadError otSetPanId(otPanId aPanId) { return sThreadNetif->GetMac().SetPanId(aPanId); } @@ -470,6 +472,52 @@ ThreadError otDisable(void) return sThreadNetif->Down(); } +ThreadError otActiveScan(uint16_t aScanChannels, uint16_t aScanDuration, otHandleActiveScanResult aCallback) +{ + return sThreadNetif->GetMac().ActiveScan(aScanChannels, aScanDuration, &HandleActiveScanResult, + reinterpret_cast(aCallback)); +} + +void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame) +{ + otHandleActiveScanResult handler = reinterpret_cast(aContext); + otActiveScanResult result = {}; + Mac::Address address; + Mac::Beacon *beacon; + uint8_t payloadLength; + + if (aFrame == NULL) + { + handler(NULL); + ExitNow(); + } + + SuccessOrExit(aFrame->GetSrcAddr(address)); + VerifyOrExit(address.mLength == sizeof(address.mExtAddress), ;); + memcpy(&result.mExtAddress, &address.mExtAddress, sizeof(result.mExtAddress)); + + aFrame->GetSrcPanId(result.mPanId); + result.mChannel = aFrame->GetChannel(); + result.mRssi = aFrame->GetPower(); + + payloadLength = aFrame->GetPayloadLength(); + beacon = reinterpret_cast(aFrame->GetPayload()); + + if (payloadLength >= sizeof(*beacon) && beacon->IsValid()) + { + result.mVersion = beacon->GetProtocolVersion(); + result.mIsJoinable = beacon->IsJoiningPermitted(); + result.mIsNative = beacon->IsNative(); + result.mNetworkName = beacon->GetNetworkName(); + result.mExtPanId = beacon->GetExtendedPanId(); + } + + handler(&result); + +exit: + return; +} + otMessage otNewUdpMessage() { return Ip6::Udp::NewMessage(0); diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index 3d184c109..446e8a085 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -409,7 +409,7 @@ void AddressResolver::HandleAddressError(Coap::Header &aHeader, Message &aMessag children = mMle.GetChildren(&numChildren); memcpy(&macAddr, mlIidTlv.GetIid(), sizeof(macAddr)); - macAddr.mBytes[0] ^= 0x2; + macAddr.m8[0] ^= 0x2; for (int i = 0; i < Mle::kMaxChildren; i++) { @@ -491,9 +491,9 @@ void AddressResolver::HandleAddressQuery(Coap::Header &aHeader, Message &aMessag continue; } - children[i].mMacAddr.mBytes[0] ^= 0x2; - mlIidTlv.SetIid(children[i].mMacAddr.mBytes); - children[i].mMacAddr.mBytes[0] ^= 0x2; + children[i].mMacAddr.m8[0] ^= 0x2; + mlIidTlv.SetIid(children[i].mMacAddr.m8); + children[i].mMacAddr.m8[0] ^= 0x2; lastTransactionTimeTlv.SetTime(Timer::GetNow() - children[i].mLastHeard); SendAddressQueryResponse(targetTlv, mlIidTlv, &lastTransactionTimeTlv, aMessageInfo.GetPeerAddr()); ExitNow(); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 1b54463b2..c40ba2c98 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -437,12 +437,8 @@ void Mle::GenerateNonce(const Mac::ExtAddress &aMacAddr, uint32_t aFrameCounter, uint8_t *aNonce) { // source address - for (int i = 0; i < 8; i++) - { - aNonce[i] = aMacAddr.mBytes[i]; - } - - aNonce += 8; + memcpy(aNonce, aMacAddr.m8, sizeof(aMacAddr)); + aNonce += sizeof(aMacAddr); // frame counter aNonce[0] = aFrameCounter >> 24;