mirror of
https://github.com/espressif/openthread.git
synced 2026-08-29 21:39:54 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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));
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user