Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrfconnect] Implemented WiFiNetworkDiagnostics events generation #32962

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 103 additions & 6 deletions src/platform/nrfconnect/wifi/WiFiManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <crypto/RandUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/DiagnosticDataProvider.h>
#include <platform/Zephyr/InetUtils.h>

#include <zephyr/kernel.h>
Expand Down Expand Up @@ -151,7 +152,7 @@ void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mg
Platform::UniquePtr<uint8_t> eventData(new uint8_t[cb->info_length]);
VerifyOrReturn(eventData);
memcpy(eventData.get(), cb->info, cb->info_length);
sEventHandlerMap[mgmtEvent](std::move(eventData));
sEventHandlerMap[mgmtEvent](std::move(eventData), cb->info_length);
}
}

Expand Down Expand Up @@ -292,8 +293,11 @@ CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const
return CHIP_NO_ERROR;
}

void WiFiManager::ScanResultHandler(Platform::UniquePtr<uint8_t> data)
void WiFiManager::ScanResultHandler(Platform::UniquePtr<uint8_t> data, size_t length)
{
// Validate that input data size matches the expected one.
VerifyOrReturn(length == sizeof(wifi_scan_result));

// Contrary to other handlers, offload accumulating of the scan results from the CHIP thread to the caller's thread
const wifi_scan_result * scanResult = reinterpret_cast<const wifi_scan_result *>(data.get());

Expand Down Expand Up @@ -337,8 +341,11 @@ void WiFiManager::ScanResultHandler(Platform::UniquePtr<uint8_t> data)
}
}

void WiFiManager::ScanDoneHandler(Platform::UniquePtr<uint8_t> data)
void WiFiManager::ScanDoneHandler(Platform::UniquePtr<uint8_t> data, size_t length)
{
// Validate that input data size matches the expected one.
VerifyOrReturn(length == sizeof(wifi_status));

CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] {
Platform::UniquePtr<uint8_t> safePtr(capturedData);
uint8_t * rawData = safePtr.get();
Expand Down Expand Up @@ -416,8 +423,13 @@ void WiFiManager::SendRouterSolicitation(System::Layer * layer, void * param)
}
}

void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data, size_t length)
{
using app::Clusters::WiFiNetworkDiagnostics::AssociationFailureCauseEnum;

// Validate that input data size matches the expected one.
VerifyOrReturn(length == sizeof(wifi_status));

CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] {
Platform::UniquePtr<uint8_t> safePtr(capturedData);
uint8_t * rawData = safePtr.get();
Expand All @@ -432,6 +444,32 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
{
Instance().mHandling.mOnConnectionDone(connStatus);
}

WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate();
if (delegate)
{
uint16_t reason = Instance().GetLastDisconnectReason();
uint8_t associationFailureCause;

switch (connStatus)
{
case WIFI_STATUS_CONN_WRONG_PASSWORD:
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kAuthenticationFailed);
break;
case WIFI_STATUS_CONN_FAIL:
case WIFI_STATUS_CONN_TIMEOUT:
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kAssociationFailed);
break;
case WIFI_STATUS_CONN_AP_NOT_FOUND:
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kSsidNotFound);
break;
default:
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kUnknown);
break;
}

delegate->OnAssociationFailureDetected(associationFailureCause, reason);
}
}
else // The connection has been established successfully.
{
Expand All @@ -457,6 +495,13 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
{
ChipLogError(DeviceLayer, "Cannot post event [error: %s]", ErrorStr(error));
}

WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate();
if (delegate)
{
delegate->OnConnectionStatusChanged(
to_underlying(app::Clusters::WiFiNetworkDiagnostics::ConnectionStatusEnum::kConnected));
}
}
// cleanup the provisioning data as it is configured per each connect request
Instance().ClearStationProvisioningData();
Expand All @@ -469,13 +514,55 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
}
}

