Skip to content

Commit

Permalink
NcpBase: Update getter for OFF_MESH_ROUTES to include `NextHopIsThi…
Browse files Browse the repository at this point in the history
…sDevcie` field (openthread#1886)

The spinel header file and spinel documentation are also updated
accordingly.
  • Loading branch information
abtink authored and jwhui committed Jun 9, 2017
1 parent f60d71f commit 566930f
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 23 deletions.
14 changes: 9 additions & 5 deletions doc/spinel-protocol-src/spinel-tech-thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ The local stable network data.
Data per item is:

* `6`: IPv6 Prefix
* `C`: Prefix length, in bits
* `C`: Prefix length in bits
* `b`: Stable flag
* `C`: TLV flags
* `b`: "Is defined locally" flag. Set if this network was locally
Expand All @@ -98,18 +98,22 @@ Data per item is:

### PROP 91: PROP_THREAD_OFF_MESH_ROUTES
* Type: Read-Write
* Packed-Encoding: `A(t(6CbCb))`
* Packed-Encoding: `A(t(6CbCbb))`

Data per item is:

* `6`: IPv6 Prefix
* `C`: Prefix length, in bits
* `6`: Route Prefix
* `C`: Prefix length in bits
* `b`: Stable flag
* `C`: Other flags
* `C`: Route preference flags
* `b`: "Is defined locally" flag. Set if this route info was locally
defined as part of local network data. Assumed to be true for set,
insert and replace. Clear if the route is part of partition's network
data.
* `b`: "Next hop is this device" flag. Set if the next hop for the
route is this device itself (i.e., route was added by this device)
This value is ignored when adding an external route. For any added
route the next hop is this device.

### PROP 92: PROP_THREAD_ASSISTING_PORTS
* Type: Read-Write
Expand Down
84 changes: 67 additions & 17 deletions src/ncp/ncp_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,58 @@ static uint8_t BorderRouterConfigToFlagByte(const otBorderRouterConfig &config)
return flags;
}

static uint8_t ExternalRoutePreferenceToFlagByte(int aPreference)
{
uint8_t flags;

switch (aPreference)
{
case OT_ROUTE_PREFERENCE_LOW:
flags = SPINEL_ROUTE_PREFERENCE_LOW;
break;

case OT_ROUTE_PREFERENCE_MED:
flags = SPINEL_ROUTE_PREFERENCE_MEDIUM;
break;

case OT_ROUTE_PREFERENCE_HIGH:
flags = SPINEL_ROUTE_PREFERENCE_HIGH;
break;

default:
flags = SPINEL_ROUTE_PREFERENCE_MEDIUM;
break;
}

return flags;
}

#if OPENTHREAD_ENABLE_BORDER_ROUTER

static int FlagByteToExternalRoutePreference(uint8_t aFlags)
{
int route_preference = 0;

switch (aFlags & SPINEL_NET_FLAG_PREFERENCE_MASK)
{
case SPINEL_ROUTE_PREFERENCE_HIGH:
route_preference = OT_ROUTE_PREFERENCE_HIGH;
break;

case SPINEL_ROUTE_PREFERENCE_MEDIUM:
route_preference = OT_ROUTE_PREFERENCE_MED;
break;

case SPINEL_ROUTE_PREFERENCE_LOW:
route_preference = OT_ROUTE_PREFERENCE_LOW;
break;
}

return route_preference;
}

#endif // OPENTHREAD_ENABLE_BORDER_ROUTER

