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.
diff --git a/examples/platform/posix/radio.cpp b/examples/platform/posix/radio.cpp
index 5aebbee..40a9ffc 100644
--- a/examples/platform/posix/radio.cpp
+++ b/examples/platform/posix/radio.cpp
@@ -61,8 +61,15 @@
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 @@
case kStateListen:
case kStateTransmit:
+ case kStateAckWait:
s_state = kStateIdle;
pthread_cond_signal(&s_condition_variable);
break;
@@ -205,6 +213,7 @@
{
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 @@
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 @@
}
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<Mac::Frame *>(s_transmit_frame)->GetAckRequest())
+ if (reinterpret_cast<Mac::Frame *>(s_transmit_frame)->GetAckRequest())
+ {
+ s_state = kStateAckWait;
+ }
+ else
{
otPlatRadioSignalTransmitDone();
}
@@ -249,7 +264,7 @@
{
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 @@
int length;
uint8_t tx_sequence, rx_sequence;
uint8_t command_id;
+ RadioMessage message;
while (1)
{
@@ -288,7 +304,7 @@
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 @@
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 @@
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 send_ack()
{
Mac::Frame *ack_frame;
+ RadioMessage message;
uint8_t sequence;
struct sockaddr_in sockaddr;
@@ -374,6 +406,9 @@
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 @@
}
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 @@
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<Mac::Frame *>(s_receive_frame);
receive_frame->GetDstAddr(dstaddr);
@@ -425,7 +457,6 @@
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 b4eba39..792ef92 100644
--- a/include/openthread-types.h
+++ b/include/openthread-types.h
@@ -65,6 +65,49 @@
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 98c937b..0729507 100644
--- a/include/openthread.h
+++ b/include/openthread.h
@@ -51,6 +51,7 @@
* @{
*
* @defgroup execution Execution
+ * @defgroup commands Commands
* @defgroup config Configuration
* @defgroup diags Diagnostics
* @defgroup messages Message Buffers
@@ -136,6 +137,57 @@
*/
/**
+ * @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);
+
+/**
+ * @}
+ *
+ */
+
+/**
* @addtogroup config Configuration
*
* @brief
@@ -289,7 +341,7 @@
*
* @sa otSetPanId
*/
-uint16_t otGetPanId(void);
+otPanId otGetPanId(void);
/**
* Set the IEEE 802.15.4 PAN ID.
@@ -301,7 +353,34 @@
*
* @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);
/**
* @}
@@ -731,47 +810,6 @@
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
*
* @brief
diff --git a/src/cli/README.md b/src/cli/README.md
index 080a71c..2063a10 100644
--- a/src/cli/README.md
+++ b/src/cli/README.md
@@ -27,6 +27,7 @@
* [rloc16](#rloc16)
* [route](#route)
* [routerupgradethreshold](#routerupgradethreshold)
+* [scan](#scan)
* [start](#start)
* [state](#state)
* [stop](#stop)
@@ -396,6 +397,20 @@
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 626c6df..10a6ac8 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -69,6 +69,7 @@
{ "rloc16", &ProcessRloc16 },
{ "route", &ProcessRoute },
{ "routerupgradethreshold", &ProcessRouterUpgradeThreshold },
+ { "scan", &ProcessScan },
{ "shutdown", &ProcessShutdown },
{ "start", &ProcessStart },
{ "state", &ProcessState },
@@ -167,7 +168,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessChildTimeout(int argc, char *argv[])
@@ -187,7 +188,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessContextIdReuseDelay(int argc, char *argv[])
@@ -207,7 +208,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessExtAddress(int argc, char *argv[])
@@ -240,7 +241,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
ThreadError Interpreter::ProcessIpAddrAdd(int argc, char *argv[])
@@ -302,7 +303,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessKeySequence(int argc, char *argv[])
@@ -322,7 +323,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessLeaderWeight(int argc, char *argv[])
@@ -342,7 +343,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessMasterKey(int argc, char *argv[])
@@ -371,7 +372,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessMode(int argc, char *argv[])
@@ -437,7 +438,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessNetworkDataRegister(int argc, char *argv[])
@@ -446,7 +447,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessNetworkIdTimeout(int argc, char *argv[])
@@ -466,7 +467,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessNetworkName(int argc, char *argv[])
@@ -483,7 +484,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessPanId(int argc, char *argv[])
@@ -503,7 +504,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::HandleEchoResponse(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
@@ -544,7 +545,7 @@
sResponse.Init();
exit:
- {}
+ return;
}
ThreadError Interpreter::ProcessPrefixAdd(int argc, char *argv[])
@@ -685,7 +686,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessReleaseRouterId(int argc, char *argv[])
@@ -700,7 +701,7 @@
}
exit:
- {}
+ return;
}
void Interpreter::ProcessRloc16(int argc, char *argv[])
@@ -819,7 +820,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessRouterUpgradeThreshold(int argc, char *argv[])
@@ -839,7 +840,72 @@
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 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessState(int argc, char *argv[])
@@ -913,7 +979,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessStop(int argc, char *argv[])
@@ -922,7 +988,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessWhitelist(int argc, char *argv[])
@@ -973,7 +1039,7 @@
sResponse.Append("Done\r\n");
exit:
- {}
+ return;
}
void Interpreter::ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer)
@@ -1012,7 +1078,7 @@
}
exit:
- {}
+ return;
}
} // namespace Cli
diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp
index a34990d..f7b78cb 100644
--- a/src/cli/cli.hpp
+++ b/src/cli/cli.hpp
@@ -159,6 +159,7 @@
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 @@
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 499db7b..f847db3 100644
--- a/src/core/mac/mac.cpp
+++ b/src/core/mac/mac.cpp
@@ -85,11 +85,12 @@
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 @@
for (size_t i = 0; i < sizeof(mExtAddress); i++)
{
- mExtAddress.mBytes[i] = otPlatRandomGet();
+ mExtAddress.m8[i] = otPlatRandomGet();
}
SetExtendedPanId(sExtendedPanidInit);
@@ -121,7 +122,7 @@
SuccessOrExit(error = otPlatRadioEnable());
- SetExtendedPanId(mExtendedPanid);
+ SetExtendedPanId(mBeacon.GetExtendedPanId());
otPlatRadioSetPanId(mPanId);
otPlatRadioSetShortAddress(mShortAddress);
{
@@ -129,7 +130,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
else if (mTransmitBeacon)
{
mTransmitBeacon = false;
- assert(false);
mState = kStateTransmitBeacon;
StartCsmaBackoff();
}
@@ -386,7 +384,7 @@
// 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::SendBeacon(Frame &aFrame)
{
- uint8_t *payload;
uint16_t fcf;
// initialize MAC header
@@ -426,38 +423,8 @@
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 @@
switch (mState)
{
case kStateActiveScan:
- mAckTimer.Start(mScanIntervalPerChannel);
+ mAckTimer.Start(mScanDuration);
break;
case kStateTransmitBeacon:
@@ -634,17 +601,17 @@
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 @@
switch (mState)
{
case kStateActiveScan:
- mAckTimer.Start(mScanIntervalPerChannel);
+ mAckTimer.Start(mScanDuration);
break;
case kStateTransmitBeacon:
@@ -908,7 +875,7 @@
switch (mState)
{
case kStateActiveScan:
- HandleBeaconFrame();
+ mActiveScanHandler(mActiveScanContext, &mReceiveFrame);
break;
default:
@@ -934,71 +901,6 @@
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<char*>(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 @@
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 e6118c7..9215074 100644
--- a/src/core/mac/mac.hpp
+++ b/src/core/mac/mac.hpp
@@ -65,36 +65,19 @@
*/
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 @@
/**
* 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 @@
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 @@
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 @@
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 a766f94..16b5271 100644
--- a/src/core/mac/mac_frame.cpp
+++ b/src/core/mac/mac_frame.cpp
@@ -41,8 +41,8 @@
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 @@
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 @@
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 @@
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 @@
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 e153619..a88c5f6 100644
--- a/src/core/mac/mac_frame.hpp
+++ b/src/core/mac/mac_frame.hpp
@@ -36,7 +36,9 @@
#include <limits.h>
#include <stdint.h>
+#include <string.h>
+#include <common/encoding.hpp>
#include <openthread-types.h>
#include <platform/radio.h>
@@ -64,19 +66,19 @@
* 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 @@
*
*/
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.
};
/**
@@ -585,6 +581,157 @@
};
/**
+ * 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 89f0324..273287e 100644
--- a/src/core/net/ip6_address.cpp
+++ b/src/core/net/ip6_address.cpp
@@ -116,7 +116,7 @@
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 a58d035..385ff80 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 ThreadNetif *sThreadNetif;
-#ifdef __cplusplus
-extern "C" {
-#endif
+static void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame);
void otInit()
{
@@ -184,12 +186,12 @@
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 @@
return sThreadNetif->Down();
}
+ThreadError otActiveScan(uint16_t aScanChannels, uint16_t aScanDuration, otHandleActiveScanResult aCallback)
+{
+ return sThreadNetif->GetMac().ActiveScan(aScanChannels, aScanDuration, &HandleActiveScanResult,
+ reinterpret_cast<void *>(aCallback));
+}
+
+void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame)
+{
+ otHandleActiveScanResult handler = reinterpret_cast<otHandleActiveScanResult>(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<Mac::Beacon *>(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 3d184c1..446e8a0 100644
--- a/src/core/thread/address_resolver.cpp
+++ b/src/core/thread/address_resolver.cpp
@@ -409,7 +409,7 @@
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 @@
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 1b54463..c40ba2c 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -437,12 +437,8 @@
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;