Skip to content

Commit 9a81bed

Browse files
[nrfconnect] Implemented WiFiNetworkDiagnostics events generation (#32962)
* Added generation of optional events from WiFiNetworkDiagnostics cluster. * Improved handler methods to validate the input data size
1 parent 7b7af2f commit 9a81bed

File tree

2 files changed

+111
-11
lines changed

2 files changed

+111
-11
lines changed

src/platform/nrfconnect/wifi/WiFiManager.cpp

+103-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <crypto/RandUtils.h>
2626
#include <lib/support/logging/CHIPLogging.h>
2727
#include <platform/CHIPDeviceLayer.h>
28+
#include <platform/DiagnosticDataProvider.h>
2829
#include <platform/Zephyr/InetUtils.h>
2930

3031
#include <zephyr/kernel.h>
@@ -151,7 +152,7 @@ void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mg
151152
Platform::UniquePtr<uint8_t> eventData(new uint8_t[cb->info_length]);
152153
VerifyOrReturn(eventData);
153154
memcpy(eventData.get(), cb->info, cb->info_length);
154-
sEventHandlerMap[mgmtEvent](std::move(eventData));
155+
sEventHandlerMap[mgmtEvent](std::move(eventData), cb->info_length);
155156
}
156157
}
157158

@@ -292,8 +293,11 @@ CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const
292293
return CHIP_NO_ERROR;
293294
}
294295

295-
void WiFiManager::ScanResultHandler(Platform::UniquePtr<uint8_t> data)
296+
void WiFiManager::ScanResultHandler(Platform::UniquePtr<uint8_t> data, size_t length)
296297
{
298+
// Validate that input data size matches the expected one.
299+
VerifyOrReturn(length == sizeof(wifi_scan_result));
300+
297301
// Contrary to other handlers, offload accumulating of the scan results from the CHIP thread to the caller's thread
298302
const wifi_scan_result * scanResult = reinterpret_cast<const wifi_scan_result *>(data.get());
299303

@@ -337,8 +341,11 @@ void WiFiManager::ScanResultHandler(Platform::UniquePtr<uint8_t> data)
337341
}
338342
}
339343

340-
void WiFiManager::ScanDoneHandler(Platform::UniquePtr<uint8_t> data)
344+
void WiFiManager::ScanDoneHandler(Platform::UniquePtr<uint8_t> data, size_t length)
341345
{
346+
// Validate that input data size matches the expected one.
347+
VerifyOrReturn(length == sizeof(wifi_status));
348+
342349
CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] {
343350
Platform::UniquePtr<uint8_t> safePtr(capturedData);
344351
uint8_t * rawData = safePtr.get();
@@ -416,8 +423,13 @@ void WiFiManager::SendRouterSolicitation(System::Layer * layer, void * param)
416423
}
417424
}
418425

419-
void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
426+
void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data, size_t length)
420427
{
428+
using app::Clusters::WiFiNetworkDiagnostics::AssociationFailureCauseEnum;
429+
430+
// Validate that input data size matches the expected one.
431+
VerifyOrReturn(length == sizeof(wifi_status));
432+
421433
CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] {
422434
Platform::UniquePtr<uint8_t> safePtr(capturedData);
423435
uint8_t * rawData = safePtr.get();
@@ -432,6 +444,32 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
432444
{
433445
Instance().mHandling.mOnConnectionDone(connStatus);
434446
}
447+
448+
WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate();
449+
if (delegate)
450+
{
451+
uint16_t reason = Instance().GetLastDisconnectReason();
452+
uint8_t associationFailureCause;
453+
454+
switch (connStatus)
455+
{
456+
case WIFI_STATUS_CONN_WRONG_PASSWORD:
457+
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kAuthenticationFailed);
458+
break;
459+
case WIFI_STATUS_CONN_FAIL:
460+
case WIFI_STATUS_CONN_TIMEOUT:
461+
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kAssociationFailed);
462+
break;
463+
case WIFI_STATUS_CONN_AP_NOT_FOUND:
464+
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kSsidNotFound);
465+
break;
466+
default:
467+
associationFailureCause = to_underlying(AssociationFailureCauseEnum::kUnknown);
468+
break;
469+
}
470+
471+
delegate->OnAssociationFailureDetected(associationFailureCause, reason);
472+
}
435473
}
436474
else // The connection has been established successfully.
437475
{
@@ -457,6 +495,13 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
457495
{
458496
ChipLogError(DeviceLayer, "Cannot post event [error: %s]", ErrorStr(error));
459497
}
498+
499+
WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate();
500+
if (delegate)
501+
{
502+
delegate->OnConnectionStatusChanged(
503+
to_underlying(app::Clusters::WiFiNetworkDiagnostics::ConnectionStatusEnum::kConnected));
504+
}
460505
}
461506
// cleanup the provisioning data as it is configured per each connect request
462507
Instance().ClearStationProvisioningData();
@@ -469,13 +514,55 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr<uint8_t> data)
469514
}
470515
}
471516

