1 /*
2  * Copyright (c) 2023 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_scan_manager.h"
17 #include "wifi_manager.h"
18 #include "wifi_service_manager.h"
19 #include "wifi_config_center.h"
20 #include "wifi_global_func.h"
21 #include "wifi_logger.h"
22 #include "wifi_common_event_helper.h"
23 #include "wifi_system_timer.h"
24 #ifdef OHOS_ARCH_LITE
25 #include "wifi_internal_event_dispatcher_lite.h"
26 #else
27 #include "wifi_country_code_manager.h"
28 #include "wifi_internal_event_dispatcher.h"
29 #include "wifi_sa_manager.h"
30 #endif
31 
32 DEFINE_WIFILOG_LABEL("WifiScanManager");
33 
34 namespace OHOS {
35 namespace Wifi {
WifiScanManager()36 WifiScanManager::WifiScanManager()
37 {
38     WIFI_LOGI("create WifiScanManager");
39     InitScanCallback();
40 }
41 
GetScanCallback()42 IScanSerivceCallbacks& WifiScanManager::GetScanCallback()
43 {
44     return mScanCallback;
45 }
46 
GetStaCallback() const47 StaServiceCallback WifiScanManager::GetStaCallback() const
48 {
49     return mStaCallback;
50 }
51 
52 #ifndef OHOS_ARCH_LITE
UnloadScanSaTimerCallback()53 static void UnloadScanSaTimerCallback()
54 {
55     WifiSaLoadManager::GetInstance().UnloadWifiSa(WIFI_SCAN_ABILITY_ID);
56     WifiManager::GetInstance().GetWifiScanManager()->StopUnloadScanSaTimer();
57 }
58 
StopUnloadScanSaTimer(void)59 void WifiScanManager::StopUnloadScanSaTimer(void)
60 {
61     WIFI_LOGI("StopUnloadScanSaTimer! unloadScanSaTimerId:%{public}u", unloadScanSaTimerId);
62     std::unique_lock<std::mutex> lock(unloadScanSaTimerMutex);
63     if (unloadScanSaTimerId == 0) {
64         return;
65     }
66     MiscServices::TimeServiceClient::GetInstance()->StopTimer(unloadScanSaTimerId);
67     MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(unloadScanSaTimerId);
68     unloadScanSaTimerId = 0;
69     return;
70 }
71 
StartUnloadScanSaTimer(void)72 void WifiScanManager::StartUnloadScanSaTimer(void)
73 {
74     WIFI_LOGI("StartUnloadScanSaTimer! unloadScanSaTimerId:%{public}u", unloadScanSaTimerId);
75     std::unique_lock<std::mutex> lock(unloadScanSaTimerMutex);
76     if (unloadScanSaTimerId == 0) {
77         std::shared_ptr<WifiSysTimer> wifiSysTimer = std::make_shared<WifiSysTimer>(false, 0, true, false);
78         wifiSysTimer->SetCallbackInfo(UnloadScanSaTimerCallback);
79         unloadScanSaTimerId = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(wifiSysTimer);
80         int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
81         MiscServices::TimeServiceClient::GetInstance()->StartTimer(unloadScanSaTimerId,
82             currentTime + TIMEOUT_UNLOAD_WIFI_SA);
83         WIFI_LOGI("StartUnloadScanSaTimer success! unloadScanSaTimerId:%{public}u", unloadScanSaTimerId);
84     }
85     return;
86 }
87 #endif
88 
CheckAndStartScanService(int instId)89 void WifiScanManager::CheckAndStartScanService(int instId)
90 {
91     WifiOprMidState scanState = WifiConfigCenter::GetInstance().GetScanMidState(instId);
92     WIFI_LOGI("CheckAndStartScanService scanState: %{public}d", static_cast<int>(scanState));
93     if (scanState != WifiOprMidState::CLOSED) {
94         /* If the scanning function is enabled when the STA is not enabled, you need to start the scheduled
95              scanning function immediately when the STA is enabled. */
96         IScanService *pService = WifiServiceManager::GetInstance().GetScanServiceInst(instId);
97         if (pService != nullptr) {
98             pService->DisableScan(false);
99         }
100         return;
101     }
102     if (!WifiConfigCenter::GetInstance().SetScanMidState(scanState, WifiOprMidState::OPENING, instId)) {
103         WIFI_LOGW("Failed to set scan mid state opening!");
104         return;
105     }
106     ErrCode errCode = TryToStartScanService(instId);
107     if (errCode != WIFI_OPT_SUCCESS) {
108         WifiConfigCenter::GetInstance().SetScanMidState(WifiOprMidState::OPENING, WifiOprMidState::CLOSED, instId);
109         WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_SCAN, instId);
110     }
111 #ifndef OHOS_ARCH_LITE
112     WifiCountryCodeManager::GetInstance().SetWifiCountryCodeFromExternal();
113 #endif
114     return;
115 }
116 
TryToStartScanService(int instId)117 ErrCode WifiScanManager::TryToStartScanService(int instId)
118 {
119     ErrCode errCode = WIFI_OPT_FAILED;
120     do {
121         if (WifiServiceManager::GetInstance().CheckAndEnforceService(WIFI_SERVICE_SCAN) < 0) {
122             WIFI_LOGE("Load %{public}s service failed!", WIFI_SERVICE_SCAN);
123             break;
124         }
125         IScanService *pService = WifiServiceManager::GetInstance().GetScanServiceInst(instId);
126         if (pService == nullptr) {
127             WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_SCAN);
128             break;
129         }
130         errCode = pService->RegisterScanCallbacks(mScanCallback);
131         if (errCode != WIFI_OPT_SUCCESS) {
132             WIFI_LOGE("Register scan service callback failed!");
133             break;
134         }
135         errCode = pService->Init();
136         if (errCode != WIFI_OPT_SUCCESS) {
137             WIFI_LOGE("init scan service failed, ret %{public}d!", static_cast<int>(errCode));
138             break;
139         }
140         IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
141         if (pEnhanceService == nullptr) {
142             WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_ENHANCE);
143             break;
144         }
145         errCode = pService->SetEnhanceService(pEnhanceService);
146         if (errCode != WIFI_OPT_SUCCESS) {
147             WIFI_LOGE("SetEnhanceService failed, ret %{public}d!", static_cast<int>(errCode));
148             break;
149         }
150     } while (0);
151     return errCode;
152 }
153 
CheckAndStopScanService(int instId)154 void WifiScanManager::CheckAndStopScanService(int instId)
155 {
156     /**
157      * Check unload SCAN service
158      * When anytime scanning is enabled and the control policy allows, airplane
159      * mode and power saving mode are disabled.   --- Do not disable the scan
160      * service. Otherwise, disable the SCAN service.
161      */
162     WifiOprMidState scanState = WifiConfigCenter::GetInstance().GetScanMidState(instId);
163     WIFI_LOGI("[CheckAndStopScanService] scanState %{public}d!", static_cast<int>(scanState));
164     if (scanState != WifiOprMidState::OPENING && scanState != WifiOprMidState::RUNNING) {
165         return;
166     }
167     ScanControlInfo info;
168     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanControlInfo(info, instId);
169     if (WifiSettings::GetInstance().GetScanAlwaysState() && IsAllowScanAnyTime(info) &&
170         WifiConfigCenter::GetInstance().GetAirplaneModeState() == MODE_STATE_CLOSE &&
171         WifiConfigCenter::GetInstance().GetPowerSavingModeState() == MODE_STATE_CLOSE) {
172         return;
173     }
174     IScanService *pService = WifiServiceManager::GetInstance().GetScanServiceInst(instId);
175     if (pService == nullptr) {
176         WIFI_LOGE("[CheckAndStopScanService] scan service is null.");
177         WifiManager::GetInstance().PushServiceCloseMsg(WifiCloseServiceCode::SCAN_SERVICE_CLOSE, instId);
178         WifiConfigCenter::GetInstance().SetScanMidState(scanState, WifiOprMidState::CLOSED, instId);
179         return;
180     }
181     ErrCode ret = pService->DisableScan(true);
182     if (ret != WIFI_OPT_SUCCESS) { // scan service is not exist
183         WIFI_LOGE("[CheckAndStopScanService] UnInit service failed!");
184     }
185 }
186 
CloseScanService(int instId)187 void WifiScanManager::CloseScanService(int instId)
188 {
189     WIFI_LOGI("close scan service");
190     WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_SCAN, instId);
191     WifiConfigCenter::GetInstance().SetScanMidState(WifiOprMidState::CLOSED, instId);
192     WifiOprMidState staState = WifiConfigCenter::GetInstance().GetWifiMidState(instId);
193     WIFI_LOGI("CloseScanService, current sta state:%{public}d", staState);
194     if (staState == WifiOprMidState::OPENING || staState == WifiOprMidState::RUNNING) {
195         CheckAndStartScanService(instId);
196         return;
197     }
198 #ifndef OHOS_ARCH_LITE
199     StartUnloadScanSaTimer();
200 #endif
201     return;
202 }
203 
InitScanCallback(void)204 void WifiScanManager::InitScanCallback(void)
205 {
206     using namespace std::placeholders;
207     mScanCallback.OnScanStartEvent = std::bind(&WifiScanManager::DealScanOpenRes, this, _1);
208     mScanCallback.OnScanStopEvent = std::bind(&WifiScanManager::DealScanCloseRes, this, _1);
209     mScanCallback.OnScanFinishEvent = std::bind(&WifiScanManager::DealScanFinished, this, _1, _2);
210     mScanCallback.OnScanInfoEvent = std::bind(&WifiScanManager::DealScanInfoNotify, this, _1, _2);
211     mScanCallback.OnStoreScanInfoEvent = std::bind(&WifiScanManager::DealStoreScanInfoEvent, this, _1, _2);
212 
213     mStaCallback.callbackModuleName = "WifiScanManager";
214 }
215 
DealScanOpenRes(int instId)216 void WifiScanManager::DealScanOpenRes(int instId)
217 {
218     WifiConfigCenter::GetInstance().SetScanMidState(WifiOprMidState::OPENING, WifiOprMidState::RUNNING, instId);
219 }
220 
DealScanCloseRes(int instId)221 void WifiScanManager::DealScanCloseRes(int instId)
222 {
223     WifiManager::GetInstance().PushServiceCloseMsg(WifiCloseServiceCode::SCAN_SERVICE_CLOSE, instId);
224 }
225 
DealScanFinished(int state,int instId)226 void WifiScanManager::DealScanFinished(int state, int instId)
227 {
228     WIFI_LOGE("%{public}s, state: %{public}d!", __func__, state);
229     WifiEventCallbackMsg cbMsg;
230     cbMsg.msgCode = WIFI_CBK_MSG_SCAN_STATE_CHANGE;
231     cbMsg.msgData = state;
232     cbMsg.id = instId;
233     WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
234 }
235 
DealScanInfoNotify(std::vector<InterScanInfo> & results,int instId)236 void WifiScanManager::DealScanInfoNotify(std::vector<InterScanInfo> &results, int instId)
237 {
238     if (WifiConfigCenter::GetInstance().GetWifiMidState(instId) == WifiOprMidState::RUNNING) {
239         IStaService *pService = WifiServiceManager::GetInstance().GetStaServiceInst(instId);
240         if (pService != nullptr) {
241             pService->ConnectivityManager(results);
242         }
243 
244 #ifdef FEATURE_WIFI_PRO_SUPPORT
245         IWifiProService *pWifiProService = WifiServiceManager::GetInstance().GetWifiProServiceInst(instId);
246         if (pWifiProService != nullptr) {
247             pWifiProService->DealScanResult(results);
248         }
249 #endif
250     }
251 }
252 
DealStoreScanInfoEvent(std::vector<InterScanInfo> & results,int instId)253 void WifiScanManager::DealStoreScanInfoEvent(std::vector<InterScanInfo> &results, int instId)
254 {
255     WIFI_LOGI("DealStoreScanInfoEvent");
256 }
257 
DealStaOpened(int instId)258 void WifiScanManager::DealStaOpened(int instId)
259 {
260     WIFI_LOGI("wifi opened id=%{public}d", instId);
261     WifiConfigCenter::GetInstance().GetWifiScanConfig()->CleanWifiCategoryRecord();
262     CheckAndStartScanService(instId);
263 }
264 }  // namespace Wifi
265 }  // namespace OHOS