diff --git a/src/platform/Zephyr/ThreadStackManagerImpl.cpp b/src/platform/Zephyr/ThreadStackManagerImpl.cpp index df8c27fe41..58a92f3bef 100644 --- a/src/platform/Zephyr/ThreadStackManagerImpl.cpp +++ b/src/platform/Zephyr/ThreadStackManagerImpl.cpp @@ -27,16 +27,13 @@ #include #include -#include #include -#include #include namespace chip { namespace DeviceLayer { using namespace ::chip::DeviceLayer::Internal; -using namespace ::chip::Inet; ThreadStackManagerImpl ThreadStackManagerImpl::sInstance; @@ -46,18 +43,6 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack() ReturnErrorOnFailure(GenericThreadStackManagerImpl_OpenThread::DoInit(instance)); - UDPEndPointImplSockets::SetMulticastGroupHandler([](InterfaceId, const IPAddress & address, bool join) { - const otIp6Address otAddress = ToOpenThreadIP6Address(address); - const auto handler = join ? otIp6SubscribeMulticastAddress : otIp6UnsubscribeMulticastAddress; - otError error; - - ThreadStackMgr().LockThreadStack(); - error = handler(openthread_get_default_instance(), &otAddress); - ThreadStackMgr().UnlockThreadStack(); - - return MapOpenThreadError(error); - }); - return CHIP_NO_ERROR; } diff --git a/src/platform/nrfconnect/BUILD.gn b/src/platform/nrfconnect/BUILD.gn index f6807b3f8d..5a11b4f3d0 100644 --- a/src/platform/nrfconnect/BUILD.gn +++ b/src/platform/nrfconnect/BUILD.gn @@ -28,6 +28,8 @@ static_library("nrfconnect") { "../Zephyr/ConfigurationManagerImpl.cpp", "../Zephyr/DiagnosticDataProviderImpl.cpp", "../Zephyr/DiagnosticDataProviderImpl.h", + "../Zephyr/InetUtils.cpp", + "../Zephyr/InetUtils.h", "../Zephyr/KeyValueStoreManagerImpl.cpp", "../Zephyr/Logging.cpp", "../Zephyr/PlatformManagerImpl.cpp", @@ -96,8 +98,6 @@ static_library("nrfconnect") { if (chip_enable_wifi) { sources += [ - "../Zephyr/InetUtils.cpp", - "../Zephyr/InetUtils.h", "OTAImageProcessorImplWiFi.h", "wifi/ConnectivityManagerImplWiFi.cpp", "wifi/ConnectivityManagerImplWiFi.h", diff --git a/src/platform/nrfconnect/ConnectivityManagerImpl.cpp b/src/platform/nrfconnect/ConnectivityManagerImpl.cpp index 504b0d0460..81d8bd1088 100644 --- a/src/platform/nrfconnect/ConnectivityManagerImpl.cpp +++ b/src/platform/nrfconnect/ConnectivityManagerImpl.cpp @@ -17,11 +17,12 @@ #include -#include -#include - +#include #include #include +#include +#include +#include #include @@ -35,15 +36,57 @@ #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include +#include #endif -using namespace ::chip; -using namespace ::chip::TLV; +using namespace ::chip::Inet; using namespace ::chip::DeviceLayer::Internal; namespace chip { namespace DeviceLayer { +namespace { +CHIP_ERROR JoinLeaveMulticastGroup(net_if * iface, const Inet::IPAddress & address, bool join) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + if (net_if_l2(iface) == &NET_L2_GET_NAME(OPENTHREAD)) + { + const otIp6Address otAddress = ToOpenThreadIP6Address(address); + const auto handler = join ? otIp6SubscribeMulticastAddress : otIp6UnsubscribeMulticastAddress; + otError error; + + ThreadStackMgr().LockThreadStack(); + error = handler(openthread_get_default_instance(), &otAddress); + ThreadStackMgr().UnlockThreadStack(); + + return MapOpenThreadError(error); + } +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + // The following code should also be valid for other interface types, such as Ethernet, + // but they are not officially supported, so for now enable it for Wi-Fi only. + const in6_addr in6Addr = InetUtils::ToZephyrAddr(address); + + if (join) + { + net_if_mcast_addr * maddr = net_if_ipv6_maddr_add(iface, &in6Addr); + + if (maddr && !net_if_ipv6_maddr_is_joined(maddr)) + { + net_if_ipv6_maddr_join(iface, maddr); + } + } + else + { + VerifyOrReturnError(net_if_ipv6_maddr_rm(iface, &in6Addr), CHIP_ERROR_INVALID_ADDRESS); + } +#endif + + return CHIP_NO_ERROR; +} +} // namespace + ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; CHIP_ERROR ConnectivityManagerImpl::_Init() @@ -54,6 +97,25 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() #if CHIP_DEVICE_CONFIG_ENABLE_WIFI ReturnErrorOnFailure(InitWiFi()); #endif + + UDPEndPointImplSockets::SetMulticastGroupHandler([](InterfaceId interfaceId, const IPAddress & address, bool join) { + if (interfaceId.IsPresent()) + { + net_if * iface = InetUtils::GetInterface(interfaceId); + VerifyOrReturnError(iface != nullptr, INET_ERROR_UNKNOWN_INTERFACE); + + return JoinLeaveMulticastGroup(iface, address, join); + } + + // If the interface is not specified, join or leave the multicast group on all interfaces. + for (int i = 1; net_if * iface = net_if_get_by_index(i); i++) + { + ReturnErrorOnFailure(JoinLeaveMulticastGroup(iface, address, join)); + } + + return CHIP_NO_ERROR; + }); + return CHIP_NO_ERROR; } diff --git a/src/platform/nrfconnect/wifi/WiFiManager.cpp b/src/platform/nrfconnect/wifi/WiFiManager.cpp index 54f0540b79..6b2babb974 100644 --- a/src/platform/nrfconnect/wifi/WiFiManager.cpp +++ b/src/platform/nrfconnect/wifi/WiFiManager.cpp @@ -23,8 +23,6 @@ #include "WiFiManager.h" #include -#include -#include #include #include #include @@ -161,30 +159,6 @@ CHIP_ERROR WiFiManager::Init() mNetIf = InetUtils::GetWiFiInterface(); VerifyOrReturnError(mNetIf != nullptr, INET_ERROR_UNKNOWN_INTERFACE); - // TODO: consider moving these to ConnectivityManagerImpl to be prepared for handling multiple interfaces on a single device. - Inet::UDPEndPointImplSockets::SetMulticastGroupHandler( - [](Inet::InterfaceId interfaceId, const Inet::IPAddress & address, bool join) { - const in6_addr addr = InetUtils::ToZephyrAddr(address); - net_if * iface = InetUtils::GetInterface(interfaceId); - VerifyOrReturnError(iface != nullptr, INET_ERROR_UNKNOWN_INTERFACE); - - if (join) - { - net_if_mcast_addr * maddr = net_if_ipv6_maddr_add(iface, &addr); - - if (maddr && !net_if_ipv6_maddr_is_joined(maddr) && !net_ipv6_is_addr_mcast_link_all_nodes(&addr)) - { - net_if_ipv6_maddr_join(iface, maddr); - } - } - else - { - VerifyOrReturnError(net_ipv6_is_addr_mcast_link_all_nodes(&addr) || net_if_ipv6_maddr_rm(iface, &addr), - CHIP_ERROR_INVALID_ADDRESS); - } - - return CHIP_NO_ERROR; - }); net_mgmt_init_event_callback(&mWiFiMgmtClbk, WifiMgmtEventHandler, kWifiManagementEvents); net_mgmt_add_event_callback(&mWiFiMgmtClbk);