472-
void WiFiManager::DisconnectHandler(Platform::UniquePtr<uint8_t>)
517+
void WiFiManager::DisconnectHandler(Platform::UniquePtr<uint8_t> data, size_t length)
473518
{
474-
SystemLayer().ScheduleLambda([] {
519+
// Validate that input data size matches the expected one.
520+
VerifyOrReturn(length == sizeof(wifi_status));
521+
522+
CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] {
523+
Platform::UniquePtr<uint8_t> safePtr(capturedData);
524+
uint8_t * rawData = safePtr.get();
525+
const wifi_status * status = reinterpret_cast<const wifi_status *>(rawData);
526+
uint16_t reason;
527+
528+
switch (status->disconn_reason)
529+
{
530+
case WIFI_REASON_DISCONN_UNSPECIFIED:
531+
reason = WLAN_REASON_UNSPECIFIED;
532+
break;
533+
case WIFI_REASON_DISCONN_USER_REQUEST:
534+
reason = WLAN_REASON_DEAUTH_LEAVING;
535+
break;
536+
case WIFI_REASON_DISCONN_AP_LEAVING:
537+
reason = WLAN_REASON_DEAUTH_LEAVING;
538+
break;
539+
case WIFI_REASON_DISCONN_INACTIVITY:
540+
reason = WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY;
541+
break;
542+
default:
543+
reason = WLAN_REASON_UNSPECIFIED;
544+
break;
545+
}
546+
Instance().SetLastDisconnectReason(reason);
547+
475548
ChipLogProgress(DeviceLayer, "WiFi station disconnected");
476549
Instance().mWiFiState = WIFI_STATE_DISCONNECTED;
477550
Instance().PostConnectivityStatusChange(kConnectivity_Lost);
551+
552+
WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate();
553+
if (delegate)
554+
{
555+
delegate->OnConnectionStatusChanged(
556+
to_underlying(app::Clusters::WiFiNetworkDiagnostics::ConnectionStatusEnum::kNotConnected));
557+
delegate->OnDisconnectionDetected(reason);
558+
}
478559
});
560+
561+
if (CHIP_NO_ERROR == err)
562+
{
563+
// the ownership has been transferred to the worker thread - release the buffer
564+
data.release();
565+
}
479566
}
480567

481568
void WiFiManager::IPv6AddressChangeHandler(const void * data)
@@ -586,5 +673,15 @@ CHIP_ERROR WiFiManager::SetLowPowerMode(bool onoff)
586673
return CHIP_NO_ERROR;
587674
}
588675

676+
void WiFiManager::SetLastDisconnectReason(uint16_t reason)
677+
{
678+
mLastDisconnectedReason = reason;
679+
}
680+
681+
uint16_t WiFiManager::GetLastDisconnectReason()
682+
{
683+
return mLastDisconnectedReason;
684+
}
685+
589686
} // namespace DeviceLayer
590687
} // namespace chip

src/platform/nrfconnect/wifi/WiFiManager.h

+8-5
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,11 @@ class WiFiManager
179179
CHIP_ERROR GetNetworkStatistics(NetworkStatistics & stats) const;
180180
void AbortConnectionRecovery();
181181
CHIP_ERROR SetLowPowerMode(bool onoff);
182+
void SetLastDisconnectReason(uint16_t reason);
183+
uint16_t GetLastDisconnectReason();
182184

183185
private:
184-
using NetEventHandler = void (*)(Platform::UniquePtr<uint8_t>);
186+
using NetEventHandler = void (*)(Platform::UniquePtr<uint8_t>, size_t);
185187

186188
struct ConnectionParams
187189
{
@@ -197,10 +199,10 @@ class WiFiManager
197199
// Event handling
198200
static void WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface);
199201
static void IPv6MgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface);
200-
static void ScanResultHandler(Platform::UniquePtr<uint8_t> data);
201-
static void ScanDoneHandler(Platform::UniquePtr<uint8_t> data);
202-
static void ConnectHandler(Platform::UniquePtr<uint8_t> data);
203-
static void DisconnectHandler(Platform::UniquePtr<uint8_t> data);
202+
static void ScanResultHandler(Platform::UniquePtr<uint8_t> data, size_t length);
203+
static void ScanDoneHandler(Platform::UniquePtr<uint8_t> data, size_t length);
204+
static void ConnectHandler(Platform::UniquePtr<uint8_t> data, size_t length);
205+
static void DisconnectHandler(Platform::UniquePtr<uint8_t> data, size_t length);
204206
static void PostConnectivityStatusChange(ConnectivityChange changeType);
205207
static void SendRouterSolicitation(System::Layer * layer, void * param);
206208
static void IPv6AddressChangeHandler(const void * data);
@@ -234,6 +236,7 @@ class WiFiManager
234236
uint32_t mConnectionRecoveryCounter{ 0 };
235237
uint32_t mConnectionRecoveryTimeMs{ kConnectionRecoveryMinIntervalMs };
236238
bool mApplicationDisconnectRequested{ false };
239+
uint16_t mLastDisconnectedReason = WLAN_REASON_UNSPECIFIED;
237240

238241
static const Map<wifi_iface_state, StationStatus, 10> sStatusMap;
239242
static const Map<uint32_t, NetEventHandler, 5> sEventHandlerMap;

0 commit comments

Comments
 (0)