From fb5faeb6f88a09222db22ecd51ba84f668419cbf Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 21 Dec 2017 10:31:29 -0800 Subject: [PATCH] [ncp] adding CHILD_TABLE_ADDRESSES spinel property and its get handler (#2434) This property provides the list of all addresses associated with every child including any registered IPv6 addresses. --- doc/spinel-protocol-src/spinel-tech-thread.md | 18 ++++++++- include/openthread/ip6.h | 11 ++++++ src/core/api/ip6_api.cpp | 5 +++ src/ncp/ncp_base.cpp | 1 + src/ncp/ncp_base.hpp | 1 + src/ncp/ncp_base_ftd.cpp | 39 +++++++++++++++++++ src/ncp/spinel.c | 4 ++ src/ncp/spinel.h | 20 +++++++++- 8 files changed, 95 insertions(+), 4 deletions(-) diff --git a/doc/spinel-protocol-src/spinel-tech-thread.md b/doc/spinel-protocol-src/spinel-tech-thread.md index c0059b170..43d93adb4 100644 --- a/doc/spinel-protocol-src/spinel-tech-thread.md +++ b/doc/spinel-protocol-src/spinel-tech-thread.md @@ -45,7 +45,7 @@ Table containing info about all the children of this node. Data per item is: -* `E`: Extended/long address +* `E`: Extended address * `S`: RLOC16 * `L`: Timeout (in seconds) * `L`: Age (in seconds) @@ -227,7 +227,7 @@ disabled. Data per item is: -* `E`: Extended/long address +* `E`: Extended address * `S`: RLOC16 * `L`: Age * `C`: Link Quality In @@ -525,3 +525,17 @@ It can only be included in one of the following Dataset properties: * SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET * SPINEL_PROP_THREAD_MGMT_PENDING_DATASET + +### PROP 5409: SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES (#prop-thread-child-table-addresses) + +* Type: Read-Only +* Packing-Encoding: `A(t(ESA(6))` + +This property provides the list of all addresses associated with every child +including any registered IPv6 addresses. + +Data per item is: + +* `E`: Extended address of the child +* `S`: RLOC16 of the child +* `A(6)`: List of IPv6 addresses registered by the child (if any) diff --git a/include/openthread/ip6.h b/include/openthread/ip6.h index da1d64d73..4cf739e14 100644 --- a/include/openthread/ip6.h +++ b/include/openthread/ip6.h @@ -377,6 +377,17 @@ OTAPI otError OTCALL otIp6AddressFromString(const char *aString, otIp6Address *a */ OTAPI uint8_t OTCALL otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond); +/** + * This function indicates whether or not a given IPv6 address is the Unspecified Address. + * + * @param[in] aAddress A pointer to an IPv6 address. + * + * @retval TRUE If the IPv6 address is the Unspecified Address. + * @retval FALSE If the IPv6 address is not the Unspecified Address. + * + */ +bool otIp6IsAddressUnspecified(const otIp6Address *aAddress); + /** * @} * diff --git a/src/core/api/ip6_api.cpp b/src/core/api/ip6_api.cpp index 97b172a53..337e2451a 100644 --- a/src/core/api/ip6_api.cpp +++ b/src/core/api/ip6_api.cpp @@ -254,3 +254,8 @@ uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond exit: return rval; } + +bool otIp6IsAddressUnspecified(const otIp6Address *aAddress) +{ + return static_cast(aAddress)->IsUnspecified(); +} diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 83bb23532..1a5b00e33 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -211,6 +211,7 @@ const NcpBase::PropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = NCP_GET_PROP_HANDLER_ENTRY(NET_PSKC), NCP_GET_PROP_HANDLER_ENTRY(THREAD_LEADER_WEIGHT), NCP_GET_PROP_HANDLER_ENTRY(THREAD_CHILD_TABLE), + NCP_GET_PROP_HANDLER_ENTRY(THREAD_CHILD_TABLE_ADDRESSES), NCP_GET_PROP_HANDLER_ENTRY(THREAD_ROUTER_TABLE), NCP_GET_PROP_HANDLER_ENTRY(THREAD_LOCAL_LEADER_WEIGHT), NCP_GET_PROP_HANDLER_ENTRY(THREAD_ROUTER_ROLE_ENABLED), diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index cd1bf49c0..8b6f1f0cc 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -605,6 +605,7 @@ protected: NCP_SET_PROP_HANDLER(NET_PSKC); NCP_GET_PROP_HANDLER(THREAD_CHILD_TABLE); + NCP_GET_PROP_HANDLER(THREAD_CHILD_TABLE_ADDRESSES); NCP_GET_PROP_HANDLER(THREAD_ROUTER_TABLE); NCP_GET_PROP_HANDLER(THREAD_CHILD_COUNT_MAX); NCP_SET_PROP_HANDLER(THREAD_CHILD_COUNT_MAX); diff --git a/src/ncp/ncp_base_ftd.cpp b/src/ncp/ncp_base_ftd.cpp index 90e1cd909..ba6cc311a 100644 --- a/src/ncp/ncp_base_ftd.cpp +++ b/src/ncp/ncp_base_ftd.cpp @@ -210,6 +210,45 @@ exit: return error; } +otError NcpBase::GetPropertyHandler_THREAD_CHILD_TABLE_ADDRESSES(void) +{ + otError error = OT_ERROR_NONE; + otChildInfo childInfo; + uint8_t maxChildren; + const otIp6Address *ip6Address; + + maxChildren = otThreadGetMaxAllowedChildren(mInstance); + + for (uint8_t childIndex = 0; childIndex < maxChildren; childIndex++) + { + if ((otThreadGetChildInfoByIndex(mInstance, childIndex, &childInfo) != OT_ERROR_NONE) || + childInfo.mIsStateRestoring) + { + continue; + } + + SuccessOrExit(error = mEncoder.OpenStruct()); + + SuccessOrExit(error = mEncoder.WriteEui64(childInfo.mExtAddress)); + SuccessOrExit(error = mEncoder.WriteUint16(childInfo.mRloc16)); + + ip6Address = childInfo.mIp6Addresses; + + for (uint8_t num = childInfo.mIp6AddressesLength; num > 0; num--, ip6Address++) + { + if (!otIp6IsAddressUnspecified(ip6Address)) + { + SuccessOrExit(error = mEncoder.WriteIp6Address(*ip6Address)); + } + } + + SuccessOrExit(error = mEncoder.CloseStruct()); + } + +exit: + return error; +} + otError NcpBase::GetPropertyHandler_THREAD_ROUTER_ROLE_ENABLED(void) { return mEncoder.WriteBool(otThreadIsRouterRoleEnabled(mInstance)); diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index 1078f19c1..5ce711ff4 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1509,6 +1509,10 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_DATASET_RAW_TLVS"; break; + case SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES: + ret = "PROP_THREAD_CHILD_TABLE_ADDRESSES"; + break; + case SPINEL_PROP_IPV6_LL_ADDR: ret = "PROP_IPV6_LL_ADDR"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index f19148b1e..1ad8822c5 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -798,7 +798,7 @@ typedef enum * * Data per item is: * - * `E`: Extended/long address + * `E`: Extended address * `S`: RLOC16 * `L`: Timeout (in seconds) * `L`: Age (in seconds) @@ -955,7 +955,7 @@ typedef enum * * Data per item is: * - * `E`: Extended/long address + * `E`: Extended address * `S`: RLOC16 * `L`: Age (in seconds) * `C`: Link Quality In @@ -1220,6 +1220,22 @@ typedef enum * */ SPINEL_PROP_DATASET_RAW_TLVS = SPINEL_PROP_THREAD_EXT__BEGIN + 32, + + /// Child table addresses + /** Format: `A(t(ESA(6)))` - Read only + * + * This property provides the list of all addresses associated with every child + * including any registered IPv6 addresses. + * + * Data per item is: + * + * `E`: Extended address of the child + * `S`: RLOC16 of the child + * `A(6)`: List of IPv6 addresses registered by the child (if any) + * + */ + SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES + = SPINEL_PROP_THREAD_EXT__BEGIN + 33, SPINEL_PROP_THREAD_EXT__END = 0x1600, SPINEL_PROP_IPV6__BEGIN = 0x60,