• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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