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/GLibTypeDeleter.h>
45 : #include <platform/Linux/dbus/wpa/DBusWpa.h>
46 : #include <platform/Linux/dbus/wpa/DBusWpaBss.h>
47 : #include <platform/Linux/dbus/wpa/DBusWpaInterface.h>
48 : #include <platform/Linux/dbus/wpa/DBusWpaNetwork.h>
49 : #include <system/SystemMutex.h>
50 :
51 : #include <mutex>
52 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
53 : #include <wifipaf/WiFiPAFEndPoint.h>
54 : #include <wifipaf/WiFiPAFLayer.h>
55 : #endif
56 : #endif
57 :
58 : #include <platform/Linux/NetworkCommissioningDriver.h>
59 : #include <platform/NetworkCommissioning.h>
60 : #include <vector>
61 :
62 : namespace chip {
63 :
64 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
65 :
66 : template <>
67 : struct GAutoPtrDeleter<WpaSupplicant1>
68 : {
69 : using deleter = GObjectDeleter;
70 : };
71 :
72 : template <>
73 : struct GAutoPtrDeleter<WpaSupplicant1BSS>
74 : {
75 : using deleter = GObjectDeleter;
76 : };
77 :
78 : template <>
79 : struct GAutoPtrDeleter<WpaSupplicant1Interface>
80 : {
81 : using deleter = GObjectDeleter;
82 : };
83 :
84 : template <>
85 : struct GAutoPtrDeleter<WpaSupplicant1Network>
86 : {
87 : using deleter = GObjectDeleter;
88 : };
89 :
90 : #endif // CHIP_DEVICE_CONFIG_ENABLE_WPA
91 :
92 : namespace DeviceLayer {
93 :
94 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
95 : struct GDBusWpaSupplicant
96 : {
97 : enum class WpaState
98 : {
99 : INIT,
100 : CONNECTING,
101 : CONNECTED,
102 : NOT_CONNECTED,
103 : NO_INTERFACE_PATH,
104 : GOT_INTERFACE_PATH,
105 : INTERFACE_CONNECTED,
106 : };
107 :
108 : enum class WpaScanningState
109 : {
110 : IDLE,
111 : SCANNING,
112 : };
113 :
114 : WpaState state = WpaState::INIT;
115 : WpaScanningState scanState = WpaScanningState::IDLE;
116 : GAutoPtr<WpaSupplicant1> proxy;
117 : GAutoPtr<WpaSupplicant1Interface> iface;
118 : GAutoPtr<WpaSupplicant1BSS> bss;
119 : GAutoPtr<char> interfacePath;
120 : GAutoPtr<char> networkPath;
121 : };
122 : #endif
123 :
124 : /**
125 : * Concrete implementation of the ConnectivityManager singleton object for Linux platforms.
126 : */
127 : class ConnectivityManagerImpl final : public ConnectivityManager,
128 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
129 : public Internal::GenericConnectivityManagerImpl_BLE<ConnectivityManagerImpl>,
130 : #else
131 : public Internal::GenericConnectivityManagerImpl_NoBLE<ConnectivityManagerImpl>,
132 : #endif
133 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
134 : public Internal::GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>,
135 : #else
136 : public Internal::GenericConnectivityManagerImpl_NoThread<ConnectivityManagerImpl>,
137 : #endif
138 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
139 : public Internal::GenericConnectivityManagerImpl_WiFi<ConnectivityManagerImpl>,
140 : #else
141 : public Internal::GenericConnectivityManagerImpl_NoWiFi<ConnectivityManagerImpl>,
142 : #endif
143 : public Internal::GenericConnectivityManagerImpl_UDP<ConnectivityManagerImpl>,
144 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
145 : public Internal::GenericConnectivityManagerImpl_TCP<ConnectivityManagerImpl>,
146 : #endif
147 : public Internal::GenericConnectivityManagerImpl<ConnectivityManagerImpl>
148 : {
149 : // Allow the ConnectivityManager interface class to delegate method calls to
150 : // the implementation methods provided by this class.
151 : friend class ConnectivityManager;
152 :
153 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
154 : public:
155 : void
156 : SetNetworkStatusChangeCallback(NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * statusChangeCallback)
157 : {
158 : mpStatusChangeCallback = statusChangeCallback;
159 : }
160 :
161 : CHIP_ERROR ConnectWiFiNetworkAsync(ByteSpan ssid, ByteSpan credentials,
162 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback);
163 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
164 : CHIP_ERROR ConnectWiFiNetworkWithPDCAsync(ByteSpan ssid, ByteSpan networkIdentity, ByteSpan clientIdentity,
165 : const Crypto::P256Keypair & clientIdentityKeypair,
166 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback);
167 : #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
168 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
169 : CHIP_ERROR _WiFiPAFSubscribe(const uint16_t & connDiscriminator, void * appState, OnConnectionCompleteFunct onSuccess,
170 : OnConnectionErrorFunct onError);
171 : CHIP_ERROR _WiFiPAFCancelSubscribe(uint32_t SubscribeId);
172 : CHIP_ERROR _WiFiPAFCancelIncompleteSubscribe();
173 : void OnDiscoveryResult(GVariant * obj);
174 : void OnReplied(GVariant * obj);
175 : void OnNanReceive(GVariant * obj);
176 : void OnNanPublishTerminated(guint public_id, gchar * reason);
177 : void OnNanSubscribeTerminated(guint subscribe_id, gchar * reason);
178 : CHIP_ERROR _WiFiPAFSend(const WiFiPAF::WiFiPAFSession & TxInfo, chip::System::PacketBufferHandle && msgBuf);
179 : void _WiFiPafSetApFreq(const uint16_t freq) { mApFreq = freq; }
180 : CHIP_ERROR _WiFiPAFShutdown(uint32_t id, WiFiPAF::WiFiPafRole role);
181 : #endif
182 :
183 : void PostNetworkConnect();
184 : CHIP_ERROR CommitConfig();
185 :
186 : void StartWiFiManagement();
187 : bool IsWiFiManagementStarted();
188 : void StartNonConcurrentWiFiManagement();
189 : int32_t GetDisconnectReason();
190 : CHIP_ERROR GetWiFiBssId(MutableByteSpan & value);
191 : CHIP_ERROR GetWiFiSecurityType(app::Clusters::WiFiNetworkDiagnostics::SecurityTypeEnum & securityType);
192 : CHIP_ERROR GetWiFiVersion(app::Clusters::WiFiNetworkDiagnostics::WiFiVersionEnum & wiFiVersion);
193 : CHIP_ERROR GetConfiguredNetwork(NetworkCommissioning::Network & network);
194 : CHIP_ERROR StartWiFiScan(ByteSpan ssid, NetworkCommissioning::WiFiDriver::ScanCallback * callback);
195 :
196 : private:
197 : CHIP_ERROR _ConnectWiFiNetworkAsync(GVariant * networkArgs,
198 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback)
199 : CHIP_REQUIRES(mWpaSupplicantMutex);
200 : void _ConnectWiFiNetworkAsyncCallback(GObject * sourceObject, GAsyncResult * res);
201 : #endif
202 :
203 : public:
204 : const char * GetEthernetIfName() { return (mEthIfName[0] == '\0') ? nullptr : mEthIfName; }
205 :
206 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
207 : const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; }
208 : #endif
209 :
210 : private:
211 : // ===== Members that implement the ConnectivityManager abstract interface.
212 :
213 : struct WiFiNetworkScanned
214 : {
215 : // The fields matches WiFiInterfaceScanResult::Type.
216 : uint8_t ssid[Internal::kMaxWiFiSSIDLength];
217 : uint8_t ssidLen;
218 : uint8_t bssid[6];
219 : int8_t rssi;
220 : uint16_t frequencyBand;
221 : uint8_t channel;
222 : uint8_t security;
223 : };
224 :
225 : CHIP_ERROR _Init();
226 : void _OnPlatformEvent(const ChipDeviceEvent * event);
227 :
228 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
229 : WiFiStationMode _GetWiFiStationMode();
230 : CHIP_ERROR _SetWiFiStationMode(ConnectivityManager::WiFiStationMode val);
231 : System::Clock::Timeout _GetWiFiStationReconnectInterval();
232 : CHIP_ERROR _SetWiFiStationReconnectInterval(System::Clock::Timeout val);
233 : bool _IsWiFiStationEnabled();
234 : bool _IsWiFiStationConnected();
235 : bool _IsWiFiStationApplicationControlled();
236 : bool _IsWiFiStationProvisioned();
237 : void _ClearWiFiStationProvision();
238 : bool _CanStartWiFiScan();
239 :
240 : WiFiAPMode _GetWiFiAPMode();
241 : CHIP_ERROR _SetWiFiAPMode(WiFiAPMode val);
242 : bool _IsWiFiAPActive();
243 : bool _IsWiFiAPApplicationControlled();
244 : void _DemandStartWiFiAP();
245 : void _StopOnDemandWiFiAP();
246 : void _MaintainOnDemandWiFiAP();
247 : System::Clock::Timeout _GetWiFiAPIdleTimeout();
248 : void _SetWiFiAPIdleTimeout(System::Clock::Timeout val);
249 : void UpdateNetworkStatus();
250 : CHIP_ERROR StopAutoScan();
251 :
252 : void _OnWpaProxyReady(GObject * sourceObject, GAsyncResult * res);
253 : void _OnWpaInterfaceRemoved(WpaSupplicant1 * proxy, const char * path);
254 : void _OnWpaInterfaceAdded(WpaSupplicant1 * proxy, const char * path, GVariant * properties);
255 : void _OnWpaPropertiesChanged(WpaSupplicant1Interface * proxy, GVariant * properties);
256 : void _OnWpaInterfaceScanDone(WpaSupplicant1Interface * proxy, gboolean success);
257 : void _OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res);
258 : void _OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res);
259 : void _OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res);
260 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
261 : OnConnectionCompleteFunct mOnPafSubscribeComplete;
262 : OnConnectionErrorFunct mOnPafSubscribeError;
263 : WiFiPAF::WiFiPAFLayer * pmWiFiPAF;
264 : WiFiPAF::WiFiPAFEndPoint mWiFiPAFEndPoint;
265 : void * mAppState;
266 : uint16_t mApFreq;
267 : CHIP_ERROR _WiFiPAFPublish(WiFiPAFAdvertiseParam & args);
268 : CHIP_ERROR _WiFiPAFCancelPublish(uint32_t PublishId);
269 : #endif
270 :
271 : bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result);
272 :
273 : CHIP_ERROR _StartWiFiManagement();
274 :
275 : bool mAssociationStarted = false;
276 : BitFlags<ConnectivityFlags> mConnectivityFlag;
277 : GDBusWpaSupplicant mWpaSupplicant CHIP_GUARDED_BY(mWpaSupplicantMutex);
278 : // Access to mWpaSupplicant has to be protected by a mutex because it is accessed from
279 : // the CHIP event loop thread and dedicated D-Bus thread started by platform manager.
280 : std::mutex mWpaSupplicantMutex;
281 :
282 : NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr;
283 : #endif
284 :
285 : // ==================== ConnectivityManager Private Methods ====================
286 :
287 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
288 : void DriveAPState();
289 : CHIP_ERROR ConfigureWiFiAP();
290 : void ChangeWiFiAPState(WiFiAPState newState);
291 : static void DriveAPState(::chip::System::Layer * aLayer, void * aAppState);
292 : #endif
293 :
294 : // ===== Members for internal use by the following friends.
295 :
296 : friend ConnectivityManager & ConnectivityMgr();
297 : friend ConnectivityManagerImpl & ConnectivityMgrImpl();
298 :
299 : static ConnectivityManagerImpl sInstance;
300 :
301 : // ===== Private members reserved for use by this class only.
302 :
303 : char mEthIfName[Inet::InterfaceId::kMaxIfNameLength];
304 :
305 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
306 : ConnectivityManager::WiFiStationMode mWiFiStationMode;
307 : ConnectivityManager::WiFiAPMode mWiFiAPMode;
308 : WiFiAPState mWiFiAPState;
309 : System::Clock::Timestamp mLastAPDemandTime;
310 : System::Clock::Timeout mWiFiStationReconnectInterval;
311 : System::Clock::Timeout mWiFiAPIdleTimeout;
312 : #endif
313 :
314 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
315 : char sWiFiIfName[Inet::InterfaceId::kMaxIfNameLength];
316 : #endif
317 :
318 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
319 : uint8_t sInterestedSSID[Internal::kMaxWiFiSSIDLength];
320 : uint8_t sInterestedSSIDLen;
321 : #endif
322 : NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback;
323 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback;
324 : };
325 :
326 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
327 : inline ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::_GetWiFiAPMode()
328 : {
329 : return mWiFiAPMode;
330 : }
331 :
332 : inline bool ConnectivityManagerImpl::_IsWiFiAPActive()
333 : {
334 : return mWiFiAPState == kWiFiAPState_Active;
335 : }
336 :
337 : inline bool ConnectivityManagerImpl::_IsWiFiAPApplicationControlled()
338 : {
339 : return mWiFiAPMode == kWiFiAPMode_ApplicationControlled;
340 : }
341 :
342 : inline System::Clock::Timeout ConnectivityManagerImpl::_GetWiFiAPIdleTimeout()
343 : {
344 : return mWiFiAPIdleTimeout;
345 : }
346 :
347 : #endif
348 :
349 : /**
350 : * Returns the public interface of the ConnectivityManager singleton object.
351 : *
352 : * chip applications should use this to access features of the ConnectivityManager object
353 : * that are common to all platforms.
354 : */
355 54 : inline ConnectivityManager & ConnectivityMgr()
356 : {
357 54 : return ConnectivityManagerImpl::sInstance;
358 : }
359 :
360 : /**
361 : * Returns the platform-specific implementation of the ConnectivityManager singleton object.
362 : *
363 : * chip applications can use this to gain access to features of the ConnectivityManager
364 : * that are specific to the ESP32 platform.
365 : */
366 0 : inline ConnectivityManagerImpl & ConnectivityMgrImpl()
367 : {
368 0 : return ConnectivityManagerImpl::sInstance;
369 : }
370 :
371 : } // namespace DeviceLayer
372 : } // namespace chip
|