Skip to content

Commit fa956ce

Browse files
authored
Add and Leverage Linux Connectivity Callback Introspection, Mutation, and Action Delegation Methods (project-chip#43062)
* Rename 'mpScanCallback' to 'mpOneShotScanCallback'. This more accurately reflects its set-scan-and-clear usage. * Documentation: Document the 'mpOneShotScanCallback' data member. * Rename 'mpConnectCallback' to 'mpOneShotConnectCallback'. This more accurately reflects its set-connect-and-clear usage. * Documentation: Document the 'mpOneShotConnectCallback' data member. * Added network commissioning-related action delegation methods. These three methods consolidate the handling and dispatch of scan, connect, and network status change action delegation callback invocation and, for scan and connect, post-invocation nullification. * Add parallel setters for all scan, connect, and status change callbacks. This not only makes it easier to keep callback members private as implementations fan out from the current, single wpa_supplicant implementation but also reduces duplication among those implementations for common callback-related operations. * Initialize callbacks in the explicit initializer only. Previously, the status change callback was initialized with a default initializer and the connect and scan callbacks were initialized in the explicit initializer. With this change, all three are now initialized in the explicit initializer. * Added two connect- and scan-related callback introspection methods. * Leverage callback introspection, mutation, and action delegation methods.
1 parent 045f879 commit fa956ce

3 files changed

Lines changed: 123 additions & 47 deletions

File tree

src/platform/Linux/ConnectivityManagerImpl.cpp

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@ ConnectivityManagerImpl & ConnectivityManagerImpl::GetDefaultInstance()
6363
return sInstance;
6464
}
6565

66+
// Linux Implementation-specific Methods
67+
68+
// Mutation
69+
70+
void ConnectivityManagerImpl::SetOneShotConnectCallback(OneShotConnectCallback * inOneShotConnectCallback) noexcept
71+
{
72+
mpOneShotConnectCallback = inOneShotConnectCallback;
73+
}
74+
75+
void ConnectivityManagerImpl::SetOneShotScanCallback(OneShotScanCallback * inOneShotScanCallback) noexcept
76+
{
77+
mpOneShotScanCallback = inOneShotScanCallback;
78+
}
79+
80+
void ConnectivityManagerImpl::SetNetworkStatusChangeCallback(NetworkStatusChangeCallback * inStatusChangeCallback) noexcept
81+
{
82+
mpStatusChangeCallback = inStatusChangeCallback;
83+
}
84+
6685
void ConnectivityManagerImpl::UpdateEthernetNetworkingStatus()
6786
{
6887
if (mpStatusChangeCallback != nullptr)
@@ -82,8 +101,9 @@ CHIP_ERROR ConnectivityManagerImpl::_Init()
82101
mWiFiStationMode = kWiFiStationMode_Disabled;
83102
mWiFiStationReconnectInterval = System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_WIFI_STATION_RECONNECT_INTERVAL);
84103
#endif
85-
mpConnectCallback = nullptr;
86-
mpScanCallback = nullptr;
104+
SetNetworkStatusChangeCallback(nullptr);
105+
SetOneShotConnectCallback(nullptr);
106+
SetOneShotScanCallback(nullptr);
87107

88108
if (ConnectivityUtils::GetEthInterfaceName(mEthIfName, Inet::InterfaceId::kMaxIfNameLength) == CHIP_NO_ERROR)
89109
{
@@ -128,6 +148,18 @@ CHIP_ERROR ConnectivityManagerImpl::_Init()
128148
#endif
129149
}
130150

151+
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
152+
bool ConnectivityManagerImpl::IsWiFiStationConnecting() const noexcept
153+
{
154+
return mpOneShotConnectCallback != nullptr;
155+
}
156+
157+
bool ConnectivityManagerImpl::IsWiFiStationScanning() const noexcept
158+
{
159+
return mpOneShotScanCallback != nullptr;
160+
}
161+
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
162+
131163
void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
132164
{
133165
// Forward the event to the generic base classes as needed.
@@ -179,5 +211,35 @@ ConnectivityManagerImpl & ConnectivityMgrImpl(void)
179211
return ConnectivityManagerImpl::GetDefaultInstance();
180212
}
181213

