Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2021 Project CHIP Authors
4 : * Copyright (c) 2018 Nest Labs, Inc.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : #pragma once
20 :
21 : #include <platform/ConnectivityManager.h>
22 : #include <platform/internal/GenericConnectivityManagerImpl.h>
23 : #include <platform/internal/GenericConnectivityManagerImpl_UDP.h>
24 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
25 : #include <platform/internal/GenericConnectivityManagerImpl_TCP.h>
26 : #endif
27 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
28 : #include <platform/internal/GenericConnectivityManagerImpl_BLE.h>
29 : #else
30 : #include <platform/internal/GenericConnectivityManagerImpl_NoBLE.h>
31 : #endif
32 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
33 : #include <platform/internal/GenericConnectivityManagerImpl_Thread.h>
34 : #else
35 : #include <platform/internal/GenericConnectivityManagerImpl_NoThread.h>
36 : #endif
37 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
38 : #include <platform/internal/GenericConnectivityManagerImpl_WiFi.h>
39 : #else
40 : #include <platform/internal/GenericConnectivityManagerImpl_NoWiFi.h>
41 : #endif
42 :
43 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
44 : #include <platform/Linux/dbus/wpa/DBusWpa.h>
45 : #include <platform/Linux/dbus/wpa/DBusWpaBss.h>
46 : #include <platform/Linux/dbus/wpa/DBusWpaInterface.h>
47 : #include <platform/Linux/dbus/wpa/DBusWpaNetwork.h>
48 : #include <system/SystemMutex.h>
49 :
50 : #include <mutex>
51 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
52 : #include <transport/raw/WiFiPAF.h>
53 : #endif
54 : #endif
55 :
56 : #include <platform/Linux/NetworkCommissioningDriver.h>
57 : #include <platform/NetworkCommissioning.h>
58 : #include <vector>
59 :
60 : namespace chip {
61 : namespace Inet {
62 : class IPAddress;
63 : } // namespace Inet
64 : } // namespace chip
65 :
66 : namespace chip {
67 : namespace DeviceLayer {
68 :
69 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
70 : struct GDBusWpaSupplicant
71 : {
72 : enum class WpaState
73 : {
74 : INIT,
75 : CONNECTING,
76 : CONNECTED,
77 : NOT_CONNECTED,
78 : NO_INTERFACE_PATH,
79 : GOT_INTERFACE_PATH,
80 : INTERFACE_CONNECTED,
81 : };
82 :
83 : enum class WpaScanningState
84 : {
85 : IDLE,
86 : SCANNING,
87 : };
88 :
89 : WpaState state = WpaState::INIT;
90 : WpaScanningState scanState = WpaScanningState::IDLE;
91 : WpaFiW1Wpa_supplicant1 * proxy = nullptr;
92 : WpaFiW1Wpa_supplicant1Interface * iface = nullptr;
93 : WpaFiW1Wpa_supplicant1BSS * bss = nullptr;
94 : gchar * interfacePath = nullptr;
95 : gchar * networkPath = nullptr;
96 : };
97 : #endif
98 :
99 : /**
100 : * Concrete implementation of the ConnectivityManager singleton object for Linux platforms.
101 : */
102 : class ConnectivityManagerImpl final : public ConnectivityManager,
103 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
104 : public Internal::GenericConnectivityManagerImpl_BLE<ConnectivityManagerImpl>,
105 : #else
106 : public Internal::GenericConnectivityManagerImpl_NoBLE<ConnectivityManagerImpl>,
107 : #endif
108 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
109 : public Internal::GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>,
110 : #else
111 : public Internal::GenericConnectivityManagerImpl_NoThread<ConnectivityManagerImpl>,
112 : #endif
113 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
114 : public Internal::GenericConnectivityManagerImpl_WiFi<ConnectivityManagerImpl>,
115 : #else
116 : public Internal::GenericConnectivityManagerImpl_NoWiFi<ConnectivityManagerImpl>,
117 : #endif
118 : public Internal::GenericConnectivityManagerImpl_UDP<ConnectivityManagerImpl>,
119 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
120 : public Internal::GenericConnectivityManagerImpl_TCP<ConnectivityManagerImpl>,
121 : #endif
122 : public Internal::GenericConnectivityManagerImpl<ConnectivityManagerImpl>
123 : {
124 : // Allow the ConnectivityManager interface class to delegate method calls to
125 : // the implementation methods provided by this class.
126 : friend class ConnectivityManager;
127 :
128 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
129 : public:
130 : void
131 : SetNetworkStatusChangeCallback(NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * statusChangeCallback)
132 : {
133 : mpStatusChangeCallback = statusChangeCallback;
134 : }
135 :
136 : CHIP_ERROR ConnectWiFiNetworkAsync(ByteSpan ssid, ByteSpan credentials,
137 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback);
138 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
139 : CHIP_ERROR ConnectWiFiNetworkWithPDCAsync(ByteSpan ssid, ByteSpan networkIdentity, ByteSpan clientIdentity,
140 : const Crypto::P256Keypair & clientIdentityKeypair,
141 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback);
142 : #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
143 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
144 : CHIP_ERROR _WiFiPAFConnect(const SetupDiscriminator & connDiscriminator, void * appState, OnConnectionCompleteFunct onSuccess,
145 : OnConnectionErrorFunct onError);
146 : CHIP_ERROR _WiFiPAFCancelConnect();
147 : void OnDiscoveryResult(gboolean success, GVariant * obj);
148 : void OnNanReceive(GVariant * obj);
149 : void OnNanSubscribeTerminated(gint term_subscribe_id, gint reason);
150 : CHIP_ERROR _WiFiPAFSend(chip::System::PacketBufferHandle && msgBuf);
151 : Transport::WiFiPAFBase * _GetWiFiPAF();
152 : void _SetWiFiPAF(Transport::WiFiPAFBase * pWiFiPAF);
153 : #endif
154 :
155 : void PostNetworkConnect();
156 : CHIP_ERROR CommitConfig();
157 :
158 : void StartWiFiManagement();
159 : bool IsWiFiManagementStarted();
160 : void StartNonConcurrentWiFiManagement();
161 : int32_t GetDisconnectReason();
162 : CHIP_ERROR GetWiFiBssId(MutableByteSpan & value);
163 : CHIP_ERROR GetWiFiSecurityType(app::Clusters::WiFiNetworkDiagnostics::SecurityTypeEnum & securityType);
164 : CHIP_ERROR GetWiFiVersion(app::Clusters::WiFiNetworkDiagnostics::WiFiVersionEnum & wiFiVersion);
165 : CHIP_ERROR GetConfiguredNetwork(NetworkCommissioning::Network & network);
166 : CHIP_ERROR StartWiFiScan(ByteSpan ssid, NetworkCommissioning::WiFiDriver::ScanCallback * callback);
167 :
168 : private:
169 : CHIP_ERROR _ConnectWiFiNetworkAsync(GVariant * networkArgs,
170 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback)
171 : CHIP_REQUIRES(mWpaSupplicantMutex);
172 : void _ConnectWiFiNetworkAsyncCallback(GObject * sourceObject, GAsyncResult * res);
173 : #endif
174 :
175 : public:
176 : const char * GetEthernetIfName() { return (mEthIfName[0] == '\0') ? nullptr : mEthIfName; }
177 :
178 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
179 : const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; }
180 : #endif
181 :
182 : private:
183 : // ===== Members that implement the ConnectivityManager abstract interface.
184 :
185 : struct WiFiNetworkScanned
186 : {
187 : // The fields matches WiFiInterfaceScanResult::Type.
188 : uint8_t ssid[Internal::kMaxWiFiSSIDLength];
189 : uint8_t ssidLen;
190 : uint8_t bssid[6];
191 : int8_t rssi;
192 : uint16_t frequencyBand;
193 : uint8_t channel;
194 : uint8_t security;
195 : };
196 :
197 : CHIP_ERROR _Init();
198 : void _OnPlatformEvent(const ChipDeviceEvent * event);
199 :
200 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
201 : WiFiStationMode _GetWiFiStationMode();
202 : CHIP_ERROR _SetWiFiStationMode(ConnectivityManager::WiFiStationMode val);
203 : System::Clock::Timeout _GetWiFiStationReconnectInterval();
204 : CHIP_ERROR _SetWiFiStationReconnectInterval(System::Clock::Timeout val);
205 : bool _IsWiFiStationEnabled();
206 : bool _IsWiFiStationConnected();
207 : bool _IsWiFiStationApplicationControlled();
208 : bool _IsWiFiStationProvisioned();
209 : void _ClearWiFiStationProvision();
210 : bool _CanStartWiFiScan();
211 :
212 : WiFiAPMode _GetWiFiAPMode();
213 : CHIP_ERROR _SetWiFiAPMode(WiFiAPMode val);
214 : bool _IsWiFiAPActive();
215 : bool _IsWiFiAPApplicationControlled();
216 : void _DemandStartWiFiAP();
217 : void _StopOnDemandWiFiAP();
218 : void _MaintainOnDemandWiFiAP();
219 : System::Clock::Timeout _GetWiFiAPIdleTimeout();
220 : void _SetWiFiAPIdleTimeout(System::Clock::Timeout val);
221 : void UpdateNetworkStatus();
222 : CHIP_ERROR StopAutoScan();
223 :
224 : void _OnWpaProxyReady(GObject * sourceObject, GAsyncResult * res);
225 : void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties);
226 : void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties);
227 : void _OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * properties);
228 : void _OnWpaInterfaceScanDone(WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success);
229 : void _OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res);
230 : void _OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res);
231 : void _OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res);
232 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
233 : struct wpa_dbus_discov_info
234 : {
235 : uint32_t subscribe_id;
236 : uint32_t peer_publish_id;
237 : uint8_t peer_addr[6];
238 : uint32_t ssi_len;
239 : };
240 : uint32_t mpresubscribe_id;
241 : struct wpa_dbus_discov_info mpaf_info;
242 : struct wpa_dbus_nanrx_info
243 : {
244 : uint32_t id;
245 : uint32_t peer_id;
246 : uint8_t peer_addr[6];
247 : uint32_t ssi_len;
248 : };
249 : struct wpa_dbus_nanrx_info mpaf_nanrx_info;
250 :
251 : OnConnectionCompleteFunct mOnPafSubscribeComplete;
252 : OnConnectionErrorFunct mOnPafSubscribeError;
253 : Transport::WiFiPAFBase * pmWiFiPAF;
254 : void * mAppState;
255 : CHIP_ERROR _SetWiFiPAFAdvertisingEnabled(WiFiPAFAdvertiseParam & args);
256 : CHIP_ERROR _WiFiPAFPublish(WiFiPAFAdvertiseParam & args);
257 : CHIP_ERROR _WiFiPAFCancelPublish();
258 : #endif
259 :
260 : bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result);
261 :
262 : CHIP_ERROR _StartWiFiManagement();
263 :
264 : bool mAssociationStarted = false;
265 : BitFlags<ConnectivityFlags> mConnectivityFlag;
266 : GDBusWpaSupplicant mWpaSupplicant CHIP_GUARDED_BY(mWpaSupplicantMutex);
267 : // Access to mWpaSupplicant has to be protected by a mutex because it is accessed from
268 : // the CHIP event loop thread and dedicated D-Bus thread started by platform manager.
269 : std::mutex mWpaSupplicantMutex;
270 :
271 : NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr;
272 : #endif
273 :
274 : // ==================== ConnectivityManager Private Methods ====================
275 :
276 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
277 : void DriveAPState();
278 : CHIP_ERROR ConfigureWiFiAP();
279 : void ChangeWiFiAPState(WiFiAPState newState);
280 : static void DriveAPState(::chip::System::Layer * aLayer, void * aAppState);
281 : #endif
282 :
283 : // ===== Members for internal use by the following friends.
284 :
285 : friend ConnectivityManager & ConnectivityMgr();
286 : friend ConnectivityManagerImpl & ConnectivityMgrImpl();
287 :
288 : static ConnectivityManagerImpl sInstance;
289 :
290 : // ===== Private members reserved for use by this class only.
291 :
292 : char mEthIfName[IFNAMSIZ];
293 :
294 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
295 : ConnectivityManager::WiFiStationMode mWiFiStationMode;
296 : ConnectivityManager::WiFiAPMode mWiFiAPMode;
297 : WiFiAPState mWiFiAPState;
298 : System::Clock::Timestamp mLastAPDemandTime;
299 : System::Clock::Timeout mWiFiStationReconnectInterval;
300 : System::Clock::Timeout mWiFiAPIdleTimeout;
301 : #endif
302 :
303 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
304 : char sWiFiIfName[IFNAMSIZ];
305 : #endif
306 :
307 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
308 : uint8_t sInterestedSSID[Internal::kMaxWiFiSSIDLength];
309 : uint8_t sInterestedSSIDLen;
310 : #endif
311 : NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback;
312 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback;
313 : };
314 :
315 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
316 : inline ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::_GetWiFiAPMode()
317 : {
318 : return mWiFiAPMode;
319 : }
320 :
321 : inline bool ConnectivityManagerImpl::_IsWiFiAPActive()
322 : {
323 : return mWiFiAPState == kWiFiAPState_Active;
324 : }
325 :
326 : inline bool ConnectivityManagerImpl::_IsWiFiAPApplicationControlled()
327 : {
328 : return mWiFiAPMode == kWiFiAPMode_ApplicationControlled;
329 : }
330 :
331 : inline System::Clock::Timeout ConnectivityManagerImpl::_GetWiFiAPIdleTimeout()
332 : {
333 : return mWiFiAPIdleTimeout;
334 : }
335 :
336 : #endif
337 :
338 : /**
339 : * Returns the public interface of the ConnectivityManager singleton object.
340 : *
341 : * chip applications should use this to access features of the ConnectivityManager object
342 : * that are common to all platforms.
343 : */
344 183 : inline ConnectivityManager & ConnectivityMgr()
345 : {
346 183 : return ConnectivityManagerImpl::sInstance;
347 : }
348 :
349 : /**
350 : * Returns the platform-specific implementation of the ConnectivityManager singleton object.
351 : *
352 : * chip applications can use this to gain access to features of the ConnectivityManager
353 : * that are specific to the ESP32 platform.
354 : */
355 : inline ConnectivityManagerImpl & ConnectivityMgrImpl()
356 : {
357 : return ConnectivityManagerImpl::sInstance;
358 : }
359 :
360 : } // namespace DeviceLayer
361 : } // namespace chip
|