From d309a9579d271fd46fbc2def0f8363c72cb5655e Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 23 Jan 2017 13:24:46 -0800 Subject: [PATCH] New spinel properties to get the "leader" network data (#1191) - Adding two new spinel properties: `THREAD_LEADER_NETWORK_DATA` and `THREAD_STABLE_LEADER_NETWORK_DATA` (read-only) - Add the corresponding `GetHandler` for the two new properties in `NcpBase`. - When a `OT_THREAD_NETDATA_UPDATED` event is received in `NcpBase` in addition to sending `HREAD_ON_MESH_NETS` we also send the full leader network data (this is mainly intended for debugging). --- src/ncp/ncp_base.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++ src/ncp/ncp_base.hpp | 2 ++ src/ncp/spinel.c | 8 +++++++ src/ncp/spinel.h | 12 ++++++++++ 4 files changed, 74 insertions(+) diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 84efb533c..320fa9c9e 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -137,6 +137,8 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = { SPINEL_PROP_THREAD_NETWORK_DATA_VERSION, &NcpBase::GetPropertyHandler_THREAD_NETWORK_DATA_VERSION }, { SPINEL_PROP_THREAD_STABLE_NETWORK_DATA, &NcpBase::GetPropertyHandler_THREAD_STABLE_NETWORK_DATA }, { SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION, &NcpBase::GetPropertyHandler_THREAD_STABLE_NETWORK_DATA_VERSION }, + { SPINEL_PROP_THREAD_LEADER_NETWORK_DATA, &NcpBase::GetPropertyHandler_THREAD_LEADER_NETWORK_DATA }, + { SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA, &NcpBase::GetPropertyHandler_THREAD_STABLE_LEADER_NETWORK_DATA }, { SPINEL_PROP_THREAD_LOCAL_ROUTES, &NcpBase::NcpBase::GetPropertyHandler_THREAD_LOCAL_ROUTES }, { SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::NcpBase::GetPropertyHandler_THREAD_ASSISTING_PORTS }, { SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE, &NcpBase::GetPropertyHandler_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE }, @@ -882,6 +884,11 @@ void NcpBase::UpdateChangedProps(void) SPINEL_PROP_THREAD_ON_MESH_NETS )); + SuccessOrExit(HandleCommandPropertyGet( + SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, + SPINEL_PROP_THREAD_LEADER_NETWORK_DATA + )); + mChangedFlags &= ~static_cast(OT_THREAD_NETDATA_UPDATED); } else if ((mChangedFlags & (OT_IP6_RLOC_ADDED | OT_IP6_RLOC_REMOVED)) != 0) @@ -1985,6 +1992,51 @@ exit: return errorCode; } +ThreadError NcpBase::GetPropertyHandler_THREAD_LEADER_NETWORK_DATA(uint8_t header, spinel_prop_key_t key) +{ + ThreadError errorCode = kThreadError_None; + uint8_t network_data[255]; + uint8_t network_data_len = 255; + + SuccessOrExit(errorCode = OutboundFrameBegin()); + SuccessOrExit(errorCode = OutboundFrameFeedPacked("Cii", header, SPINEL_CMD_PROP_VALUE_IS, key)); + otGetNetworkDataLeader( + mInstance, + false, // Stable? + network_data, + &network_data_len + ); + SuccessOrExit(errorCode = OutboundFrameFeedData(network_data, network_data_len)); + SuccessOrExit(errorCode = OutboundFrameSend()); + +exit: + return errorCode; +} + +ThreadError NcpBase::GetPropertyHandler_THREAD_STABLE_LEADER_NETWORK_DATA(uint8_t header, spinel_prop_key_t key) +{ + ThreadError errorCode = kThreadError_None; + uint8_t network_data[255]; + uint8_t network_data_len = 255; + + + SuccessOrExit(errorCode = OutboundFrameBegin()); + + SuccessOrExit(errorCode = OutboundFrameFeedPacked("Cii", header, SPINEL_CMD_PROP_VALUE_IS, key)); + otGetNetworkDataLeader( + mInstance, + true, // Stable? + network_data, + &network_data_len + ); + + SuccessOrExit(errorCode = OutboundFrameFeedData(network_data, network_data_len)); + SuccessOrExit(errorCode = OutboundFrameSend()); + +exit: + return errorCode; +} + ThreadError NcpBase::GetPropertyHandler_THREAD_LEADER_RID(uint8_t header, spinel_prop_key_t key) { return SendPropertyUpdate( diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 5ec3fe592..c74e6a7b9 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -336,6 +336,8 @@ private: ThreadError GetPropertyHandler_THREAD_NETWORK_DATA_VERSION(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_STABLE_NETWORK_DATA(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_STABLE_NETWORK_DATA_VERSION(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_LEADER_NETWORK_DATA(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_STABLE_LEADER_NETWORK_DATA(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_MAC_PROMISCUOUS_MODE(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_ASSISTING_PORTS(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE(uint8_t header, spinel_prop_key_t key); diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index 90b1508a5..0c1cb8582 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1119,6 +1119,14 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "SPINEL_PROP_THREAD_STABLE_NETWORK_DATA"; break; + case SPINEL_PROP_THREAD_LEADER_NETWORK_DATA: + ret = "SPINEL_PROP_THREAD_LEADER_NETWORK_DATA"; + break; + + case SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA: + ret = "SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA"; + break; + case SPINEL_PROP_THREAD_ON_MESH_NETS: ret = "SPINEL_PROP_THREAD_ON_MESH_NETS"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 019b83361..5932b84c8 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -762,6 +762,18 @@ typedef enum */ SPINEL_PROP_THREAD_CHILD_COUNT_MAX = SPINEL_PROP_THREAD_EXT__BEGIN + 12, + /// Leader network data + /** Format: `D` - Read only + */ + SPINEL_PROP_THREAD_LEADER_NETWORK_DATA + = SPINEL_PROP_THREAD_EXT__BEGIN + 13, + + /// Stable leader network data + /** Format: `D` - Read only + */ + SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA + = SPINEL_PROP_THREAD_EXT__BEGIN + 14, + SPINEL_PROP_THREAD_EXT__END = 0x1600, SPINEL_PROP_IPV6__BEGIN = 0x60,