// ----------------------------------------------------------------------------
// MARK: Class Boilerplate
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -3248,7 +3300,6 @@ otError NcpBase::GetPropertyHandler_THREAD_OFF_MESH_ROUTES(uint8_t header, spine
otError errorCode = OT_ERROR_NONE;
otExternalRouteConfig external_route_config;
otNetworkDataIterator iter = OT_NETWORK_DATA_ITERATOR_INIT;
uint8_t flags;

mDisableStreamWrite = true;

Expand All @@ -3263,46 +3314,44 @@ otError NcpBase::GetPropertyHandler_THREAD_OFF_MESH_ROUTES(uint8_t header, spine

while (otNetDataGetNextRoute(mInstance, &iter, &external_route_config) == OT_ERROR_NONE)
{
flags = static_cast<uint8_t>(external_route_config.mPreference);
flags <<= SPINEL_NET_FLAG_PREFERENCE_OFFSET;

SuccessOrExit(
errorCode = OutboundFrameFeedPacked(
SPINEL_DATATYPE_STRUCT_S(
SPINEL_DATATYPE_IPv6ADDR_S // IPv6 Prefix
SPINEL_DATATYPE_UINT8_S // Prefix Length (in bits)
SPINEL_DATATYPE_BOOL_S // isStable
SPINEL_DATATYPE_UINT8_S // Flags
SPINEL_DATATYPE_BOOL_S // IsStable
SPINEL_DATATYPE_UINT8_S // Route Preference Flags
SPINEL_DATATYPE_BOOL_S // IsLocal
SPINEL_DATATYPE_BOOL_S // NextHopIsThisDevice
),
&external_route_config.mPrefix.mPrefix,
external_route_config.mPrefix.mLength,
external_route_config.mStable,
flags,
false
ExternalRoutePreferenceToFlagByte(external_route_config.mPreference),
false,
external_route_config.mNextHopIsThisDevice
));
}

#if OPENTHREAD_ENABLE_BORDER_ROUTER
while (otBorderRouterGetNextRoute(mInstance, &iter, &external_route_config) == OT_ERROR_NONE)
{
flags = static_cast<uint8_t>(external_route_config.mPreference);
flags <<= SPINEL_NET_FLAG_PREFERENCE_OFFSET;

SuccessOrExit(
errorCode = OutboundFrameFeedPacked(
SPINEL_DATATYPE_STRUCT_S(
SPINEL_DATATYPE_IPv6ADDR_S // IPv6 Prefix
SPINEL_DATATYPE_UINT8_S // Prefix Length (in bits)
SPINEL_DATATYPE_BOOL_S // isStable
SPINEL_DATATYPE_UINT8_S // Flags
SPINEL_DATATYPE_BOOL_S // IsStable
SPINEL_DATATYPE_UINT8_S // Route Preference Flags
SPINEL_DATATYPE_BOOL_S // IsLocal
SPINEL_DATATYPE_BOOL_S // NextHopIsThisDevice
),
&external_route_config.mPrefix.mPrefix,
external_route_config.mPrefix.mLength,
external_route_config.mStable,
flags,
true
ExternalRoutePreferenceToFlagByte(external_route_config.mPreference),
true,
external_route_config.mNextHopIsThisDevice
));
}
#endif // OPENTHREAD_ENABLE_BORDER_ROUTER
Expand Down Expand Up @@ -7030,7 +7079,7 @@ otError NcpBase::InsertPropertyHandler_THREAD_OFF_MESH_ROUTES(uint8_t header, sp
SPINEL_DATATYPE_IPv6ADDR_S // Route prefix
SPINEL_DATATYPE_UINT8_S // Prefix length (in bits)
SPINEL_DATATYPE_BOOL_S // Stable
SPINEL_DATATYPE_UINT8_S // Flags
SPINEL_DATATYPE_UINT8_S // Flags (Route Preference)
),
&addr_ptr,
&ext_route_config.mPrefix.mLength,
Expand All @@ -7042,7 +7091,8 @@ otError NcpBase::InsertPropertyHandler_THREAD_OFF_MESH_ROUTES(uint8_t header, sp
{
ext_route_config.mPrefix.mPrefix = *addr_ptr;
ext_route_config.mStable = stable;
ext_route_config.mPreference = ((flags & SPINEL_NET_FLAG_PREFERENCE_MASK) >> SPINEL_NET_FLAG_PREFERENCE_OFFSET);
ext_route_config.mPreference = FlagByteToExternalRoutePreference(flags);

errorCode = otBorderRouterAddRoute(mInstance, &ext_route_config);

if (errorCode == OT_ERROR_NONE)
Expand Down
30 changes: 29 additions & 1 deletion src/ncp/spinel.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@ enum
SPINEL_NET_FLAG_PREFERENCE_MASK = (3 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
};

enum
{
SPINEL_ROUTE_PREFERENCE_HIGH = (1 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
SPINEL_ROUTE_PREFERENCE_MEDIUM = (0 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
SPINEL_ROUTE_PREFERENCE_LOW = (3 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
};

enum {
SPINEL_GPIO_FLAG_DIR_INPUT = 0,
SPINEL_GPIO_FLAG_DIR_OUTPUT = SPINEL_BIT_MASK(0, 8),
Expand Down Expand Up @@ -744,7 +751,28 @@ typedef enum
SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION
= SPINEL_PROP_THREAD__BEGIN + 9, ///< [S]
SPINEL_PROP_THREAD_ON_MESH_NETS = SPINEL_PROP_THREAD__BEGIN + 10, ///< array(ipv6prefix,prefixlen,stable,flags,isLocal) [A(t(6CbCb))]
SPINEL_PROP_THREAD_OFF_MESH_ROUTES = SPINEL_PROP_THREAD__BEGIN + 11, ///< array(ipv6prefix,prefixlen,stable,flags,isLocal) [A(t(6CbCb))]

/// Off-mesh routes
/** Format: [A(t(6CbCbb))]
*
* Data per item is:
*
* `6`: Route Prefix
* `C`: Prefix length in bits
* `b`: Stable flag
* `C`: Route preference flags
* `b`: "Is defined locally" flag. Set if this route info was locally
* defined as part of local network data. Assumed to be true for set,
* insert and replace. Clear if the route is part of partition's network
* data.
* `b`: "Next hop is this device" flag. Set if the next hop for the
* route is this device itself (i.e., route was added by this device)
* This value is ignored when adding an external route. For any added
* route the next hop is this device.
*
*/
SPINEL_PROP_THREAD_OFF_MESH_ROUTES = SPINEL_PROP_THREAD__BEGIN + 11,

SPINEL_PROP_THREAD_ASSISTING_PORTS = SPINEL_PROP_THREAD__BEGIN + 12, ///< array(portn) [A(S)]
SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE
= SPINEL_PROP_THREAD__BEGIN + 13, ///< [b]
Expand Down

0 comments on commit 566930f

Please sign in to comment.