mirror of
https://github.com/espressif/openthread.git
synced 2026-10-10 09:47:35 +00:00
Add API to retrieve child diag information. (#226)
This commit is contained in:
+31
-11
@@ -395,21 +395,41 @@ typedef enum
|
||||
} otDeviceRole;
|
||||
|
||||
/**
|
||||
* This structure holds diagnostics information for a Thread Router
|
||||
* This structure holds diagnostic information for a Thread Child
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
otExtAddress mExtAddress; ///< IEEE 802.15.4 Extended Address
|
||||
uint16_t mRloc16; ///< RLOC16
|
||||
uint8_t mRouterId; ///< Router ID
|
||||
uint8_t mNextHop; ///< Next hop to router
|
||||
uint8_t mPathCost; ///< Path cost to router
|
||||
uint8_t mLinkQualityIn; ///< Link Quality In
|
||||
uint8_t mLinkQualityOut; ///< Link Quality Out
|
||||
uint8_t mAge; ///< Time last heard
|
||||
bool mAllocated : 1; ///< Router ID allocated or not
|
||||
bool mLinkEstablished : 1; ///< Link established with Router ID or not
|
||||
otExtAddress mExtAddress; ///< IEEE 802.15.4 Extended Address
|
||||
uint32_t mTimeout; ///< Timeout
|
||||
uint16_t mRloc16; ///< RLOC16
|
||||
uint8_t mChildId; ///< Router ID
|
||||
uint8_t mNetworkDataVersion; ///< Network Data Version
|
||||
uint8_t mAge; ///< Time last heard
|
||||
uint8_t mLinkQualityIn; ///< Link Quality In
|
||||
int8_t mAverageRssi; ///< Average RSSI
|
||||
bool mRxOnWhenIdle : 1; ///< rx-on-when-idle
|
||||
bool mSecureDataRequest : 1; ///< Secure Data Requests
|
||||
bool mFullFunction : 1; ///< Full Function Device
|
||||
bool mFullNetworkData : 1; ///< Full Network Data
|
||||
} otChildInfo;
|
||||
|
||||
/**
|
||||
* This structure holds diagnostic information for a Thread Router
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
otExtAddress mExtAddress; ///< IEEE 802.15.4 Extended Address
|
||||
uint16_t mRloc16; ///< RLOC16
|
||||
uint8_t mRouterId; ///< Router ID
|
||||
uint8_t mNextHop; ///< Next hop to router
|
||||
uint8_t mPathCost; ///< Path cost to router
|
||||
uint8_t mLinkQualityIn; ///< Link Quality In
|
||||
uint8_t mLinkQualityOut; ///< Link Quality Out
|
||||
uint8_t mAge; ///< Time last heard
|
||||
bool mAllocated : 1; ///< Router ID allocated or not
|
||||
bool mLinkEstablished : 1; ///< Link established with Router ID or not
|
||||
} otRouterInfo;
|
||||
|
||||
/**
|
||||
|
||||
@@ -854,6 +854,24 @@ ThreadError otBecomeLeader(void);
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function retains diagnostic information for an attached Child by its Child ID or RLOC16.
|
||||
*
|
||||
* @param[in] aChildId The Child ID or RLOC16 for the attached child.
|
||||
* @param[out] aChildInfo A pointer to where the child information is placed.
|
||||
*
|
||||
*/
|
||||
ThreadError otGetChildInfoById(uint16_t aChildId, otChildInfo *aChildInfo);
|
||||
|
||||
/**
|
||||
* The function retains diagnostic information for an attached Child by the internal table index.
|
||||
*
|
||||
* @param[in] aChildIndex The table index.
|
||||
* @param[out] aChildInfo A pointer to where the child information is placed.
|
||||
*
|
||||
*/
|
||||
ThreadError otGetChildInfoByIndex(uint8_t aChildIndex, otChildInfo *aChildInfo);
|
||||
|
||||
/**
|
||||
* Get the device role.
|
||||
*
|
||||
|
||||
@@ -8,6 +8,7 @@ OpenThread test scripts use the CLI to execute test cases.
|
||||
## OpenThread Command List
|
||||
|
||||
* [channel](#channel)
|
||||
* [child](#child)
|
||||
* [childtimeout](#childtimeout)
|
||||
* [contextreusedelay](#contextreusedelay)
|
||||
* [counter](#counter)
|
||||
@@ -56,6 +57,34 @@ Set the IEEE 802.15.4 Channel value.
|
||||
Done
|
||||
```
|
||||
|
||||
### child list
|
||||
|
||||
List attached Child IDs
|
||||
|
||||
```bash
|
||||
> child list
|
||||
1 2 3 6 7 8
|
||||
Done
|
||||
```
|
||||
|
||||
### child \<id\>
|
||||
|
||||
Print diagnostic information for an attached Thread Child. The `id` may be a Child ID or an RLOC16.
|
||||
|
||||
```bash
|
||||
> child 1
|
||||
Child ID: 1
|
||||
Rloc: 9c01
|
||||
Ext Addr: e2b3540590b0fd87
|
||||
Mode: rsn
|
||||
Net Data: 184
|
||||
Timeout: 100
|
||||
Age: 0
|
||||
LQI: 3
|
||||
RSSI: -20
|
||||
Done
|
||||
```
|
||||
|
||||
### childtimeout
|
||||
|
||||
Get the Thread Child Timeout value.
|
||||
|
||||
@@ -51,6 +51,7 @@ const struct Command Interpreter::sCommands[] =
|
||||
{
|
||||
{ "help", &ProcessHelp },
|
||||
{ "channel", &ProcessChannel },
|
||||
{ "child", &ProcessChild },
|
||||
{ "childtimeout", &ProcessChildTimeout },
|
||||
{ "contextreusedelay", &ProcessContextIdReuseDelay },
|
||||
{ "counter", &ProcessCounters },
|
||||
@@ -186,6 +187,78 @@ exit:
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
void Interpreter::ProcessChild(int argc, char *argv[])
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
otChildInfo childInfo;
|
||||
long value;
|
||||
|
||||
VerifyOrExit(argc > 0, error = kThreadError_Parse);
|
||||
|
||||
if (strcmp(argv[0], "list") == 0)
|
||||
{
|
||||
for (int i = 0; ; i++)
|
||||
{
|
||||
if (otGetChildInfoByIndex(i, &childInfo) != kThreadError_None)
|
||||
{
|
||||
sServer->OutputFormat("\r\n");
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
if (childInfo.mTimeout > 0)
|
||||
{
|
||||
sServer->OutputFormat("%d ", childInfo.mChildId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(error = ParseLong(argv[0], value));
|
||||
SuccessOrExit(error = otGetChildInfoById(value, &childInfo));
|
||||
|
||||
sServer->OutputFormat("Child ID: %d\r\n", childInfo.mChildId);
|
||||
sServer->OutputFormat("Rloc: %04x\r\n", childInfo.mRloc16);
|
||||
sServer->OutputFormat("Ext Addr: ");
|
||||
|
||||
for (int j = 0; j < sizeof(childInfo.mExtAddress); j++)
|
||||
{
|
||||
sServer->OutputFormat("%02x", childInfo.mExtAddress.m8[j]);
|
||||
}
|
||||
|
||||
sServer->OutputFormat("\r\n");
|
||||
sServer->OutputFormat("Mode: ");
|
||||
|
||||
if (childInfo.mRxOnWhenIdle)
|
||||
{
|
||||
sServer->OutputFormat("r");
|
||||
}
|
||||
|
||||
if (childInfo.mSecureDataRequest)
|
||||
{
|
||||
sServer->OutputFormat("s");
|
||||
}
|
||||
|
||||
if (childInfo.mFullFunction)
|
||||
{
|
||||
sServer->OutputFormat("d");
|
||||
}
|
||||
|
||||
if (childInfo.mFullNetworkData)
|
||||
{
|
||||
sServer->OutputFormat("n");
|
||||
}
|
||||
|
||||
sServer->OutputFormat("\r\n");
|
||||
|
||||
sServer->OutputFormat("Net Data: %d\r\n", childInfo.mNetworkDataVersion);
|
||||
sServer->OutputFormat("Timeout: %d\r\n", childInfo.mTimeout);
|
||||
sServer->OutputFormat("Age: %d\r\n", childInfo.mAge);
|
||||
sServer->OutputFormat("LQI: %d\r\n", childInfo.mLinkQualityIn);
|
||||
sServer->OutputFormat("RSSI: %d\r\n", childInfo.mAverageRssi);
|
||||
|
||||
exit:
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
void Interpreter::ProcessChildTimeout(int argc, char *argv[])
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
@@ -88,6 +88,7 @@ private:
|
||||
|
||||
static void ProcessHelp(int argc, char *argv[]);
|
||||
static void ProcessChannel(int argc, char *argv[]);
|
||||
static void ProcessChild(int argc, char *argv[]);
|
||||
static void ProcessChildTimeout(int argc, char *argv[]);
|
||||
static void ProcessContextIdReuseDelay(int argc, char *argv[]);
|
||||
static void ProcessCounters(int argc, char *argv[]);
|
||||
|
||||
@@ -454,6 +454,30 @@ ThreadError otBecomeLeader(void)
|
||||
return sThreadNetif->GetMle().BecomeLeader();
|
||||
}
|
||||
|
||||
ThreadError otGetChildInfoById(uint16_t aChildId, otChildInfo *aChildInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aChildInfo != NULL, error = kThreadError_InvalidArgs);
|
||||
|
||||
error = sThreadNetif->GetMle().GetChildInfoById(aChildId, *aChildInfo);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError otGetChildInfoByIndex(uint8_t aChildIndex, otChildInfo *aChildInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aChildInfo != NULL, error = kThreadError_InvalidArgs);
|
||||
|
||||
error = sThreadNetif->GetMle().GetChildInfoByIndex(aChildIndex, *aChildInfo);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otDeviceRole otGetDeviceRole(void)
|
||||
{
|
||||
otDeviceRole rval = kDeviceRoleDisabled;
|
||||
|
||||
@@ -976,6 +976,23 @@ Child *MleRouter::NewChild(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Child *MleRouter::FindChild(uint16_t aChildId)
|
||||
{
|
||||
Child *rval = NULL;
|
||||
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
{
|
||||
if (mChildren[i].mState != Neighbor::kStateInvalid &&
|
||||
GetChildId(mChildren[i].mValid.mRloc16) == aChildId)
|
||||
{
|
||||
ExitNow(rval = &mChildren[i]);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
Child *MleRouter::FindChild(const Mac::ExtAddress &aAddress)
|
||||
{
|
||||
Child *rval = NULL;
|
||||
@@ -2252,6 +2269,56 @@ Router *MleRouter::GetRouters(uint8_t *aNumRouters)
|
||||
return mRouters;
|
||||
}
|
||||
|
||||
ThreadError MleRouter::GetChildInfoById(uint16_t aChildId, otChildInfo &aChildInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Child *child;
|
||||
|
||||
if ((aChildId & ~kChildIdMask) != 0)
|
||||
{
|
||||
aChildId = GetChildId(aChildId);
|
||||
}
|
||||
|
||||
VerifyOrExit((child = FindChild(aChildId)) != NULL, error = kThreadError_NotFound);
|
||||
GetChildInfo(*child, aChildInfo);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError MleRouter::GetChildInfoByIndex(uint8_t aChildIndex, otChildInfo &aChildInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aChildIndex < kMaxChildren, error = kThreadError_InvalidArgs);
|
||||
GetChildInfo(mChildren[aChildIndex], aChildInfo);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void MleRouter::GetChildInfo(Child &aChild, otChildInfo &aChildInfo)
|
||||
{
|
||||
memset(&aChildInfo, 0, sizeof(aChildInfo));
|
||||
|
||||
if (aChild.mState == Neighbor::kStateValid)
|
||||
{
|
||||
memcpy(&aChildInfo.mExtAddress, &aChild.mMacAddr, sizeof(aChildInfo.mExtAddress));
|
||||
aChildInfo.mTimeout = aChild.mTimeout;
|
||||
aChildInfo.mRloc16 = aChild.mValid.mRloc16;
|
||||
aChildInfo.mChildId = GetChildId(aChild.mValid.mRloc16);
|
||||
aChildInfo.mNetworkDataVersion = aChild.mNetworkDataVersion;
|
||||
aChildInfo.mAge = Timer::MsecToSec(Timer::GetNow() - aChild.mLastHeard);
|
||||
aChildInfo.mLinkQualityIn = aChild.mLinkInfo.GetLinkQuality();
|
||||
aChildInfo.mAverageRssi = aChild.mLinkInfo.GetAverageRss();
|
||||
|
||||
aChildInfo.mRxOnWhenIdle = (aChild.mMode & ModeTlv::kModeRxOnWhenIdle) != 0;
|
||||
aChildInfo.mSecureDataRequest = (aChild.mMode & ModeTlv::kModeSecureDataRequest) != 0;
|
||||
aChildInfo.mFullFunction = (aChild.mMode & ModeTlv::kModeFFD) != 0;
|
||||
aChildInfo.mFullNetworkData = (aChild.mMode & ModeTlv::kModeFullNetworkData) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadError MleRouter::GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
@@ -279,6 +279,24 @@ public:
|
||||
*/
|
||||
Neighbor *GetNeighbor(const Ip6::Address &aAddress);
|
||||
|
||||
/**
|
||||
* This method retains diagnotsic information for an attached child by Child ID or RLOC16.
|
||||
*
|
||||
* @param[in] aChildId The Child ID or RLOC16 for an attached child.
|
||||
* @param[out] aChildInfo The child information.
|
||||
*
|
||||
*/
|
||||
ThreadError GetChildInfoById(uint16_t aChildId, otChildInfo &aChildInfo);
|
||||
|
||||
/**
|
||||
* This method retains diagnotsic information for an attached child by the internal table index.
|
||||
*
|
||||
* @param[in] aChildIndex The table index.
|
||||
* @param[out] aChildInfo The child information.
|
||||
*
|
||||
*/
|
||||
ThreadError GetChildInfoByIndex(uint8_t aChildIndex, otChildInfo &aChildInfo);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Router array.
|
||||
*
|
||||
@@ -340,6 +358,7 @@ private:
|
||||
ThreadError AppendChildAddresses(Message &aMessage, Child &aChild);
|
||||
ThreadError AppendRoute(Message &aMessage);
|
||||
uint8_t GetLinkCost(uint8_t aRouterId);
|
||||
void GetChildInfo(Child &aChild, otChildInfo &aChildInfo);
|
||||
ThreadError HandleDetachStart(void);
|
||||
ThreadError HandleChildStart(otMleAttachFilter aFilter);
|
||||
ThreadError HandleLinkRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
@@ -388,6 +407,7 @@ private:
|
||||
static uint8_t LqiToCost(uint8_t aLqi);
|
||||
|
||||
Child *NewChild(void);
|
||||
Child *FindChild(uint16_t aChildId);
|
||||
Child *FindChild(const Mac::ExtAddress &aMacAddr);
|
||||
|
||||
int AllocateRouterId(void);
|
||||
|
||||
Reference in New Issue
Block a user