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 WifiConfigCenter::GetInstance().SetCoexSupport(true);
215 }
216 return;
217 }
218
GetSupportedFeatures(long & features) const219 int WifiManager::GetSupportedFeatures(long &features) const
220 {
221 long supportedFeatures = mSupportedFeatures;
222 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_INFRA);
223 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_INFRA_5G);
224 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_PASSPOINT);
225 if (g_supportsapcoexistflag) {
226 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_AP_STA);
227 }
228 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_WPA3_SAE);
229 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_WPA3_SUITE_B);
230 supportedFeatures |= static_cast<long>(WifiFeatures::WIFI_FEATURE_OWE);
231 features = supportedFeatures;
232
233 return 0;
234 }
235
AddSupportedFeatures(WifiFeatures feature)236 void WifiManager::AddSupportedFeatures(WifiFeatures feature)
237 {
238 mSupportedFeatures = static_cast<long>(static_cast<unsigned long>(mSupportedFeatures) |
239 static_cast<unsigned long>(feature));
240 }
241
PushServiceCloseMsg(WifiCloseServiceCode code,int instId)242 void WifiManager::PushServiceCloseMsg(WifiCloseServiceCode code, int instId)
243 {
244 switch (code) {
245 case WifiCloseServiceCode::STA_SERVICE_CLOSE:
246 mCloseServiceThread->PostAsyncTask([this, instId]() {
247 wifiStaManager->CloseStaService(instId);
248 });
249 break;
250 case WifiCloseServiceCode::SCAN_SERVICE_CLOSE:
251 mCloseServiceThread->PostAsyncTask([this, instId]() {
252 wifiScanManager->CloseScanService(instId);
253 });
254 break;
255 #ifdef FEATURE_AP_SUPPORT
256 case WifiCloseServiceCode::AP_SERVICE_CLOSE:
257 mCloseServiceThread->PostAsyncTask([this, instId]() {
258 wifiHotspotManager->CloseApService(instId);
259 });
260 break;
261 #endif
262 #ifdef FEATURE_P2P_SUPPORT
263 case WifiCloseServiceCode::P2P_SERVICE_CLOSE:
264 mCloseServiceThread->PostAsyncTask([this]() {
265 wifiP2pManager->CloseP2pService();
266 });
267 break;
268 #endif
269 case WifiCloseServiceCode::STA_MSG_OPENED:
270 mCloseServiceThread->PostAsyncTask([this, instId]() {
271 wifiStaManager->DealStaOpened(instId);
272 wifiScanManager->DealStaOpened(instId);
273 });
274 break;
275 case WifiCloseServiceCode::STA_MSG_STOPED:
276 mCloseServiceThread->PostAsyncTask([this, instId]() {
277 wifiStaManager->DealStaStopped(instId);
278 });
279 break;
280 case WifiCloseServiceCode::SERVICE_THREAD_EXIT:
281 WIFI_LOGI("DealCloseServiceMsg exit!");
282 return;
283 default:
284 WIFI_LOGW("Unknown message code, %{public}d", static_cast<int>(code));
285 break;
286 }
287 return;
288 }
289
AutoStartEnhanceService(void)290 void WifiManager::AutoStartEnhanceService(void)
291 {
292 WIFI_LOGI("AutoStartEnhanceService start");
293 ErrCode errCode = WIFI_OPT_FAILED;
294 do {
295 if (WifiServiceManager::GetInstance().CheckAndEnforceService(WIFI_SERVICE_ENHANCE) < 0) {
296 WIFI_LOGE("Load %{public}s service failed!", WIFI_SERVICE_ENHANCE);
297 break;
298 }
299 IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
300 if (pEnhanceService == nullptr) {
301 WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_ENHANCE);
302 break;
303 }
304 errCode = pEnhanceService->Init();
305 if (errCode != WIFI_OPT_SUCCESS) {
306 WIFI_LOGE("init Enhance service failed, ret %{public}d!", static_cast<int>(errCode));
307 break;
308 }
309 } while (0);
310 return;
311 }
312
GetWifiStaManager()313 std::unique_ptr<WifiStaManager>& WifiManager::GetWifiStaManager()
314 {
315 return wifiStaManager;
316 }
317
GetWifiScanManager()318 std::unique_ptr<WifiScanManager>& WifiManager::GetWifiScanManager()
319 {
320 return wifiScanManager;
321 }
322
GetWifiTogglerManager()323 std::unique_ptr<WifiTogglerManager>& WifiManager::GetWifiTogglerManager()
324 {
325 return wifiTogglerManager;
326 }
327
328 #ifdef FEATURE_AP_SUPPORT
GetWifiHotspotManager()329 std::unique_ptr<WifiHotspotManager>& WifiManager::GetWifiHotspotManager()
330 {
331 return wifiHotspotManager;
332 }
333 #endif
334
335 #ifdef FEATURE_P2P_SUPPORT
GetWifiP2pManager()336 std::unique_ptr<WifiP2pManager>& WifiManager::GetWifiP2pManager()
337 {
338 return wifiP2pManager;
339 }
340 #endif
341
342 #ifndef OHOS_ARCH_LITE
GetWifiEventSubscriberManager()343 std::unique_ptr<WifiEventSubscriberManager>& WifiManager::GetWifiEventSubscriberManager()
344 {
345 return wifiEventSubscriberManager;
346 }
347
GetWifiMultiVapManager()348 std::unique_ptr<WifiMultiVapManager>& WifiManager::GetWifiMultiVapManager()
349 {
350 return wifiMultiVapManager;
351 }
352 #endif
353
354 #ifdef FEATURE_HPF_SUPPORT
InstallPacketFilterProgram(int event,int instId)355 void WifiManager::InstallPacketFilterProgram(int event, int instId)
356 {
357 WIFI_LOGD("%{public}s enter event: %{public}d, instId: %{public}d", __FUNCTION__, event, instId);
358 IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
359 if (pEnhanceService == nullptr) {
360 WIFI_LOGW("%{public}s pEnhanceService is nullptr", __FUNCTION__);
361 return;
362 }
363 // fill mac address arr
364 unsigned char macAddr[WIFI_MAC_LEN] = {0};
365 std::string macStr;
366 WifiSettings::GetInstance().GetRealMacAddress(macStr, instId);
367 WIFI_LOGD("%{public}s convert mac from str to arr success, macStr: %{public}s",
368 __FUNCTION__, OHOS::Wifi::MacAnonymize(macStr).c_str());
369 if (OHOS::Wifi::MacStrToArray(macStr, macAddr) != EOK) {
370 WIFI_LOGW("%{public}s get mac addr fail, set default mac addr", __FUNCTION__);
371 if (memset_s(macAddr, WIFI_MAC_LEN, 0x00, WIFI_MAC_LEN) != EOK) {
372 WIFI_LOGE("%{public}s set default mac addr fail", __FUNCTION__);
373 }
374 }
375 // get number ip and net mask
376 IpInfo ipInfo;
377 WifiConfigCenter::GetInstance().GetIpInfo(ipInfo, instId);
378 if (ipInfo.ipAddress == 0 || ipInfo.netmask == 0) {
379 WIFI_LOGW("%{public}s cannot get device ip address", __FUNCTION__);
380 }
381 std::string ipAddrStr = IpTools::ConvertIpv4Address(ipInfo.ipAddress);
382 std::string ipMaskStr = IpTools::ConvertIpv4Mask(ipInfo.netmask);
383 int netMaskLen = IpTools::GetMaskLength(ipMaskStr);
384 WIFI_LOGD("%{public}s get ip info ipaddrStr: %{public}s, ipMaskStr: %{public}s, netMaskLen: %{public}d",
385 __FUNCTION__,
386 OHOS::Wifi::MacAnonymize(ipAddrStr).c_str(), OHOS::Wifi::MacAnonymize(ipMaskStr).c_str(), netMaskLen);
387 if (pEnhanceService->InstallFilterProgram(
388 ipInfo.ipAddress, netMaskLen, macAddr, WIFI_MAC_LEN, event) != WIFI_OPT_SUCCESS) {
389 WIFI_LOGE("%{public}s InstallFilterProgram fail", __FUNCTION__);
390 return;
391 }
392 WIFI_LOGE("%{public}s InstallFilterProgram success", __FUNCTION__);
393 }
394 #endif
395
CheckAndStartSta()396 void WifiManager::CheckAndStartSta()
397 {
398 DIR *dir = nullptr;
399 struct dirent *dent = nullptr;
400 int currentWaitTime = 0;
401 const int sleepTime = 1;
402 const int maxWaitTimes = 30;
403 while (currentWaitTime < maxWaitTimes) {
404 dir = opendir("/sys/class/net");
405 if (dir == nullptr) {
406 wifiTogglerManager->WifiToggled(1, 0);
407 return;
408 }
409 while ((dent = readdir(dir)) != nullptr) {
410 if (dent->d_name[0] == '.') {
411 continue;
412 }
413 if (strncmp(dent->d_name, "wlan", strlen("wlan")) == 0) {
414 closedir(dir);
415 wifiTogglerManager->WifiToggled(1, 0);
416 return;
417 }
418 }
419 closedir(dir);
420 sleep(sleepTime);
421 currentWaitTime++;
422 }
423 wifiTogglerManager->WifiToggled(1, 0);
424 }
425
AutoStartServiceThread()426 void WifiManager::AutoStartServiceThread()
427 {
428 WIFI_LOGI("Auto start service...");
429 CheckAndStartSta();
430 }
431
InitPidfile()432 void WifiManager::InitPidfile()
433 {
434 char pidFile[DIR_MAX_LENGTH] = {0, };
435 int n = snprintf_s(pidFile, DIR_MAX_LENGTH, DIR_MAX_LENGTH - 1, "%s/%s.pid",
436 CONFIG_ROOR_DIR, WIFI_MANAGGER_PID_NAME);
437 if (n < 0) {
438 LOGE("InitPidfile: construct pidFile name failed.");
439 return;
440 }
441 unlink(pidFile);
442
443 pid_t pid = getpid();
444 char buf[PID_MAX_LENGTH] = {0};
445 if (snprintf_s(buf, PID_MAX_LENGTH, PID_MAX_LENGTH - 1, "%d", pid) < 0) {
446 LOGE("InitPidfile: pidFile:%{public}s failed, snprintf_s error:%{public}d!", pidFile, errno);
447 return;
448 }
449
450 int fd;
451 if ((fd = open(pidFile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
452 LOGE("InitPidfile: open pidFile:%{public}s error:%{public}d!", pidFile, errno);
453 return;
454 }
455
456 ssize_t bytes;
457 if ((bytes = write(fd, buf, strlen(buf))) <= 0) {
458 LOGE("InitPidfile failed, write pidFile:%{public}s error:%{public}d, bytes:%{public}zd!",
459 pidFile, errno, bytes);
460 close(fd);
461 return;
462 }
463 LOGI("InitPidfile: buf:%{public}s write pidFile:%{public}s, bytes:%{public}zd!", buf, pidFile, bytes);
464 close(fd);
465
466 if (chdir(CONFIG_ROOR_DIR) != 0) {
467 LOGE("InitPidfile failed, chdir pidDir:%{public}s error:%{public}d!", CONFIG_ROOR_DIR, errno);
468 return;
469 }
470
471 umask(DEFAULT_UMASK_VALUE);
472 chmod(pidFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
473 return;
474 }
475 } // namespace Wifi
476 } // namespace OHOS
477