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 : #endif
52 :
53 : #include <platform/Linux/NetworkCommissioningDriver.h>
54 : #include <platform/NetworkCommissioning.h>
55 : #include <vector>
56 :
57 : namespace chip {
58 : namespace Inet {
59 : class IPAddress;
60 : } // namespace Inet
61 : } // namespace chip
62 :
63 : namespace chip {
64 : namespace DeviceLayer {
65 :
66 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
67 : struct GDBusWpaSupplicant
68 : {
69 : enum WpaState
70 : {
71 : INIT,
72 : WPA_CONNECTING,
73 : WPA_CONNECTED,
74 : WPA_NOT_CONNECTED,
75 : WPA_NO_INTERFACE_PATH,
76 : WPA_GOT_INTERFACE_PATH,
77 : WPA_INTERFACE_CONNECTED,
78 : };
79 :
80 : enum WpaScanning
81 : {
82 : WIFI_SCANNING_IDLE,
83 : WIFI_SCANNING,
84 : };
85 :
86 : WpaState state = INIT;
87 : WpaScanning scanState = WIFI_SCANNING_IDLE;
88 : WpaFiW1Wpa_supplicant1 * proxy = nullptr;
89 : WpaFiW1Wpa_supplicant1Interface * iface = nullptr;
90 : WpaFiW1Wpa_supplicant1BSS * bss = nullptr;
91 : gchar * interfacePath = nullptr;
92 : gchar * networkPath = nullptr;
93 : };
94 : #endif
95 :
96 : /**
97 : * Concrete implementation of the ConnectivityManager singleton object for Linux platforms.
98 : */
99 : class ConnectivityManagerImpl final : public ConnectivityManager,
100 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
101 : public Internal::GenericConnectivityManagerImpl_BLE<ConnectivityManagerImpl>,
102 : #else
103 : public Internal::GenericConnectivityManagerImpl_NoBLE<ConnectivityManagerImpl>,
104 : #endif
105 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
106 : public Internal::GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>,
107 : #else
108 : public Internal::GenericConnectivityManagerImpl_NoThread<ConnectivityManagerImpl>,
109 : #endif
110 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
111 : public Internal::GenericConnectivityManagerImpl_WiFi<ConnectivityManagerImpl>,
112 : #else
113 : public Internal::GenericConnectivityManagerImpl_NoWiFi<ConnectivityManagerImpl>,
114 : #endif
115 : public Internal::GenericConnectivityManagerImpl_UDP<ConnectivityManagerImpl>,
116 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
117 : public Internal::GenericConnectivityManagerImpl_TCP<ConnectivityManagerImpl>,
118 : #endif
119 : public Internal::GenericConnectivityManagerImpl<ConnectivityManagerImpl>
120 : {
121 : // Allow the ConnectivityManager interface class to delegate method calls to
122 : // the implementation methods provided by this class.
123 : friend class ConnectivityManager;
124 :
125 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
126 : public:
127 : void
128 : SetNetworkStatusChangeCallback(NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * statusChangeCallback)
129 : {
130 : mpStatusChangeCallback = statusChangeCallback;
131 : }
132 :
133 : CHIP_ERROR ConnectWiFiNetworkAsync(ByteSpan ssid, ByteSpan credentials,
134 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback);
135 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
136 : CHIP_ERROR ConnectWiFiNetworkWithPDCAsync(ByteSpan ssid, ByteSpan networkIdentity, ByteSpan clientIdentity,
137 : const Crypto::P256Keypair & clientIdentityKeypair,
138 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback);
139 : #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC
140 :
141 : void PostNetworkConnect();
142 : CHIP_ERROR CommitConfig();
143 :
144 : void StartWiFiManagement();
145 : bool IsWiFiManagementStarted();
146 : void StartNonConcurrentWiFiManagement();
147 : int32_t GetDisconnectReason();
148 : CHIP_ERROR GetWiFiBssId(MutableByteSpan & value);
149 : CHIP_ERROR GetWiFiSecurityType(app::Clusters::WiFiNetworkDiagnostics::SecurityTypeEnum & securityType);
150 : CHIP_ERROR GetWiFiVersion(app::Clusters::WiFiNetworkDiagnostics::WiFiVersionEnum & wiFiVersion);
151 : CHIP_ERROR GetConfiguredNetwork(NetworkCommissioning::Network & network);
152 : CHIP_ERROR StartWiFiScan(ByteSpan ssid, NetworkCommissioning::WiFiDriver::ScanCallback * callback);
153 :
154 : private:
155 : CHIP_ERROR _ConnectWiFiNetworkAsync(GVariant * networkArgs,
156 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback)
157 : CHIP_REQUIRES(mWpaSupplicantMutex);
158 : static void _ConnectWiFiNetworkAsyncCallback(GObject * source_object, GAsyncResult * res, gpointer user_data);
159 : #endif
160 :
161 : public:
162 : const char * GetEthernetIfName() { return (mEthIfName[0] == '\0') ? nullptr : mEthIfName; }
163 :
164 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
165 : static const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; }
166 : #endif
167 :
168 : private:
169 : // ===== Members that implement the ConnectivityManager abstract interface.
170 :
171 : struct WiFiNetworkScanned
172 : {
173 : // The fields matches WiFiInterfaceScanResult::Type.
174 : uint8_t ssid[Internal::kMaxWiFiSSIDLength];
175 : uint8_t ssidLen;
176 : uint8_t bssid[6];
177 : int8_t rssi;
178 : uint16_t frequencyBand;
179 : uint8_t channel;
180 : uint8_t security;
181 : };
182 :
183 : CHIP_ERROR _Init();
184 : void _OnPlatformEvent(const ChipDeviceEvent * event);
185 :
186 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
187 : WiFiStationMode _GetWiFiStationMode();
188 : CHIP_ERROR _SetWiFiStationMode(ConnectivityManager::WiFiStationMode val);
189 : System::Clock::Timeout _GetWiFiStationReconnectInterval();
190 : CHIP_ERROR _SetWiFiStationReconnectInterval(System::Clock::Timeout val);
191 : bool _IsWiFiStationEnabled();
192 : bool _IsWiFiStationConnected();
193 : bool _IsWiFiStationApplicationControlled();
194 : bool _IsWiFiStationProvisioned();
195 : void _ClearWiFiStationProvision();
196 : bool _CanStartWiFiScan();
197 :
198 : WiFiAPMode _GetWiFiAPMode();
199 : CHIP_ERROR _SetWiFiAPMode(WiFiAPMode val);
200 : bool _IsWiFiAPActive();
201 : bool _IsWiFiAPApplicationControlled();
202 : void _DemandStartWiFiAP();
203 : void _StopOnDemandWiFiAP();
204 : void _MaintainOnDemandWiFiAP();
205 : System::Clock::Timeout _GetWiFiAPIdleTimeout();
206 : void _SetWiFiAPIdleTimeout(System::Clock::Timeout val);
207 : void UpdateNetworkStatus();
208 : static CHIP_ERROR StopAutoScan();
209 :
210 : static void _OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data);
211 : static void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties,
212 : gpointer user_data);
213 : static void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, gpointer user_data);
214 : static void _OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changed_properties,
215 : const gchar * const * invalidated_properties, gpointer user_data);
216 : static void _OnWpaInterfaceReady(GObject * source_object, GAsyncResult * res, gpointer user_data);
217 : static void _OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data);
218 : static void _OnWpaBssProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data);
219 : static void _OnWpaInterfaceScanDone(GObject * source_object, GAsyncResult * res, gpointer user_data);
220 :
221 : static bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result);
222 :
223 : static CHIP_ERROR _StartWiFiManagement(ConnectivityManagerImpl * self);
224 :
225 : static bool mAssociationStarted;
226 : static BitFlags<ConnectivityFlags> mConnectivityFlag;
227 : static GDBusWpaSupplicant mWpaSupplicant CHIP_GUARDED_BY(mWpaSupplicantMutex);
228 : // Access to mWpaSupplicant has to be protected by a mutex because it is accessed from
229 : // the CHIP event loop thread and dedicated D-Bus thread started by platform manager.
230 : static std::mutex mWpaSupplicantMutex;
231 :
232 : NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr;
233 : #endif
234 :
235 : // ==================== ConnectivityManager Private Methods ====================
236 :
237 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
238 : void DriveAPState();
239 : CHIP_ERROR ConfigureWiFiAP();
240 : void ChangeWiFiAPState(WiFiAPState newState);
241 : static void DriveAPState(::chip::System::Layer * aLayer, void * aAppState);
242 : #endif
243 :
244 : // ===== Members for internal use by the following friends.
245 :
246 : friend ConnectivityManager & ConnectivityMgr();
247 : friend ConnectivityManagerImpl & ConnectivityMgrImpl();
248 :
249 : static ConnectivityManagerImpl sInstance;
250 :
251 : // ===== Private members reserved for use by this class only.
252 :
253 : char mEthIfName[IFNAMSIZ];
254 :
255 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
256 : ConnectivityManager::WiFiStationMode mWiFiStationMode;
257 : ConnectivityManager::WiFiAPMode mWiFiAPMode;
258 : WiFiAPState mWiFiAPState;
259 : System::Clock::Timestamp mLastAPDemandTime;
260 : System::Clock::Timeout mWiFiStationReconnectInterval;
261 : System::Clock::Timeout mWiFiAPIdleTimeout;
262 : #endif
263 :
264 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFI
265 : static char sWiFiIfName[IFNAMSIZ];
266 : #endif
267 :
268 : static uint8_t sInterestedSSID[Internal::kMaxWiFiSSIDLength];
269 : static uint8_t sInterestedSSIDLen;
270 : static NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback;
271 : static NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback;
272 : };
273 :
274 : #if CHIP_DEVICE_CONFIG_ENABLE_WPA
275 : inline ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::_GetWiFiAPMode()
276 : {
277 : return mWiFiAPMode;
278 : }
279 :
280 : inline bool ConnectivityManagerImpl::_IsWiFiAPActive()
281 : {
282 : return mWiFiAPState == kWiFiAPState_Active;
283 : }
284 :
285 : inline bool ConnectivityManagerImpl::_IsWiFiAPApplicationControlled()
286 : {
287 : return mWiFiAPMode == kWiFiAPMode_ApplicationControlled;
288 : }
289 :
290 : inline System::Clock::Timeout ConnectivityManagerImpl::_GetWiFiAPIdleTimeout()
291 : {
292 : return mWiFiAPIdleTimeout;
293 : }
294 :
295 : #endif
296 :
297 : /**
298 : * Returns the public interface of the ConnectivityManager singleton object.
299 : *
300 : * chip applications should use this to access features of the ConnectivityManager object
301 : * that are common to all platforms.
302 : */
303 0 : inline ConnectivityManager & ConnectivityMgr()
304 : {
305 0 : return ConnectivityManagerImpl::sInstance;
306 : }
307 :
308 : /**
309 : * Returns the platform-specific implementation of the ConnectivityManager singleton object.
310 : *
311 : * chip applications can use this to gain access to features of the ConnectivityManager
312 : * that are specific to the ESP32 platform.
313 : */
314 : inline ConnectivityManagerImpl & ConnectivityMgrImpl()
315 : {
316 : return ConnectivityManagerImpl::sInstance;
317 : }
318 :
319 : } // namespace DeviceLayer
320 : } // namespace chip
|