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