mirror of
https://github.com/espressif/openthread.git
synced 2026-07-31 08:07:47 +00:00
[netdata] new API to get lowpan context IDs (#8870)
This commit adds `otNetDataGetNextLowpanContextInfo()` to iterate through the list of LoWPAN Context entries in Thread Network Data providing info about the prefix, its LoWPAN Context ID and Compress flag (relating to `ContextTlv` sub-TLVs of `PrefixTlv`s in Network Data). This commit also updates CLI command `netdata show` to list the context IDs in addition to prefixes, routes, and services.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (301)
|
||||
#define OPENTHREAD_API_VERSION (302)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -71,6 +71,17 @@ typedef struct otBorderRouterConfig
|
||||
uint16_t mRloc16; ///< The border router's RLOC16 (value ignored on config add).
|
||||
} otBorderRouterConfig;
|
||||
|
||||
/**
|
||||
* This structure represents 6LoWPAN Context ID information associated with a prefix in Network Data.
|
||||
*
|
||||
*/
|
||||
typedef struct otLowpanContextInfo
|
||||
{
|
||||
uint8_t mContextId; ///< The 6LoWPAN Context ID.
|
||||
bool mCompressFlag; ///< The compress flag.
|
||||
otIp6Prefix mPrefix; ///< The associated IPv6 prefix.
|
||||
} otLowpanContextInfo;
|
||||
|
||||
/**
|
||||
* This structure represents an External Route configuration.
|
||||
*
|
||||
@@ -214,6 +225,22 @@ otError otNetDataGetNextRoute(otInstance *aInstance, otNetworkDataIterator *aIte
|
||||
*/
|
||||
otError otNetDataGetNextService(otInstance *aInstance, otNetworkDataIterator *aIterator, otServiceConfig *aConfig);
|
||||
|
||||
/**
|
||||
* Get the next 6LoWPAN Context ID info in the partition's Network Data.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in,out] aIterator A pointer to the Network Data iterator. To get the first service entry
|
||||
it should be set to OT_NETWORK_DATA_ITERATOR_INIT.
|
||||
* @param[out] aContextInfo A pointer to where the retrieved 6LoWPAN Context ID information will be placed.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully found the next 6LoWPAN Context ID info.
|
||||
* @retval OT_ERROR_NOT_FOUND No subsequent 6LoWPAN Context info exists in the partition's Network Data.
|
||||
*
|
||||
*/
|
||||
otError otNetDataGetNextLowpanContextInfo(otInstance *aInstance,
|
||||
otNetworkDataIterator *aIterator,
|
||||
otLowpanContextInfo *aContextInfo);
|
||||
|
||||
/**
|
||||
* Get the Network Data Version.
|
||||
*
|
||||
|
||||
@@ -284,14 +284,61 @@ Done
|
||||
|
||||
Usage: `netdata show [local] [-x]`
|
||||
|
||||
Print entries in Network Data, on-mesh prefixes, external routes, services, and 6LoWPAN context information.
|
||||
|
||||
On-mesh prefixes are listed under `Prefixes` header:
|
||||
|
||||
- The on-mesh prefix
|
||||
- Flags
|
||||
- p: Preferred flag
|
||||
- a: Stateless IPv6 Address Autoconfiguration flag
|
||||
- d: DHCPv6 IPv6 Address Configuration flag
|
||||
- c: DHCPv6 Other Configuration flag
|
||||
- r: Default Route flag
|
||||
- o: On Mesh flag
|
||||
- s: Stable flag
|
||||
- n: Nd Dns flag
|
||||
- D: Domain Prefix flag (only available for Thread 1.2).
|
||||
- Preference `high`, `med`, or `low`
|
||||
- RLOC16 of device which added the on-mesh prefix
|
||||
|
||||
External Routes are listed under `Routes` header:
|
||||
|
||||
- The route prefix
|
||||
- Flags
|
||||
- s: Stable flag
|
||||
- n: NAT64 flag
|
||||
- Preference `high`, `med`, or `low`
|
||||
- RLOC16 of device which added the route prefix
|
||||
|
||||
Service entries are listed under `Services` header:
|
||||
|
||||
- Enterprise number
|
||||
- Service data (as hex bytes)
|
||||
- Server data (as hex bytes)
|
||||
- Flags
|
||||
- s: Stable flag
|
||||
- RLOC16 of devices which added the service entry
|
||||
|
||||
6LoWPAN Context IDs are listed under `Contexts` header:
|
||||
|
||||
- The prefix
|
||||
- Context ID
|
||||
- Compress flag (`c` if marked or `-` otherwise).
|
||||
|
||||
Print Network Data received from the Leader.
|
||||
|
||||
```bash
|
||||
> netdata show
|
||||
Prefixes:
|
||||
fd00:dead:beef:cafe::/64 paros med dc00
|
||||
fd00:dead:beef:cafe::/64 paros med a000
|
||||
Routes:
|
||||
fd00:1234:0:0::/64 s med a000
|
||||
fd00:4567:0:0::/64 s med 8000
|
||||
Services:
|
||||
44970 5d fddead00beef00007bad0069ce45948504d2 s a000
|
||||
Contexts:
|
||||
fd00:dead:beef:cafe::/64 1 c
|
||||
Done
|
||||
```
|
||||
|
||||
|
||||
@@ -606,6 +606,25 @@ void NetworkData::OutputServices(bool aLocal)
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkData::OutputLowpanContexts(bool aLocal)
|
||||
{
|
||||
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
otLowpanContextInfo info;
|
||||
|
||||
VerifyOrExit(!aLocal);
|
||||
|
||||
OutputLine("Contexts:");
|
||||
|
||||
while (otNetDataGetNextLowpanContextInfo(GetInstancePtr(), &iterator, &info) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputIp6Prefix(info.mPrefix);
|
||||
OutputLine(" %u %c", info.mContextId, info.mCompressFlag ? 'c' : '-');
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError NetworkData::OutputBinary(bool aLocal)
|
||||
{
|
||||
otError error;
|
||||
@@ -643,6 +662,8 @@ exit:
|
||||
* Services:
|
||||
* 44970 5d c000 s 4000
|
||||
* 44970 01 9a04b000000e10 s 4000
|
||||
* Contexts:
|
||||
* fd00:dead:beef:cafe::/64 1 c
|
||||
* Done
|
||||
* @endcode
|
||||
* @code
|
||||
@@ -655,7 +676,43 @@ exit:
|
||||
* @par
|
||||
* `netdata show` from OT CLI gets full Network Data received from the Leader. This command uses several
|
||||
* API functions to combine prefixes, routes, and services, including #otNetDataGetNextOnMeshPrefix,
|
||||
* #otNetDataGetNextRoute, and #otNetDataGetNextService.
|
||||
* #otNetDataGetNextRoute, #otNetDataGetNextService and #otNetDataGetNextLowpanContextInfo.
|
||||
* @par
|
||||
* On-mesh prefixes are listed under `Prefixes` header:
|
||||
* * The on-mesh prefix
|
||||
* * Flags
|
||||
* * p: Preferred flag
|
||||
* * a: Stateless IPv6 Address Autoconfiguration flag
|
||||
* * d: DHCPv6 IPv6 Address Configuration flag
|
||||
* * c: DHCPv6 Other Configuration flag
|
||||
* * r: Default Route flag
|
||||
* * o: On Mesh flag
|
||||
* * s: Stable flag
|
||||
* * n: Nd Dns flag
|
||||
* * D: Domain Prefix flag (only available for Thread 1.2).
|
||||
* * Preference `high`, `med`, or `low`
|
||||
* * RLOC16 of device which added the on-mesh prefix
|
||||
* @par
|
||||
* External Routes are listed under `Routes` header:
|
||||
* * The route prefix
|
||||
* * Flags
|
||||
* * s: Stable flag
|
||||
* * n: NAT64 flag
|
||||
* * Preference `high`, `med`, or `low`
|
||||
* * RLOC16 of device which added the route prefix
|
||||
* @par
|
||||
* Service entries are listed under `Services` header:
|
||||
* * Enterprise number
|
||||
* * Service data (as hex bytes)
|
||||
* * Server data (as hex bytes)
|
||||
* * Flags
|
||||
* * s: Stable flag
|
||||
* * RLOC16 of devices which added the service entry
|
||||
* @par
|
||||
* 6LoWPAN Context IDs are listed under `Contexts` header:
|
||||
* * The prefix
|
||||
* * Context ID
|
||||
* * Compress flag (`c` if marked or `-` otherwise).
|
||||
* @par
|
||||
* @moreinfo{@netdata}.
|
||||
* @csa{br omrprefix}
|
||||
@@ -714,6 +771,7 @@ template <> otError NetworkData::Process<Cmd("show")>(Arg aArgs[])
|
||||
OutputPrefixes(local);
|
||||
OutputRoutes(local);
|
||||
OutputServices(local);
|
||||
OutputLowpanContexts(local);
|
||||
error = OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ private:
|
||||
void OutputPrefixes(bool aLocal);
|
||||
void OutputRoutes(bool aLocal);
|
||||
void OutputServices(bool aLocal);
|
||||
void OutputLowpanContexts(bool aLocal);
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
|
||||
@@ -94,6 +94,16 @@ otError otNetDataGetNextService(otInstance *aInstance, otNetworkDataIterator *aI
|
||||
return AsCoreType(aInstance).Get<NetworkData::Leader>().GetNextService(*aIterator, AsCoreType(aConfig));
|
||||
}
|
||||
|
||||
otError otNetDataGetNextLowpanContextInfo(otInstance *aInstance,
|
||||
otNetworkDataIterator *aIterator,
|
||||
otLowpanContextInfo *aContextInfo)
|
||||
{
|
||||
AssertPointerIsNotNull(aIterator);
|
||||
|
||||
return AsCoreType(aInstance).Get<NetworkData::Leader>().GetNextLowpanContextInfo(*aIterator,
|
||||
AsCoreType(aContextInfo));
|
||||
}
|
||||
|
||||
uint8_t otNetDataGetVersion(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Mle::MleRouter>().GetLeaderData().GetDataVersion(NetworkData::kFullSet);
|
||||
|
||||
@@ -92,6 +92,7 @@ Error NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, On
|
||||
config.mOnMeshPrefix = &aConfig;
|
||||
config.mExternalRoute = nullptr;
|
||||
config.mService = nullptr;
|
||||
config.mLowpanContext = nullptr;
|
||||
|
||||
return Iterate(aIterator, aRloc16, config);
|
||||
}
|
||||
@@ -108,6 +109,7 @@ Error NetworkData::GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, E
|
||||
config.mOnMeshPrefix = nullptr;
|
||||
config.mExternalRoute = &aConfig;
|
||||
config.mService = nullptr;
|
||||
config.mLowpanContext = nullptr;
|
||||
|
||||
return Iterate(aIterator, aRloc16, config);
|
||||
}
|
||||
@@ -124,10 +126,23 @@ Error NetworkData::GetNextService(Iterator &aIterator, uint16_t aRloc16, Service
|
||||
config.mOnMeshPrefix = nullptr;
|
||||
config.mExternalRoute = nullptr;
|
||||
config.mService = &aConfig;
|
||||
config.mLowpanContext = nullptr;
|
||||
|
||||
return Iterate(aIterator, aRloc16, config);
|
||||
}
|
||||
|
||||
Error NetworkData::GetNextLowpanContextInfo(Iterator &aIterator, LowpanContextInfo &aContextInfo) const
|
||||
{
|
||||
Config config;
|
||||
|
||||
config.mOnMeshPrefix = nullptr;
|
||||
config.mExternalRoute = nullptr;
|
||||
config.mService = nullptr;
|
||||
config.mLowpanContext = &aContextInfo;
|
||||
|
||||
return Iterate(aIterator, Mac::kShortAddrBroadcast, config);
|
||||
}
|
||||
|
||||
Error NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const
|
||||
{
|
||||
// Iterate to the next entry in Network Data matching `aRloc16`
|
||||
@@ -152,7 +167,8 @@ Error NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfi
|
||||
switch (cur->GetType())
|
||||
{
|
||||
case NetworkDataTlv::kTypePrefix:
|
||||
if ((aConfig.mOnMeshPrefix != nullptr) || (aConfig.mExternalRoute != nullptr))
|
||||
if ((aConfig.mOnMeshPrefix != nullptr) || (aConfig.mExternalRoute != nullptr) ||
|
||||
(aConfig.mLowpanContext != nullptr))
|
||||
{
|
||||
subTlvs = As<PrefixTlv>(cur)->GetSubTlvs();
|
||||
}
|
||||
@@ -199,6 +215,7 @@ Error NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfi
|
||||
|
||||
aConfig.mExternalRoute = nullptr;
|
||||
aConfig.mService = nullptr;
|
||||
aConfig.mLowpanContext = nullptr;
|
||||
aConfig.mOnMeshPrefix->SetFrom(*prefixTlv, *borderRouter, *borderRouterEntry);
|
||||
|
||||
ExitNow(error = kErrorNone);
|
||||
@@ -223,8 +240,9 @@ Error NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfi
|
||||
{
|
||||
const HasRouteEntry *hasRouteEntry = hasRoute->GetEntry(index);
|
||||
|
||||
aConfig.mOnMeshPrefix = nullptr;
|
||||
aConfig.mService = nullptr;
|
||||
aConfig.mOnMeshPrefix = nullptr;
|
||||
aConfig.mService = nullptr;
|
||||
aConfig.mLowpanContext = nullptr;
|
||||
aConfig.mExternalRoute->SetFrom(GetInstance(), *prefixTlv, *hasRoute, *hasRouteEntry);
|
||||
|
||||
ExitNow(error = kErrorNone);
|
||||
@@ -234,6 +252,29 @@ Error NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfi
|
||||
break;
|
||||
}
|
||||
|
||||
case NetworkDataTlv::kTypeContext:
|
||||
{
|
||||
const ContextTlv *contextTlv = As<ContextTlv>(subCur);
|
||||
|
||||
if (aConfig.mLowpanContext == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iterator.IsNewEntry())
|
||||
{
|
||||
aConfig.mOnMeshPrefix = nullptr;
|
||||
aConfig.mExternalRoute = nullptr;
|
||||
aConfig.mService = nullptr;
|
||||
aConfig.mLowpanContext->SetFrom(*prefixTlv, *contextTlv);
|
||||
|
||||
iterator.MarkEntryAsNotNew();
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -260,6 +301,7 @@ Error NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfi
|
||||
{
|
||||
aConfig.mOnMeshPrefix = nullptr;
|
||||
aConfig.mExternalRoute = nullptr;
|
||||
aConfig.mLowpanContext = nullptr;
|
||||
aConfig.mService->SetFrom(*service, *server);
|
||||
|
||||
iterator.MarkEntryAsNotNew();
|
||||
@@ -344,6 +386,7 @@ bool NetworkData::ContainsEntriesFrom(const NetworkData &aCompare, uint16_t aRlo
|
||||
config.mOnMeshPrefix = &prefix;
|
||||
config.mExternalRoute = &route;
|
||||
config.mService = &service;
|
||||
config.mLowpanContext = nullptr;
|
||||
|
||||
SuccessOrExit(aCompare.Iterate(iterator, aRloc16, config));
|
||||
|
||||
@@ -643,6 +686,7 @@ Error NetworkData::GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const
|
||||
config.mOnMeshPrefix = &prefixConfig;
|
||||
config.mExternalRoute = &routeConfig;
|
||||
config.mService = &serviceConfig;
|
||||
config.mLowpanContext = nullptr;
|
||||
|
||||
SuccessOrExit(error = Iterate(aIterator, Mac::kShortAddrBroadcast, config));
|
||||
|
||||
|
||||
@@ -266,6 +266,18 @@ public:
|
||||
*/
|
||||
Error GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const;
|
||||
|
||||
/**
|
||||
* This method gets the next 6LoWPAN Context ID info in the Thread Network Data.
|
||||
*
|
||||
* @param[in,out] aIterator A reference to the Network Data iterator.
|
||||
* @param[out] aContextInfo A reference to where the retrieved 6LoWPAN Context ID information will be placed.
|
||||
*
|
||||
* @retval kErrorNone Successfully found the next 6LoWPAN Context ID info.
|
||||
* @retval kErrorNotFound No subsequent 6LoWPAN Context info exists in the partition's Network Data.
|
||||
*
|
||||
*/
|
||||
Error GetNextLowpanContextInfo(Iterator &aIterator, LowpanContextInfo &aContextInfo) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Thread Network Data contains a given on mesh prefix entry.
|
||||
*
|
||||
@@ -557,6 +569,7 @@ private:
|
||||
OnMeshPrefixConfig *mOnMeshPrefix;
|
||||
ExternalRouteConfig *mExternalRoute;
|
||||
ServiceConfig *mService;
|
||||
LowpanContextInfo *mLowpanContext;
|
||||
};
|
||||
|
||||
Error Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const;
|
||||
|
||||
@@ -268,5 +268,13 @@ void ServiceConfig::SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aSer
|
||||
GetServerConfig().SetFrom(aServerTlv);
|
||||
}
|
||||
|
||||
void LowpanContextInfo::SetFrom(const PrefixTlv &aPrefixTlv, const ContextTlv &aContextTlv)
|
||||
{
|
||||
mContextId = aContextTlv.GetContextId();
|
||||
mCompressFlag = aContextTlv.IsCompress();
|
||||
aPrefixTlv.CopyPrefixTo(GetPrefix());
|
||||
GetPrefix().SetLength(aContextTlv.GetContextLength());
|
||||
}
|
||||
|
||||
} // namespace NetworkData
|
||||
} // namespace ot
|
||||
|
||||
@@ -67,6 +67,7 @@ class HasRouteTlv;
|
||||
class HasRouteEntry;
|
||||
class ServiceTlv;
|
||||
class ServerTlv;
|
||||
class ContextTlv;
|
||||
|
||||
/**
|
||||
* This enumeration represents the Network Data type.
|
||||
@@ -292,6 +293,28 @@ private:
|
||||
void SetFromTlvFlags(uint8_t aFlags);
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents 6LoWPAN Context ID information associated with a prefix in Network Data.
|
||||
*
|
||||
*/
|
||||
class LowpanContextInfo : public otLowpanContextInfo, public Clearable<LowpanContextInfo>
|
||||
{
|
||||
friend class NetworkData;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method gets the prefix.
|
||||
*
|
||||
* @return The prefix.
|
||||
*
|
||||
*/
|
||||
const Ip6::Prefix &GetPrefix(void) const { return AsCoreType(&mPrefix); }
|
||||
|
||||
private:
|
||||
Ip6::Prefix &GetPrefix(void) { return AsCoreType(&mPrefix); }
|
||||
void SetFrom(const PrefixTlv &aPrefixTlv, const ContextTlv &aContextTlv);
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents a Service Data.
|
||||
*
|
||||
@@ -392,6 +415,7 @@ private:
|
||||
|
||||
DefineCoreType(otBorderRouterConfig, NetworkData::OnMeshPrefixConfig);
|
||||
DefineCoreType(otExternalRouteConfig, NetworkData::ExternalRouteConfig);
|
||||
DefineCoreType(otLowpanContextInfo, NetworkData::LowpanContextInfo);
|
||||
DefineCoreType(otServiceConfig, NetworkData::ServiceConfig);
|
||||
DefineCoreType(otServerConfig, NetworkData::ServiceConfig::ServerConfig);
|
||||
|
||||
|
||||
@@ -2300,6 +2300,8 @@ class NodeImpl:
|
||||
for line in netdata:
|
||||
if line.startswith('Services:'):
|
||||
services_section = True
|
||||
elif line.startswith('Contexts'):
|
||||
services_section = False
|
||||
elif services_section:
|
||||
services.append(line.strip().split(' '))
|
||||
return services
|
||||
@@ -2310,8 +2312,8 @@ class NodeImpl:
|
||||
|
||||
def get_netdata(self):
|
||||
raw_netdata = self.netdata_show()
|
||||
netdata = {'Prefixes': [], 'Routes': [], 'Services': []}
|
||||
key_list = ['Prefixes', 'Routes', 'Services']
|
||||
netdata = {'Prefixes': [], 'Routes': [], 'Services': [], 'Contexts': []}
|
||||
key_list = ['Prefixes', 'Routes', 'Services', 'Contexts']
|
||||
key = None
|
||||
|
||||
for i in range(0, len(raw_netdata)):
|
||||
|
||||
@@ -359,10 +359,13 @@ class Node(object):
|
||||
outputs = [line.strip() for line in outputs]
|
||||
routes_index = outputs.index('Routes:')
|
||||
services_index = outputs.index('Services:')
|
||||
contexts_index = outputs.index('Contexts:')
|
||||
result = {}
|
||||
result['prefixes'] = outputs[1:routes_index]
|
||||
result['routes'] = outputs[routes_index + 1:services_index]
|
||||
result['services'] = outputs[services_index + 1:]
|
||||
result['services'] = outputs[services_index + 1:contexts_index]
|
||||
result['contexts'] = outputs[contexts_index + 1:]
|
||||
|
||||
return result
|
||||
|
||||
def get_netdata_prefixes(self):
|
||||
@@ -374,6 +377,9 @@ class Node(object):
|
||||
def get_netdata_services(self):
|
||||
return self.get_netdata()['services']
|
||||
|
||||
def get_netdata_contexts(self):
|
||||
return self.get_netdata()['contexts']
|
||||
|
||||
def get_netdata_versions(self):
|
||||
leaderdata = Node.parse_list(self.cli('leaderdata'))
|
||||
return (int(leaderdata['Data Version']), int(leaderdata['Stable Data Version']))
|
||||
|
||||
@@ -1694,7 +1694,7 @@ class OpenThreadTHCI(object):
|
||||
@watched
|
||||
def getNetworkData(self):
|
||||
lines = self.__executeCommand('netdata show')
|
||||
prefixes, routes, services = [], [], []
|
||||
prefixes, routes, services, contexts = [], [], [], []
|
||||
classify = None
|
||||
|
||||
for line in lines:
|
||||
@@ -1704,6 +1704,8 @@ class OpenThreadTHCI(object):
|
||||
classify = routes
|
||||
elif line == 'Services:':
|
||||
classify = services
|
||||
elif line == 'Contexts:':
|
||||
classify = contexts
|
||||
elif line == 'Done':
|
||||
classify = None
|
||||
else:
|
||||
@@ -1713,6 +1715,7 @@ class OpenThreadTHCI(object):
|
||||
'Prefixes': prefixes,
|
||||
'Routes': routes,
|
||||
'Services': services,
|
||||
'Contexts': contexts,
|
||||
}
|
||||
|
||||
@API
|
||||
|
||||
+10
-1
@@ -1570,7 +1570,16 @@ class OTCI(object):
|
||||
routes_output.append(line)
|
||||
|
||||
netdata['routes'] = self.__parse_routes(routes_output)
|
||||
netdata['services'] = self.__parse_services(output)
|
||||
|
||||
services_output = []
|
||||
while True:
|
||||
line = output.pop(0)
|
||||
if line == 'Contexts:':
|
||||
break
|
||||
else:
|
||||
services_output.append(line)
|
||||
|
||||
netdata['services'] = self.__parse_services(services_output)
|
||||
|
||||
return netdata
|
||||
|
||||
|
||||
Reference in New Issue
Block a user