void WiFiManager::DisconnectHandler(Platform::UniquePtr<uint8_t>)
void WiFiManager::DisconnectHandler(Platform::UniquePtr<uint8_t> data, size_t length)
{
SystemLayer().ScheduleLambda([] {
// Validate that input data size matches the expected one.
VerifyOrReturn(length == sizeof(wifi_status));

CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] {
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
Platform::UniquePtr<uint8_t> safePtr(capturedData);
uint8_t * rawData = safePtr.get();
const wifi_status * status = reinterpret_cast<const wifi_status *>(rawData);
kkasperczyk-no marked this conversation as resolved.
Show resolved Hide resolved
uint16_t reason;

switch (status->disconn_reason)
{
case WIFI_REASON_DISCONN_UNSPECIFIED:
reason = WLAN_REASON_UNSPECIFIED;
break;
case WIFI_REASON_DISCONN_USER_REQUEST:
reason = WLAN_REASON_DEAUTH_LEAVING;
break;
case WIFI_REASON_DISCONN_AP_LEAVING:
reason = WLAN_REASON_DEAUTH_LEAVING;
break;
case WIFI_REASON_DISCONN_INACTIVITY:
reason = WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY;
break;
default:
reason = WLAN_REASON_UNSPECIFIED;
break;
}
Instance().SetLastDisconnectReason(reason);

ChipLogProgress(DeviceLayer, "WiFi station disconnected");
Instance().mWiFiState = WIFI_STATE_DISCONNECTED;
Instance().PostConnectivityStatusChange(kConnectivity_Lost);

WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate();
if (delegate)
{
delegate->OnConnectionStatusChanged(
to_underlying(app::Clusters::WiFiNetworkDiagnostics::ConnectionStatusEnum::kNotConnected));
delegate->OnDisconnectionDetected(reason);
}
});

if (CHIP_NO_ERROR == err)
{
// the ownership has been transferred to the worker thread - release the buffer
data.release();
}
}

void WiFiManager::IPv6AddressChangeHandler(const void * data)
Expand Down Expand Up @@ -586,5 +673,15 @@ CHIP_ERROR WiFiManager::SetLowPowerMode(bool onoff)
return CHIP_NO_ERROR;
}

void WiFiManager::SetLastDisconnectReason(uint16_t reason)
{
mLastDisconnectedReason = reason;
}

uint16_t WiFiManager::GetLastDisconnectReason()
{
return mLastDisconnectedReason;
}

} // namespace DeviceLayer
} // namespace chip
13 changes: 8 additions & 5 deletions src/platform/nrfconnect/wifi/WiFiManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,11 @@ class WiFiManager
CHIP_ERROR GetNetworkStatistics(NetworkStatistics & stats) const;
void AbortConnectionRecovery();
CHIP_ERROR SetLowPowerMode(bool onoff);
void SetLastDisconnectReason(uint16_t reason);
uint16_t GetLastDisconnectReason();

private:
using NetEventHandler = void (*)(Platform::UniquePtr<uint8_t>);
using NetEventHandler = void (*)(Platform::UniquePtr<uint8_t>, size_t);

struct ConnectionParams
{
Expand All @@ -197,10 +199,10 @@ class WiFiManager
// 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 ScanResultHandler(Platform::UniquePtr<uint8_t> data, size_t length);
static void ScanDoneHandler(Platform::UniquePtr<uint8_t> data, size_t length);
static void ConnectHandler(Platform::UniquePtr<uint8_t> data, size_t length);
static void DisconnectHandler(Platform::UniquePtr<uint8_t> data, size_t length);
static void PostConnectivityStatusChange(ConnectivityChange changeType);
static void SendRouterSolicitation(System::Layer * layer, void * param);
static void IPv6AddressChangeHandler(const void * data);
Expand Down Expand Up @@ -234,6 +236,7 @@ class WiFiManager
uint32_t mConnectionRecoveryCounter{ 0 };
uint32_t mConnectionRecoveryTimeMs{ kConnectionRecoveryMinIntervalMs };
bool mApplicationDisconnectRequested{ false };
uint16_t mLastDisconnectedReason = WLAN_REASON_UNSPECIFIED;

static const Map<wifi_iface_state, StationStatus, 10> sStatusMap;
static const Map<uint32_t, NetEventHandler, 5> sEventHandlerMap;
Expand Down
Loading