mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[ncp] Support for multicast address table (#2001)
This commit adds a new spinel property (along with its prop handlers) `SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE` to provide the list of multicast IPv6 addresses. It also adds `OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED` and `OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED` to flags used in `NetifCallback` to indicate changes in multicast address list.
This commit is contained in:
committed by
Jonathan Hui
parent
fdc3ea2732
commit
5ba896266c
@@ -22,6 +22,7 @@ IPv6 Prefix + Prefix Length
|
||||
* Type: Read-Write
|
||||
* Packed-Encoding: `A(t(6CLLC))`
|
||||
|
||||
This property provides all unicast addresses.
|
||||
Array of structures containing:
|
||||
|
||||
* `6`: IPv6 Address
|
||||
@@ -39,3 +40,10 @@ turned on, ping request ICMP packets will not be passed to the host.
|
||||
|
||||
Default value is `false`.
|
||||
|
||||
### PROP 102: SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE {#prop-ipv6-multicast-address-table}
|
||||
* Type: Read-Write
|
||||
* Packed-Encoding: `A(t(6))`
|
||||
|
||||
Array of structures containing:
|
||||
|
||||
* `6`: Multicast IPv6 Address
|
||||
|
||||
@@ -653,6 +653,8 @@ enum
|
||||
OT_CHANGED_THREAD_NETDATA = 1 << 9, ///< Thread Network Data changed
|
||||
OT_CHANGED_THREAD_CHILD_ADDED = 1 << 10, ///< Child was added
|
||||
OT_CHANGED_THREAD_CHILD_REMOVED = 1 << 11, ///< Child was removed
|
||||
OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED = 1 << 12, ///< Subscribed to a IPv6 multicast address
|
||||
OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED = 1 << 13, ///< Unsubscribed from a IPv6 multicast address
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -156,6 +156,7 @@ otError Netif::SubscribeMulticast(NetifMulticastAddress &aAddress)
|
||||
|
||||
aAddress.mNext = mMulticastAddresses;
|
||||
mMulticastAddresses = &aAddress;
|
||||
SetStateChangedFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -185,6 +186,12 @@ otError Netif::UnsubscribeMulticast(const NetifMulticastAddress &aAddress)
|
||||
ExitNow(error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NOT_FOUND)
|
||||
{
|
||||
SetStateChangedFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -215,6 +222,7 @@ otError Netif::SubscribeExternalMulticast(const Address &aAddress)
|
||||
entry->mAddress = aAddress;
|
||||
entry->mNext = mMulticastAddresses;
|
||||
mMulticastAddresses = entry;
|
||||
SetStateChangedFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -254,6 +262,8 @@ otError Netif::UnsubscribeExternalMulticast(const Address &aAddress)
|
||||
// To mark the address entry as unused/available, set the `mNext` pointer back to the entry itself.
|
||||
entry->mNext = entry;
|
||||
|
||||
SetStateChangedFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -184,6 +184,7 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
|
||||
NCP_GET_PROP_HANDLER_ENTRY(IPV6_ADDRESS_TABLE),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(IPV6_ROUTE_TABLE),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(IPV6_ICMP_PING_OFFLOAD),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(IPV6_MULTICAST_ADDRESS_TABLE),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(THREAD_RLOC16_DEBUG_PASSTHRU),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(THREAD_DISCOVERY_SCAN_JOINER_FLAG),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(THREAD_DISCOVERY_SCAN_ENABLE_FILTERING),
|
||||
@@ -372,6 +373,7 @@ const NcpBase::InsertPropertyHandlerEntry NcpBase::mInsertPropertyHandlerTable[]
|
||||
NCP_INSERT_PROP_HANDLER_ENTRY(MAC_SRC_MATCH_EXTENDED_ADDRESSES),
|
||||
#endif
|
||||
NCP_INSERT_PROP_HANDLER_ENTRY(IPV6_ADDRESS_TABLE),
|
||||
NCP_INSERT_PROP_HANDLER_ENTRY(IPV6_MULTICAST_ADDRESS_TABLE),
|
||||
NCP_INSERT_PROP_HANDLER_ENTRY(THREAD_ASSISTING_PORTS),
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_INSERT_PROP_HANDLER_ENTRY(THREAD_OFF_MESH_ROUTES),
|
||||
@@ -396,6 +398,7 @@ const NcpBase::RemovePropertyHandlerEntry NcpBase::mRemovePropertyHandlerTable[]
|
||||
NCP_REMOVE_PROP_HANDLER_ENTRY(MAC_SRC_MATCH_EXTENDED_ADDRESSES),
|
||||
#endif
|
||||
NCP_REMOVE_PROP_HANDLER_ENTRY(IPV6_ADDRESS_TABLE),
|
||||
NCP_REMOVE_PROP_HANDLER_ENTRY(IPV6_MULTICAST_ADDRESS_TABLE),
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_REMOVE_PROP_HANDLER_ENTRY(THREAD_OFF_MESH_ROUTES),
|
||||
NCP_REMOVE_PROP_HANDLER_ENTRY(THREAD_ON_MESH_NETS),
|
||||
@@ -1340,6 +1343,17 @@ void NcpBase::UpdateChangedProps(void)
|
||||
|
||||
mChangedFlags &= ~static_cast<uint32_t>(OT_CHANGED_IP6_ADDRESS_ADDED | OT_CHANGED_IP6_ADDRESS_REMOVED);
|
||||
}
|
||||
else if ((mChangedFlags & (OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED | OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED)) != 0)
|
||||
{
|
||||
SuccessOrExit(
|
||||
HandleCommandPropertyGet(
|
||||
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
|
||||
SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE
|
||||
));
|
||||
|
||||
mChangedFlags &= ~static_cast<uint32_t>(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED |
|
||||
OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);
|
||||
}
|
||||
else if ((mChangedFlags & (OT_CHANGED_THREAD_CHILD_ADDED | OT_CHANGED_THREAD_CHILD_REMOVED)) != 0)
|
||||
{
|
||||
SuccessOrExit(
|
||||
@@ -3430,6 +3444,40 @@ otError NcpBase::GetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t aHeader, spin
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_IPV6_MULTICAST_ADDRESS_TABLE(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const otNetifMulticastAddress *address;
|
||||
|
||||
mDisableStreamWrite = true;
|
||||
|
||||
SuccessOrExit(error = OutboundFrameBegin(aHeader));
|
||||
SuccessOrExit(
|
||||
error = OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_COMMAND_PROP_S,
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey
|
||||
));
|
||||
|
||||
for (address = otIp6GetMulticastAddresses(mInstance); address; address = address->mNext)
|
||||
{
|
||||
SuccessOrExit(
|
||||
error = OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_STRUCT_S(
|
||||
SPINEL_DATATYPE_IPv6ADDR_S // IPv6 address
|
||||
),
|
||||
&address->mAddress
|
||||
));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = OutboundFrameSend());
|
||||
|
||||
exit:
|
||||
mDisableStreamWrite = false;
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_RLOC16_DEBUG_PASSTHRU(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
// Note reverse logic: passthru enabled = filter disabled
|
||||
@@ -6804,6 +6852,46 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::InsertPropertyHandler_IPV6_MULTICAST_ADDRESS_TABLE(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
otIp6Address *addrPtr;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_IPv6ADDR_S, // IPv6 address
|
||||
&addrPtr
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otIp6SubscribeMulticastAddress(mInstance, addrPtr);
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_INSERTED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
spinelError = SPINEL_STATUS_OK;
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
otError NcpBase::InsertPropertyHandler_THREAD_OFF_MESH_ROUTES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
@@ -7305,6 +7393,44 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::RemovePropertyHandler_IPV6_MULTICAST_ADDRESS_TABLE(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
otIp6Address *addrPtr;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_IPv6ADDR_S,
|
||||
&addrPtr
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otIp6UnsubscribeMulticastAddress(mInstance, addrPtr);
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_REMOVED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
otError NcpBase::RemovePropertyHandler_THREAD_OFF_MESH_ROUTES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
|
||||
@@ -375,6 +375,7 @@ private:
|
||||
NCP_GET_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
NCP_GET_PROP_HANDLER(IPV6_ROUTE_TABLE);
|
||||
NCP_GET_PROP_HANDLER(IPV6_ICMP_PING_OFFLOAD);
|
||||
NCP_GET_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
NCP_GET_PROP_HANDLER(THREAD_RLOC16_DEBUG_PASSTHRU);
|
||||
NCP_GET_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
NCP_GET_PROP_HANDLER(STREAM_NET);
|
||||
@@ -543,6 +544,7 @@ private:
|
||||
NCP_INSERT_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
#endif
|
||||
NCP_INSERT_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
NCP_INSERT_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
@@ -564,6 +566,7 @@ private:
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
#endif
|
||||
NCP_REMOVE_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
NCP_REMOVE_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
|
||||
@@ -1332,6 +1332,10 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
ret = "PROP_IPV6_ICMP_PING_OFFLOAD";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE:
|
||||
ret = "PROP_IPV6_MULTICAST_ADDRESS_TABLE";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_STREAM_DEBUG:
|
||||
ret = "PROP_STREAM_DEBUG";
|
||||
break;
|
||||
|
||||
@@ -990,6 +990,9 @@ typedef enum
|
||||
*/
|
||||
SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD = SPINEL_PROP_IPV6__BEGIN + 5, ///< [b]
|
||||
|
||||
SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE
|
||||
= SPINEL_PROP_IPV6__BEGIN + 6, ///< [A(t(6))]
|
||||
|
||||
SPINEL_PROP_IPV6__END = 0x70,
|
||||
|
||||
SPINEL_PROP_STREAM__BEGIN = 0x70,
|
||||
|
||||
Reference in New Issue
Block a user