214+
// Network Commissioning Action Delegation Methods
215+
216+
void ConnectivityManagerImpl::OnScanFinished(NetworkCommissioning::Status inStatus, CharSpan inDebugText,
217+
NetworkCommissioning::WiFiScanResponseIterator * inNetworks) noexcept
218+
{
219+
VerifyOrReturn(mpOneShotScanCallback != nullptr);
220+
221+
mpOneShotScanCallback->OnFinished(inStatus, inDebugText, inNetworks);
222+
223+
mpOneShotScanCallback = nullptr;
224+
}
225+
226+
void ConnectivityManagerImpl::OnConnectResult(NetworkCommissioning::Status inCommissioningError, CharSpan inDebugText,
227+
int32_t inConnectStatus) noexcept
228+
{
229+
VerifyOrReturn(mpOneShotConnectCallback != nullptr);
230+
231+
mpOneShotConnectCallback->OnResult(inCommissioningError, inDebugText, inConnectStatus);
232+
233+
mpOneShotConnectCallback = nullptr;
234+
}
235+
236+
void ConnectivityManagerImpl::OnStatusChange(NetworkCommissioning::Status inCommissioningError, Optional<ByteSpan> inNetworkId,
237+
Optional<int32_t> inConnectStatus) noexcept
238+
{
239+
VerifyOrReturn(mpStatusChangeCallback != nullptr);
240+
241+
mpStatusChangeCallback->OnNetworkingStatusChange(inCommissioningError, inNetworkId, inConnectStatus);
242+
}
243+
182244
} // namespace DeviceLayer
183245
} // namespace chip

src/platform/Linux/ConnectivityManagerImpl.h

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,13 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
183183
const char * GetEthernetIfName() { return (mEthIfName[0] == '\0') ? nullptr : mEthIfName; }
184184
void UpdateEthernetNetworkingStatus();
185185

186-
void
187-
SetNetworkStatusChangeCallback(NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * statusChangeCallback)
188-
{
189-
mpStatusChangeCallback = statusChangeCallback;
190-
}
186+
using NetworkStatusChangeCallback = NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback;
187+
using OneShotScanCallback = NetworkCommissioning::WiFiDriver::ScanCallback;
188+
using OneShotConnectCallback = NetworkCommissioning::Internal::WirelessDriver::ConnectCallback;
189+
190+
void SetOneShotConnectCallback(OneShotConnectCallback * inOneShotConnectCallback) noexcept;
191+
void SetOneShotScanCallback(OneShotScanCallback * inOneShotScanCallback) noexcept;
192+
void SetNetworkStatusChangeCallback(NetworkStatusChangeCallback * inStatusChangeCallback) noexcept;
191193

192194
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
193195
const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; }
@@ -199,6 +201,11 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
199201
CHIP_ERROR _Init();
200202
void _OnPlatformEvent(const ChipDeviceEvent * event);
201203

204+
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
205+
bool IsWiFiStationConnecting() const noexcept;
206+
bool IsWiFiStationScanning() const noexcept;
207+
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
208+
202209
#if CHIP_DEVICE_CONFIG_ENABLE_WPA
203210
WiFiStationMode _GetWiFiStationMode();
204211
CHIP_ERROR _SetWiFiStationMode(ConnectivityManager::WiFiStationMode val);
@@ -256,7 +263,13 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
256263
std::mutex mWpaSupplicantMutex;
257264

258265
#endif
259-
NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr;
266+
// Network Commissioning Action Delegation Methods
267+
268+
void OnScanFinished(NetworkCommissioning::Status inStatus, CharSpan inDebugText,
269+
NetworkCommissioning::WiFiScanResponseIterator * inNetworks) noexcept;
270+
void OnConnectResult(NetworkCommissioning::Status inCommissioningError, CharSpan inDebugText, int32_t inConnectStatus) noexcept;
271+
void OnStatusChange(NetworkCommissioning::Status inCommissioningError, Optional<ByteSpan> inNetworkId,
272+
Optional<int32_t> inConnectStatus) noexcept;
260273

261274
// ==================== ConnectivityManager Private Methods ====================
262275

