Skip to content

Commit

Permalink
[nrf noup] Added DNS server refresh after adding new IPv6 address
Browse files Browse the repository at this point in the history
The Wi-Fi device does not update mDNS queries after obtaining
new IPv6 GUA address, so for some time after assigning prefix,
the Thread Border Routers still use cached link-local address,
which is not routable.

Signed-off-by: Kamil Kasperczyk <kamil.kasperczyk@nordicsemi.no>
  • Loading branch information
kkasperczyk-no committed Jan 15, 2024
1 parent e13071a commit e54423d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
44 changes: 37 additions & 7 deletions src/platform/nrfconnect/wifi/WiFiManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,13 @@ const Map<wifi_iface_state, WiFiManager::StationStatus, 10>
{ WIFI_STATE_GROUP_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING },
{ WIFI_STATE_COMPLETED, WiFiManager::StationStatus::FULLY_PROVISIONED } });

const Map<uint32_t, WiFiManager::NetEventHandler, 5>
WiFiManager::sEventHandlerMap({ { NET_EVENT_WIFI_SCAN_RESULT, WiFiManager::ScanResultHandler },
{ NET_EVENT_WIFI_SCAN_DONE, WiFiManager::ScanDoneHandler },
{ NET_EVENT_WIFI_CONNECT_RESULT, WiFiManager::ConnectHandler },
{ NET_EVENT_WIFI_DISCONNECT_RESULT, WiFiManager::DisconnectHandler },
{ NET_EVENT_WIFI_DISCONNECT_COMPLETE, WiFiManager::DisconnectHandler } });
const Map<uint32_t, WiFiManager::NetEventHandler, 5> WiFiManager::sEventHandlerMap({
{ NET_EVENT_WIFI_SCAN_RESULT, WiFiManager::ScanResultHandler },
{ NET_EVENT_WIFI_SCAN_DONE, WiFiManager::ScanDoneHandler },
{ NET_EVENT_WIFI_CONNECT_RESULT, WiFiManager::ConnectHandler },
{ NET_EVENT_WIFI_DISCONNECT_RESULT, WiFiManager::DisconnectHandler },
{ NET_EVENT_WIFI_DISCONNECT_COMPLETE, WiFiManager::DisconnectHandler },
});

void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface)
{
Expand All @@ -154,14 +155,24 @@ void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mg
}
}

void WiFiManager::IPv6MgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface)
{
if (((mgmtEvent == NET_EVENT_IPV6_ADDR_ADD) || (mgmtEvent == NET_EVENT_IPV6_ADDR_DEL)) && cb->info)
{
IPv6AddressChangeHandler(cb->info);
}
}

CHIP_ERROR WiFiManager::Init()
{
mNetIf = InetUtils::GetWiFiInterface();
VerifyOrReturnError(mNetIf != nullptr, INET_ERROR_UNKNOWN_INTERFACE);


net_mgmt_init_event_callback(&mWiFiMgmtClbk, WifiMgmtEventHandler, kWifiManagementEvents);
net_mgmt_init_event_callback(&mIPv6MgmtClbk, IPv6MgmtEventHandler, kIPv6ManagementEvents);

net_mgmt_add_event_callback(&mWiFiMgmtClbk);
net_mgmt_add_event_callback(&mIPv6MgmtClbk);

ChipLogDetail(DeviceLayer, "WiFiManager has been initialized");

Expand Down Expand Up @@ -469,6 +480,25 @@ void WiFiManager::DisconnectHandler(Platform::UniquePtr<uint8_t>)
});
}

void WiFiManager::IPv6AddressChangeHandler(const void * data)
{
const in6_addr * addr = reinterpret_cast<const in6_addr *>(data);

// Filter out link-local addresses that are not routable outside of a local network.
if (!net_ipv6_is_ll_addr(addr))
{
// This is needed to send mDNS queries containing updated IPv6 addresses.
ChipDeviceEvent event;
event.Type = DeviceEventType::kDnssdRestartNeeded;

CHIP_ERROR error = PlatformMgr().PostEvent(&event);
if (error != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "Cannot post event: %" CHIP_ERROR_FORMAT, error.Format());
}
}
}

WiFiManager::StationStatus WiFiManager::GetStationStatus() const
{
return WiFiManager::sStatusMap[mWiFiState];
Expand Down
5 changes: 5 additions & 0 deletions src/platform/nrfconnect/wifi/WiFiManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,18 @@ class WiFiManager
constexpr static uint32_t kWifiManagementEvents = NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE |
NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | NET_EVENT_WIFI_IFACE_STATUS;

constexpr static uint32_t kIPv6ManagementEvents = NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_ADDR_DEL;

// Event handling
static void WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface);
static void IPv6MgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface);
static void ScanResultHandler(Platform::UniquePtr<uint8_t> data);
static void ScanDoneHandler(Platform::UniquePtr<uint8_t> data);
static void ConnectHandler(Platform::UniquePtr<uint8_t> data);
static void DisconnectHandler(Platform::UniquePtr<uint8_t> data);
static void PostConnectivityStatusChange(ConnectivityChange changeType);
static void SendRouterSolicitation(System::Layer * layer, void * param);
static void IPv6AddressChangeHandler(const void * data);

// Connection Recovery feature
// This feature allows re-scanning and re-connecting the connection to the known network after
Expand All @@ -226,6 +230,7 @@ class WiFiManager
wifi_iface_state mWiFiState;
wifi_iface_state mCachedWiFiState;
net_mgmt_event_callback mWiFiMgmtClbk{};
net_mgmt_event_callback mIPv6MgmtClbk{};
ScanResultCallback mScanResultCallback{ nullptr };
ScanDoneCallback mScanDoneCallback{ nullptr };
WiFiNetwork mWantedNetwork{};
Expand Down

0 comments on commit e54423d

Please sign in to comment.