1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "wifi_manager.h"
17 #include <dirent.h>
18 #include "wifi_auth_center.h"
19 #include "wifi_config_center.h"
20 #include "wifi_global_func.h"
21 #include "wifi_logger.h"
22 #ifdef OHOS_ARCH_LITE
23 #include "wifi_internal_event_dispatcher_lite.h"
24 #else
25 #include "parameter.h"
26 #include "wifi_internal_event_dispatcher.h"
27 #endif
28 #ifdef FEATURE_STA_SUPPORT
29 #include "wifi_country_code_manager.h"
30 #endif
31 #include "wifi_service_manager.h"
32 #include "wifi_common_def.h"
33 #include "wifi_common_util.h"
34 #include "wifi_common_service_manager.h"
35 #include "wifi_native_define.h"
36 #include "wifi_sta_hal_interface.h"
37 #ifndef OHOS_ARCH_LITE
38 #include "wifi_watchdog_utils.h"
39 #include "power_mgr_client.h"
40 #endif
41
42 namespace OHOS {
43 namespace Wifi {
44 DEFINE_WIFILOG_LABEL("WifiManager");
45
GetInstance()46 WifiManager &WifiManager::GetInstance()
47 {
48 static WifiManager gWifiManager;
49 return gWifiManager;
50 }
51
WifiManager()52 WifiManager::WifiManager() : mInitStatus(INIT_UNKNOWN), mSupportedFeatures(0)
53 {}
54
~WifiManager()55 WifiManager::~WifiManager()
56 {
57 Exit();
58 }
59
Init()60 int WifiManager::Init()
61 {
62 std::unique_lock<std::mutex> lock(initStatusMutex);
63 #ifndef OHOS_ARCH_LITE
64 WifiWatchDogUtils::GetInstance(); // init watchdog to set ffrt callback timeout before ffrt thread created
65 #endif
66 if (mInitStatus == INIT_OK) {
67 WIFI_LOGI("WifiManager already init!");
68 return 0;
69 }
70 mInitStatus = WifiCommonServiceManager::GetInstance().Init();
71 if (mInitStatus != INIT_OK) {
72 WIFI_LOGE("WifiCommonServiceManager Init failed!");
73 return -1;
74 }
75
76 if (WifiServiceManager::GetInstance().Init() < 0) {
77 WIFI_LOGE("WifiServiceManager Init failed!");
78 mInitStatus = SERVICE_MANAGER_INIT_FAILED;
79 return -1;
80 }
81
82 WifiStaHalInterface::GetInstance().RegisterNativeProcessCallback(
83 std::bind(&WifiManager::OnNativeProcessStatusChange, this, std::placeholders::_1));
84 mCloseServiceThread = std::make_unique<WifiEventHandler>("CloseServiceThread");
85 #ifndef OHOS_ARCH_LITE
86 wifiEventSubscriberManager = std::make_unique<WifiEventSubscriberManager>();
87 wifiMultiVapManager = std::make_unique<WifiMultiVapManager>();
88 #endif
89 wifiStaManager = std::make_unique<WifiStaManager>();
90 wifiScanManager = std::make_unique<WifiScanManager>();
91 wifiTogglerManager = std::make_unique<WifiTogglerManager>();
92 #ifdef FEATURE_AP_SUPPORT
93 wifiHotspotManager = std::make_unique<WifiHotspotManager>();
94 #endif
95 #ifdef FEATURE_P2P_SUPPORT
96 wifiP2pManager = std::make_unique<WifiP2pManager>();
97 #endif
98
99 if (WifiServiceManager::GetInstance().CheckPreLoadService() < 0) {
100 WIFI_LOGE("WifiServiceManager check preload feature service failed!");
101 WifiManager::GetInstance().Exit();
102 return -1;
103 }
104 mInitStatus = INIT_OK;
105
106 if (!std::filesystem::exists(WIFI_CONFIG_FILE_PATH) && !std::filesystem::exists(DUAL_WIFI_CONFIG_FILE_PATH) &&
107 !std::filesystem::exists(DUAL_SOFTAP_CONFIG_FILE_PATH)) {
108 if (IsStartUpWifiEnableSupport()) {
109 WIFI_LOGI("It's first start up, need open wifi before oobe");
110 WifiConfigCenter::GetInstance().SetPersistWifiState(WIFI_STATE_ENABLED, INSTID_WLAN0);
111 }
112 }
113 int lastState = WifiConfigCenter::GetInstance().GetPersistWifiState(INSTID_WLAN0);
114 if (lastState != WIFI_STATE_DISABLED && !IsFactoryMode()) { /* Automatic startup upon startup */
115 WIFI_LOGI("AutoStartServiceThread lastState:%{public}d", lastState);
116 WifiConfigCenter::GetInstance().SetWifiToggledState(lastState, INSTID_WLAN0);
117 mStartServiceThread = std::make_unique<WifiEventHandler>("StartServiceThread");
118 mStartServiceThread->PostAsyncTask([this]() {
119 AutoStartServiceThread();
120 });
121 } else {
122 if (WifiSettings::GetInstance().GetScanOnlySwitchState()) {
123 WIFI_LOGI("Auto start scan only!");
124 wifiTogglerManager->ScanOnlyToggled(1);
125 }
126 }
127 #ifndef OHOS_ARCH_LITE
128 WifiConfigCenter::GetInstance().SetScreenState(
129 PowerMgr::PowerMgrClient::GetInstance().IsScreenOn() ? MODE_STATE_OPEN : MODE_STATE_CLOSE);
130 #endif
131 InitPidfile();
132 CheckSapcoExist();
133 return 0;
134 }
135
Exit()136 void WifiManager::Exit()
137 {
138 WIFI_LOGI("[WifiManager] Exit.");
139 std::unique_lock<std::mutex> lock(initStatusMutex);
140 mInitStatus = INIT_UNKNOWN;
141 WifiServiceManager::GetInstance().UninstallAllService();
142 PushServiceCloseMsg(WifiCloseServiceCode::SERVICE_THREAD_EXIT);
143 if (mCloseServiceThread) {
144 mCloseServiceThread.reset();
145 }
146 if (mStartServiceThread) {
147 mStartServiceThread.reset();
148 }
149 if (wifiStaManager) {
150 wifiStaManager.reset();
151 }
152 if (wifiScanManager) {
153 wifiScanManager.reset();
154 }
155 if (wifiTogglerManager) {
156 wifiTogglerManager.reset();
157 }
158 #ifdef FEATURE_AP_SUPPORT
159 if (wifiHotspotManager) {
160 wifiHotspotManager.reset();
161 }
162 #endif
163 #ifdef FEATURE_P2P_SUPPORT
164 if (wifiP2pManager) {
165 wifiP2pManager.reset();
166 }
167 #endif
168 #ifndef OHOS_ARCH_LITE
169 if (wifiEventSubscriberManager) {
170 wifiEventSubscriberManager.reset();
171 }
172 if (wifiMultiVapManager) {
173 wifiMultiVapManager.reset();
174 }
175 #endif
176 return;
177 }
178
OnNativeProcessStatusChange(int status)179 void WifiManager::OnNativeProcessStatusChange(int status)
180 {
181 WIFI_LOGI("OnNativeProcessStatusChange status:%{public}d", status);
182 switch (status) {
183 case WPA_DEATH:
184 WIFI_LOGE("wpa_supplicant process is dead!");
185 if (wifiTogglerManager && WifiConfigCenter::GetInstance().GetWifiToggledEnable() != WIFI_STATE_DISABLED) {
186 wifiTogglerManager->ForceStopWifi();
187 }
188 break;
189 case AP_DEATH:
190 WIFI_LOGE("hostapd process is dead!");
191 if (wifiTogglerManager && WifiConfigCenter::GetInstance().GetSoftapToggledState()) {
192 wifiTogglerManager->SoftapToggled(0, 0);
193 wifiTogglerManager->SoftapToggled(1, 0);
194 }
195 break;
196 default:
197 break;
198 }
199 }
200
CheckSapcoExist()201 void WifiManager::CheckSapcoExist()
202 {
203 char preValue[PROP_SUPPORT_SAPCOEXIST_LEN] = {0};
204
205 g_supportsapcoexistflag = false;
206 int errorCode = GetParamValue(SUPPORT_SAPCOEXIST_PROP.c_str(), 0, preValue, PROP_SUPPORT_SAPCOEXIST_LEN);
207 if (errorCode < 0) {
208 WIFI_LOGI("GetSupportedFeatures no support_sapcoexist.");
209 return;
210 }
211 WIFI_LOGI("GetSupportedFeatures preValue = %{public}s.", preValue);
212 if (strncmp(preValue, SUPPORT_SAPCOEXIST.c_str(), SUPPORT_SAPCOEXIST_LEN) == 0) {
213 g_supportsapcoexistflag = true;
214 }
215 return;
216 }
217
GetSupportedFeatures(long & features) const218 int WifiManager::GetSupportedFeatures(long &features) const
219 {
220 long supportedFeatures = mSupportedFeatures;
221 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_INFRA);
222 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_INFRA_5G);
223 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_PASSPOINT);
224 if (g_supportsapcoexistflag) {
225 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_AP_STA);
226 }
227 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_WPA3_SAE);
228 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_WPA3_SUITE_B);
229 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_OWE);
230 features = supportedFeatures;
231
232 return 0;
233 }
234
AddSupportedFeatures(WifiFeatures feature)235 void WifiManager::AddSupportedFeatures(WifiFeatures feature)
236 {
237 mSupportedFeatures = static_cast<long>(static_cast<unsigned long>(mSupportedFeatures) |
238 static_cast<unsigned long>(feature));
239 }
240
PushServiceCloseMsg(WifiCloseServiceCode code,int instId)241 void WifiManager::PushServiceCloseMsg(WifiCloseServiceCode code, int instId)
242 {
243 switch (code) {
244 case WifiCloseServiceCode::STA_SERVICE_CLOSE:
245 mCloseServiceThread->PostAsyncTask([this, instId]() {
246 wifiStaManager->CloseStaService(instId);
247 });
248 break;
249 case WifiCloseServiceCode::SCAN_SERVICE_CLOSE:
250 mCloseServiceThread->PostAsyncTask([this, instId]() {
251 wifiScanManager->CloseScanService(instId);
252 });
253 break;
254 #ifdef FEATURE_AP_SUPPORT
255 case WifiCloseServiceCode::AP_SERVICE_CLOSE:
256 mCloseServiceThread->PostAsyncTask([this, instId]() {
257 wifiHotspotManager->CloseApService(instId);
258 });
259 break;
260 #endif
261 #ifdef FEATURE_P2P_SUPPORT
262 case WifiCloseServiceCode::P2P_SERVICE_CLOSE:
263 mCloseServiceThread->PostAsyncTask([this]() {
264 wifiP2pManager->CloseP2pService();
265 });
266 break;
267 #endif
268 case WifiCloseServiceCode::STA_MSG_OPENED:
269 mCloseServiceThread->PostAsyncTask([this, instId]() {
270 wifiStaManager->DealStaOpened(instId);
271 wifiScanManager->DealStaOpened(instId);
272 });
273 break;
274 case WifiCloseServiceCode::STA_MSG_STOPED:
275 mCloseServiceThread->PostAsyncTask([this, instId]() {
276 wifiStaManager->DealStaStopped(instId);
277 });
278 break;
279 case WifiCloseServiceCode::SERVICE_THREAD_EXIT:
280 WIFI_LOGI("DealCloseServiceMsg exit!");
281 return;
282 default:
283 WIFI_LOGW("Unknown message code, %{public}d", static_cast<int>(code));
284 break;
285 }
286 return;
287 }
288
AutoStartEnhanceService(void)289 void WifiManager::AutoStartEnhanceService(void)
290 {
291 WIFI_LOGI("AutoStartEnhanceService start");
292 ErrCode errCode = WIFI_OPT_FAILED;
293 do {
294 if (WifiServiceManager::GetInstance().CheckAndEnforceService(WIFI_SERVICE_ENHANCE) < 0) {
295 WIFI_LOGE("Load %{public}s service failed!", WIFI_SERVICE_ENHANCE);
296 break;
297 }
298 IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
299 if (pEnhanceService == nullptr) {
300 WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_ENHANCE);
301 break;
302 }
303 errCode = pEnhanceService->Init();
304 if (errCode != WIFI_OPT_SUCCESS) {
305 WIFI_LOGE("init Enhance service failed, ret %{public}d!", static_cast<int>(errCode));
306 break;
307 }
308 } while (0);
309 return;
310 }
311
GetWifiStaManager()312 std::unique_ptr<WifiStaManager>& WifiManager::GetWifiStaManager()
313 {
314 return wifiStaManager;
315 }
316
GetWifiScanManager()317 std::unique_ptr<WifiScanManager>& WifiManager::GetWifiScanManager()
318 {
319 return wifiScanManager;
320 }
321
GetWifiTogglerManager()322 std::unique_ptr<WifiTogglerManager>& WifiManager::GetWifiTogglerManager()
323 {
324 return wifiTogglerManager;
325 }
326
327 #ifdef FEATURE_AP_SUPPORT
GetWifiHotspotManager()328 std::unique_ptr<WifiHotspotManager>& WifiManager::GetWifiHotspotManager()
329 {
330 return wifiHotspotManager;
331 }
332 #endif
333
334 #ifdef FEATURE_P2P_SUPPORT
GetWifiP2pManager()335 std::unique_ptr<WifiP2pManager>& WifiManager::GetWifiP2pManager()
336 {
337 return wifiP2pManager;
338 }
339 #endif
340
341 #ifndef OHOS_ARCH_LITE
GetWifiEventSubscriberManager()342 std::unique_ptr<WifiEventSubscriberManager>& WifiManager::GetWifiEventSubscriberManager()
343 {
344 return wifiEventSubscriberManager;
345 }
346
GetWifiMultiVapManager()347 std::unique_ptr<WifiMultiVapManager>& WifiManager::GetWifiMultiVapManager()
348 {
349 return wifiMultiVapManager;
350 }
351 #endif
352
353 #ifdef FEATURE_HPF_SUPPORT
InstallPacketFilterProgram(int event,int instId)354 void WifiManager::InstallPacketFilterProgram(int event, int instId)
355 {
356 WIFI_LOGD("%{public}s enter event: %{public}d, instId: %{public}d", __FUNCTION__, event, instId);
357 IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
358 if (pEnhanceService == nullptr) {
359 WIFI_LOGW("%{public}s pEnhanceService is nullptr", __FUNCTION__);
360 return;
361 }
362 // fill mac address arr
363 unsigned char macAddr[WIFI_MAC_LEN] = {0};
364 std::string macStr;
365 WifiSettings::GetInstance().GetRealMacAddress(macStr, instId);
366 WIFI_LOGD("%{public}s convert mac from str to arr success, macStr: %{public}s",
367 __FUNCTION__, OHOS::Wifi::MacAnonymize(macStr).c_str());
368 if (OHOS::Wifi::MacStrToArray(macStr, macAddr) != EOK) {
369 WIFI_LOGW("%{public}s get mac addr fail, set default mac addr", __FUNCTION__);
370 if (memset_s(macAddr, WIFI_MAC_LEN, 0x00, WIFI_MAC_LEN) != EOK) {
371 WIFI_LOGE("%{public}s set default mac addr fail", __FUNCTION__);
372 }
373 }
374 // get number ip and net mask
375 IpInfo ipInfo;
376 WifiConfigCenter::GetInstance().GetIpInfo(ipInfo, instId);
377 if (ipInfo.ipAddress == 0 || ipInfo.netmask == 0) {
378 WIFI_LOGW("%{public}s cannot get device ip address", __FUNCTION__);
379 }
380 std::string ipAddrStr = IpTools::ConvertIpv4Address(ipInfo.ipAddress);
381 std::string ipMaskStr = IpTools::ConvertIpv4Mask(ipInfo.netmask);
382 int netMaskLen = IpTools::GetMaskLength(ipMaskStr);
383 WIFI_LOGD("%{public}s get ip info ipaddrStr: %{public}s, ipMaskStr: %{public}s, netMaskLen: %{public}d",
384 __FUNCTION__,
385 OHOS::Wifi::MacAnonymize(ipAddrStr).c_str(), OHOS::Wifi::MacAnonymize(ipMaskStr).c_str(), netMaskLen);
386 if (pEnhanceService->InstallFilterProgram(
387 ipInfo.ipAddress, netMaskLen, macAddr, WIFI_MAC_LEN, event) != WIFI_OPT_SUCCESS) {
388 WIFI_LOGE("%{public}s InstallFilterProgram fail", __FUNCTION__);
389 return;
390 }
391 WIFI_LOGE("%{public}s InstallFilterProgram success", __FUNCTION__);
392 }
393 #endif
394
CheckAndStartSta()395 void WifiManager::CheckAndStartSta()
396 {
397 DIR *dir = nullptr;
398 struct dirent *dent = nullptr;
399 int currentWaitTime = 0;
400 const int sleepTime = 1;
401 const int maxWaitTimes = 30;
402 while (currentWaitTime < maxWaitTimes) {
403 dir = opendir("/sys/class/net");
404 if (dir == nullptr) {
405 wifiTogglerManager->WifiToggled(1, 0);
406 return;
407 }
408 while ((dent = readdir(dir)) != nullptr) {
409 if (dent->d_name[0] == '.') {
410 continue;
411 }
412 if (strncmp(dent->d_name, "wlan", strlen("wlan")) == 0) {
413 closedir(dir);
414 wifiTogglerManager->WifiToggled(1, 0);
415 return;
416 }
417 }
418 closedir(dir);
419 sleep(sleepTime);
420 currentWaitTime++;
421 }
422 wifiTogglerManager->WifiToggled(1, 0);
423 }
424
AutoStartServiceThread()425 void WifiManager::AutoStartServiceThread()
426 {
427 WIFI_LOGI("Auto start service...");
428 CheckAndStartSta();
429 }
430
InitPidfile()431 void WifiManager::InitPidfile()
432 {
433 char pidFile[DIR_MAX_LENGTH] = {0, };
434 int n = snprintf_s(pidFile, DIR_MAX_LENGTH, DIR_MAX_LENGTH - 1, "%s/%s.pid",
435 CONFIG_ROOR_DIR, WIFI_MANAGGER_PID_NAME);
436 if (n < 0) {
437 LOGE("InitPidfile: construct pidFile name failed.");
438 return;
439 }
440 unlink(pidFile);
441
442 pid_t pid = getpid();
443 char buf[PID_MAX_LENGTH] = {0};
444 if (snprintf_s(buf, PID_MAX_LENGTH, PID_MAX_LENGTH - 1, "%d", pid) < 0) {
445 LOGE("InitPidfile: pidFile:%{public}s failed, snprintf_s error:%{public}d!", pidFile, errno);
446 return;
447 }
448
449 int fd;
450 if ((fd = open(pidFile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
451 LOGE("InitPidfile: open pidFile:%{public}s error:%{public}d!", pidFile, errno);
452 return;
453 }
454
455 ssize_t bytes;
456 if ((bytes = write(fd, buf, strlen(buf))) <= 0) {
457 LOGE("InitPidfile failed, write pidFile:%{public}s error:%{public}d, bytes:%{public}zd!",
458 pidFile, errno, bytes);
459 close(fd);
460 return;
461 }
462 LOGI("InitPidfile: buf:%{public}s write pidFile:%{public}s, bytes:%{public}zd!", buf, pidFile, bytes);
463 close(fd);
464
465 if (chdir(CONFIG_ROOR_DIR) != 0) {
466 LOGE("InitPidfile failed, chdir pidDir:%{public}s error:%{public}d!", CONFIG_ROOR_DIR, errno);
467 return;
468 }
469
470 umask(DEFAULT_UMASK_VALUE);
471 chmod(pidFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
472 return;
473 }
474 } // namespace Wifi
475 } // namespace OHOS
476