@@ -287,8 +300,27 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
287300
#if CHIP_DEVICE_CONFIG_ENABLE_WPA
288301
Internal::WiFiSSIDFixedBuffer mInterestedSSID;
289302
#endif
290-
NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback;
291-
NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback;
303+
/**
304+
* A callback through which, when non-null, the Wi-Fi driver
305+
* 'OnFinished' method is invoked after a Wi-Fi scan is
306+
* complete. The semantics of this callback are one-shot in that
307+
* it is set-scan-invoke-and-clear.
308+
*
309+
* A non-null value implies that a Wi-Fi scan is in progress.
310+
*/
311+
OneShotScanCallback * mpOneShotScanCallback;
312+
313+
/**
314+
* A callback through which, when non-null, the wireless driver
315+
* 'OnResult' method is invoked after a Wi-Fi association is
316+
* complete. The semantics of this callback are one-shot in that
317+
* it is set-associate-invoke-and-clear.
318+
*
319+
* A non-null value implies that a Wi-Fi association is in
320+
* progress.
321+
*/
322+
OneShotConnectCallback * mpOneShotConnectCallback;
323+
NetworkStatusChangeCallback * mpStatusChangeCallback;
292324
};
293325

294326
#if CHIP_DEVICE_CONFIG_ENABLE_WPA

src/platform/Linux/ConnectivityManagerImpl_NetworkManagementWpaSupplicant.cpp

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ void ConnectivityManagerImpl::UpdateNetworkStatus()
245245
{
246246
Network configuredNetwork;
247247

248-
VerifyOrReturn(IsWiFiStationEnabled() && mpStatusChangeCallback != nullptr);
248+
VerifyOrReturn(IsWiFiStationEnabled());
249249

250250
CHIP_ERROR err = GetConfiguredNetwork(configuredNetwork);
251251
if (err != CHIP_NO_ERROR)
@@ -257,14 +257,13 @@ void ConnectivityManagerImpl::UpdateNetworkStatus()
257257
// If we have already connected to the WiFi AP, then return null to indicate a success state.
258258
if (IsWiFiStationConnected())
259259
{
260-
mpStatusChangeCallback->OnNetworkingStatusChange(
261-
Status::kSuccess, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)), NullOptional);
260+
OnStatusChange(Status::kSuccess, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)),
261+
NullOptional);
262262
return;
263263
}
264264

265-
mpStatusChangeCallback->OnNetworkingStatusChange(
266-
Status::kUnknownError, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)),
267-
MakeOptional(GetDisconnectReason()));
265+
OnStatusChange(Status::kUnknownError, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)),
266+
MakeOptional(GetDisconnectReason()));
268267
}
269268

270269
void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaSupplicant1Interface * iface, GVariant * changedProperties)
@@ -350,13 +349,8 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaSupplicant1Interface *
350349
break;
351350
}
352351

353-
TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().ScheduleLambda([this, reason]() {
354-
if (mpConnectCallback != nullptr)
355-
{
356-
mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), reason);
357-
mpConnectCallback = nullptr;
358-
}
359-
});
352+
TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().ScheduleLambda(
353+
[this, reason]() { OnConnectResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), reason); });
360354
if (delegate != nullptr)
361355
{
362356
TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().ScheduleLambda([delegate, associationFailureCause, status]() {
@@ -384,11 +378,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaSupplicant1Interface *
384378
if (mAssociationStarted)
385379
{
386380
TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().ScheduleLambda([this]() {
387-
if (mpConnectCallback != nullptr)
388-
{
389-
mpConnectCallback->OnResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0);
390-
mpConnectCallback = nullptr;
391-
}
381+
OnConnectResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0);
392382
ConnectivityMgrImpl().PostNetworkConnect();
393383
});
394384
}
@@ -875,7 +865,7 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args,
875865
// Network was provisioned successfully - emit a connectivity change event so the application can update its state.
876866
NotifyWiFiConnectivityChange(kConnectivity_NoChange);
877867

878-
mpConnectCallback = apCallback;
868+
SetOneShotConnectCallback(apCallback);
879869
return CHIP_NO_ERROR;
880870
}
881871

