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.
This commit is contained in:
Jonathan Hui
2016-05-13 15:14:04 -07:00
parent baa8994190
commit 1f24fa44fa
14 changed files with 546 additions and 278 deletions
+42 -11
View File
@@ -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<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 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<Mac::Frame *>(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
+43
View File
@@ -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
*
+81 -43
View File
@@ -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
*
+15
View File
@@ -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.
+89 -23
View File
@@ -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
+2
View File
@@ -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);
+29 -128
View File
@@ -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<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 @@ ThreadError Mac::HandleMacCommand(void)
if (mState == kStateIdle)
{
assert(false);
mState = kStateTransmitBeacon;
mTransmitBeacon = false;
mBeginTransmit.Post();
StartCsmaBackoff();
}
ExitNow(error = kThreadError_Drop);
+23 -42
View File
@@ -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;
+6 -6
View File
@@ -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;
+156 -9
View File
@@ -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 @@ 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));
/**
* @}
*
+1 -1
View File
@@ -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;
}
+53 -5
View File
@@ -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<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);
+4 -4
View File
@@ -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();
+2 -6
View File
@@ -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;