Add API to retrieve child diag information. (#226)

This commit is contained in:
Jonathan Hui
2016-07-01 12:10:52 -07:00
committed by GitHub
parent 50acd07a17
commit 510f1d57f1
8 changed files with 263 additions and 11 deletions
+31 -11
View File
@@ -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;
/**
+18
View File
@@ -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.
*
+29
View File
@@ -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.
+73
View File
@@ -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;
+1
View File
@@ -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[]);
+24
View File
@@ -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;
+67
View File
@@ -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;
+20
View File
@@ -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);