@@ -893,7 +883,7 @@ ConnectivityManagerImpl::ConnectWiFiNetworkAsync(ByteSpan ssid, ByteSpan credent
893883
VerifyOrReturnError(mWpaSupplicant.iface, CHIP_ERROR_INCORRECT_STATE);
894884

895885
// There is another ongoing connect request, reject the new one.
896-
VerifyOrReturnError(mpConnectCallback == nullptr, CHIP_ERROR_INCORRECT_STATE);
886+
VerifyOrReturnError(!IsWiFiStationConnecting(), CHIP_ERROR_INCORRECT_STATE);
897887

898888
GVariantBuilder builder;
899889
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
@@ -948,7 +938,7 @@ CHIP_ERROR ConnectivityManagerImpl::ConnectWiFiNetworkWithPDCAsync(
948938
VerifyOrReturnError(mWpaSupplicant.iface, CHIP_ERROR_INCORRECT_STATE);
949939

950940
// There is another ongoing connect request, reject the new one.
951-
VerifyOrReturnError(mpConnectCallback == nullptr, CHIP_ERROR_INCORRECT_STATE);
941+
VerifyOrReturnError(!IsWiFiStationConnecting(), CHIP_ERROR_INCORRECT_STATE);
952942

953943
// Convert identities and our key pair to DER and add them to wpa_supplicant as blobs
954944
{
@@ -1269,7 +1259,7 @@ CHIP_ERROR ConnectivityManagerImpl::StartWiFiScan(ByteSpan ssid, WiFiDriver::Sca
12691259
std::lock_guard<std::mutex> lock(mWpaSupplicantMutex);
12701260
VerifyOrReturnError(mWpaSupplicant.iface, CHIP_ERROR_INCORRECT_STATE);
12711261
// There is another ongoing scan request, reject the new one.
1272-
VerifyOrReturnError(mpScanCallback == nullptr, CHIP_ERROR_INCORRECT_STATE);
1262+
VerifyOrReturnError(!IsWiFiStationScanning(), CHIP_ERROR_INCORRECT_STATE);
12731263
VerifyOrReturnError(ssid.size() <= mInterestedSSID.capacity(), CHIP_ERROR_INVALID_ARGUMENT);
12741264

12751265
GAutoPtr<GError> err;
@@ -1282,11 +1272,11 @@ CHIP_ERROR ConnectivityManagerImpl::StartWiFiScan(ByteSpan ssid, WiFiDriver::Sca
12821272
g_variant_builder_add(&builder, "{sv}", "Type", g_variant_new_string("active"));
12831273
args = g_variant_builder_end(&builder);
12841274

1285-
mpScanCallback = callback;
1275+
SetOneShotScanCallback(callback);
12861276
if (!wpa_supplicant_1_interface_call_scan_sync(mWpaSupplicant.iface.get(), args, nullptr, &err.GetReceiver()))
12871277
{
12881278
ChipLogProgress(DeviceLayer, "wpa_supplicant: failed to start network scan: %s", err ? err->message : "unknown error");
1289-
mpScanCallback = nullptr;
1279+
SetOneShotScanCallback(nullptr);
12901280
return CHIP_ERROR_INTERNAL;
12911281
}
12921282

@@ -1570,13 +1560,8 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(WpaSupplicant1Interface *
15701560
if (bsss == nullptr)
15711561
{
15721562
ChipLogProgress(DeviceLayer, "wpa_supplicant: no network found");
1573-
TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().ScheduleLambda([this]() {
1574-
if (mpScanCallback != nullptr)
1575-
{
1576-
mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), nullptr);
1577-
mpScanCallback = nullptr;
1578-
}
1579-
});
1563+
TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().ScheduleLambda(
1564+
[this]() { OnScanFinished(Status::kSuccess, CharSpan(), nullptr); });
15801565
return;
15811566
}
15821567

@@ -1597,12 +1582,9 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(WpaSupplicant1Interface *
15971582

15981583
TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().ScheduleLambda([this, networkScanned]() {
15991584
// Note: We cannot post an event in ScheduleLambda since std::vector is not trivial copyable.
1600-
if (mpScanCallback != nullptr)
1601-
{
1602-
LinuxScanResponseIterator<WiFiScanResponse> iter(networkScanned);
1603-
mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), &iter);
1604-
mpScanCallback = nullptr;
1605-
}
1585+
LinuxScanResponseIterator<WiFiScanResponse> iter(networkScanned);
1586+
1587+
OnScanFinished(Status::kSuccess, CharSpan(), &iter);
16061588

16071589
delete networkScanned;
16081590
});

0 commit comments

Comments
 (0)