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 "scan_service.h"
17 #include <cinttypes>
18 #include "log_helper.h"
19 #include "wifi_global_func.h"
20 #include "wifi_internal_msg.h"
21 #include "wifi_logger.h"
22 #include "wifi_config_center.h"
23 #include "wifi_channel_helper.h"
24 #include "wifi_sta_hal_interface.h"
25 #include "wifi_common_util.h"
26 #include "wifi_hisysevent.h"
27 #include "wifi_common_event_helper.h"
28 #include "wifi_code_convert.h"
29 DEFINE_WIFILOG_SCAN_LABEL("ScanService");
30 
31 #define MIN(A, B) (((A) >= (B)) ? (B) : (A))
32 #define MAX(A, B) (((A) >= (B)) ? (A) : (B))
33 
34 namespace OHOS {
35 namespace Wifi {
ScanService(int instId)36 ScanService::ScanService(int instId)
37     : pScanStateMachine(nullptr),
38       pScanMonitor(nullptr),
39       scanStartedFlag(false),
40       scanConfigStoreIndex(0),
41       pnoScanStartTime(0),
42       staStatus(static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED)),
43       isPnoScanBegined(false),
44       autoNetworkSelection(false),
45       lastSystemScanTime(0),
46       pnoScanFailedNum(0),
47       systemScanFailedNum(0),
48       disableScanFlag(false),
49       customCurrentTime(0),
50       customSceneForbidCount(0),
51       scanTrustMode(false),
52       lastFreezeState(false),
53       isAbsFreezeScaned(false),
54       scanResultBackup(-1),
55       mEnhanceService(nullptr),
56       m_instId(instId),
57       lastNetworkQuality(0),
58       chipsetCategory(static_cast<int>(WifiCategory::DEFAULT)),
59       chipsetFeatrureCapability(0),
60       isChipsetInfoObtained(false)
61 {}
62 
~ScanService()63 ScanService::~ScanService()
64 {
65     WIFI_LOGI("Enter ~ScanService.\n");
66 
67     if (pScanMonitor != nullptr) {
68         pScanMonitor->SetScanStateMachine(nullptr);
69         delete pScanMonitor;
70         pScanMonitor = nullptr;
71     }
72 
73     if (pScanStateMachine != nullptr) {
74         delete pScanStateMachine;
75         pScanStateMachine = nullptr;
76     }
77     WifiConfigCenter::GetInstance().GetWifiScanConfig()->ClearScanInfoList();
78 }
79 
InitScanService(const IScanSerivceCallbacks & scanSerivceCallbacks)80 bool ScanService::InitScanService(const IScanSerivceCallbacks &scanSerivceCallbacks)
81 {
82     WIFI_LOGI("Enter ScanService::InitScanService.\n");
83     {
84         std::unique_lock<std::shared_mutex> lock(mScanCallbackMutex);
85         mScanSerivceCallbacks = scanSerivceCallbacks;
86     }
87     pScanStateMachine = new (std::nothrow) ScanStateMachine(m_instId);
88     if (pScanStateMachine == nullptr) {
89         WIFI_LOGE("Alloc pScanStateMachine failed.\n");
90         return false;
91     }
92 
93     if (!pScanStateMachine->InitScanStateMachine()) {
94         WIFI_LOGE("InitScanStateMachine failed.\n");
95         return false;
96     }
97 
98     if (!pScanStateMachine->EnrollScanStatusListener(
99         std::bind(&ScanService::HandleScanStatusReport, this, std::placeholders::_1))) {
100         WIFI_LOGE("ScanStateMachine_->EnrollScanStatusListener failed.\n");
101         return false;
102     }
103     pScanMonitor = new (std::nothrow) ScanMonitor(m_instId);
104     if (pScanMonitor == nullptr) {
105         WIFI_LOGE("Alloc pScanMonitor failed.\n");
106         return false;
107     }
108 
109     if (!pScanMonitor->InitScanMonitor()) {
110         WIFI_LOGE("InitScanMonitor failed.\n");
111         return false;
112     }
113 
114     pScanMonitor->SetScanStateMachine(pScanStateMachine);
115     int delayMs = 100;
116     pScanStateMachine->MessageExecutedLater(static_cast<int>(CMD_SCAN_PREPARE), delayMs);
117     GetScanControlInfo();
118 #ifndef OHOS_ARCH_LITE
119     std::string moduleName = "ScanService_" + std::to_string(m_instId);
120     m_scanObserver = std::make_shared<WifiCountryCodeChangeObserver>(moduleName, *pScanStateMachine);
121     if (m_scanObserver == nullptr) {
122         WIFI_LOGI("m_scanObserver is null\n");
123         return false;
124     }
125     WifiCountryCodeManager::GetInstance().RegisterWifiCountryCodeChangeListener(m_scanObserver);
126 #endif
127     return true;
128 }
129 
UnInitScanService()130 void ScanService::UnInitScanService()
131 {
132     WIFI_LOGI("Enter UnInitScanService.\n");
133 #ifndef OHOS_ARCH_LITE
134     // deregistration country code change notification
135     WifiCountryCodeManager::GetInstance().UnregisterWifiCountryCodeChangeListener(m_scanObserver);
136 #endif
137     pScanMonitor->UnInitScanMonitor();
138     pScanStateMachine->StopTimer(static_cast<int>(SYSTEM_SCAN_TIMER));
139     pScanStateMachine->StopTimer(static_cast<int>(DISCONNECTED_SCAN_TIMER));
140     pScanStateMachine->StopTimer(static_cast<int>(RESTART_PNO_SCAN_TIMER));
141     pScanStateMachine->SendMessage(static_cast<int>(CMD_SCAN_FINISH));
142     scanStartedFlag = false;
143     return;
144 }
145 
RegisterScanCallbacks(const IScanSerivceCallbacks & iScanSerivceCallbacks)146 void ScanService::RegisterScanCallbacks(const IScanSerivceCallbacks &iScanSerivceCallbacks)
147 {
148     mScanSerivceCallbacks = iScanSerivceCallbacks;
149 }
150 
SetEnhanceService(IEnhanceService * enhanceService)151 void ScanService::SetEnhanceService(IEnhanceService* enhanceService)
152 {
153     mEnhanceService = enhanceService;
154 }
155 
HandleScanStatusReport(ScanStatusReport & scanStatusReport)156 void ScanService::HandleScanStatusReport(ScanStatusReport &scanStatusReport)
157 {
158     WIFI_LOGI("Enter HandleScanStatusReport, status:%{public}d", scanStatusReport.status);
159 
160     switch (scanStatusReport.status) {
161         case SCAN_STARTED_STATUS: {
162             if (pScanStateMachine == nullptr) {
163                 WIFI_LOGE("HandleScanStatusReport-SCAN_STARTED_STATUS pScanStateMachine is null\n");
164                 return;
165             }
166             scanStartedFlag = true;
167             /* Pno scan maybe has started, stop it first. */
168             pScanStateMachine->SendMessage(CMD_STOP_PNO_SCAN);
169             ReportScanStartEvent();
170             SystemScanProcess(true);
171             break;
172         }
173         case SCAN_FINISHED_STATUS: {
174             ReportScanStopEvent();
175             break;
176         }
177         case COMMON_SCAN_SUCCESS: {
178             HandleCommonScanInfo(scanStatusReport.requestIndexList, scanStatusReport.scanInfoList);
179             break;
180         }
181         case COMMON_SCAN_FAILED: {
182             HandleCommonScanFailed(scanStatusReport.requestIndexList);
183             break;
184         }
185         case PNO_SCAN_INFO: {
186             pnoScanFailedNum = 0;
187             HandlePnoScanInfo(scanStatusReport.scanInfoList);
188             break;
189         }
190         case PNO_SCAN_FAILED: {
191             if (pScanStateMachine == nullptr) {
192                 WIFI_LOGE("HandleScanStatusReport-PNO_SCAN_FAILED pScanStateMachine is null\n");
193                 return;
194             }
195             /* Start the timer and restart the PNO scanning after a delay. */
196             pScanStateMachine->StartTimer(static_cast<int>(RESTART_PNO_SCAN_TIMER), RESTART_PNO_SCAN_TIME);
197             EndPnoScan();
198             break;
199         }
200         case SCAN_INNER_EVENT: {
201             HandleInnerEventReport(scanStatusReport.innerEvent);
202             break;
203         }
204         default: {
205             WIFI_LOGI("HandleStatusReport: status is error.\n");
206             break;
207         }
208     }
209     return;
210 }
211 
HandleInnerEventReport(ScanInnerEventType innerEvent)212 void ScanService::HandleInnerEventReport(ScanInnerEventType innerEvent)
213 {
214     WIFI_LOGI("Enter HandleInnerEventReport.\n");
215 
216     switch (innerEvent) {
217         case SYSTEM_SCAN_TIMER: {
218             HandleSystemScanTimeout();
219             break;
220         }
221         case DISCONNECTED_SCAN_TIMER: {
222             HandleDisconnectedScanTimeout();
223             break;
224         }
225         case RESTART_PNO_SCAN_TIMER: {
226             RestartPnoScanTimeOut();
227             break;
228         }
229         case RESTART_SYSTEM_SCAN_TIMER: {
230             RestartSystemScanTimeOut();
231             break;
232         }
233         default: {
234             break;
235         }
236     }
237 }
238 
Scan(ScanType scanType)239 ErrCode ScanService::Scan(ScanType scanType)
240 {
241     WIFI_LOGI("Enter Scan, scanType:%{public}d.\n", static_cast<int>(scanType));
242     if (!scanStartedFlag) {
243         WIFI_LOGE("Scan service has not started.\n");
244         return WIFI_OPT_FAILED;
245     }
246 
247     ErrCode rlt = ScanControlInner(scanType);
248     if (rlt != WIFI_OPT_SUCCESS) {
249         return rlt;
250     }
251 
252     ScanConfig scanConfig;
253     /*
254      * Invoke the interface provided by the configuration center to obtain the
255      * hidden network list.
256      */
257     int uid = 0;
258 #ifndef OHOS_ARCH_LITE
259     uid = GetCallingUid();
260 #endif
261     if (uid != LOCATOR_SA_UID) {
262         if (!GetHiddenNetworkSsidList(scanConfig.hiddenNetworkSsid)) {
263             WIFI_LOGE("GetHiddenNetworkSsidList failed.\n");
264         }
265     }
266 
267     scanConfig.scanBand = SCAN_BAND_BOTH_WITH_DFS;
268     scanConfig.fullScanFlag = true;
269     scanConfig.scanType = scanType;
270     scanConfig.scanStyle = SCAN_TYPE_HIGH_ACCURACY;
271     if (!SingleScan(scanConfig)) {
272         WIFI_LOGE("SingleScan failed.\n");
273         return WIFI_OPT_FAILED;
274     }
275 
276     return WIFI_OPT_SUCCESS;
277 }
278 
ScanWithParam(const WifiScanParams & params,ScanType scanType)279 ErrCode ScanService::ScanWithParam(const WifiScanParams &params, ScanType scanType)
280 {
281     WIFI_LOGI("Enter ScanWithParam, freqs num:%{public}d.\n", (int)params.freqs.size());
282 
283     if (!scanStartedFlag) {
284         WIFI_LOGE("Scan service has not started.\n");
285         return WIFI_OPT_FAILED;
286     }
287 
288     ErrCode rlt = ScanControlInner(scanType);
289     if (rlt != WIFI_OPT_SUCCESS) {
290         return rlt;
291     }
292 
293     if ((params.band < static_cast<int>(SCAN_BAND_UNSPECIFIED)) ||
294         (params.band > static_cast<int>(SCAN_BAND_BOTH_WITH_DFS))) {
295         WIFI_LOGE("params.band is error.\n");
296         return WIFI_OPT_FAILED;
297     }
298 
299     /* When the frequency is specified, the band must be SCAN_BAND_UNSPECIFIED. */
300     if (params.freqs.empty() && (params.band == static_cast<int>(SCAN_BAND_UNSPECIFIED))) {
301         WIFI_LOGE("params is error.\n");
302         return WIFI_OPT_FAILED;
303     }
304 
305     ScanConfig scanConfig;
306     if (params.ssid.empty() && params.bssid.empty() && (params.band == static_cast<int>(SCAN_BAND_BOTH_WITH_DFS))) {
307         scanConfig.fullScanFlag = true;
308     }
309 
310     if (!params.ssid.empty()) {
311         scanConfig.hiddenNetworkSsid.push_back(params.ssid);
312     } else {
313         /*
314          * Invoke the interface provided by the configuration center to obtain the
315          * hidden network list.
316          */
317         if (!GetHiddenNetworkSsidList(scanConfig.hiddenNetworkSsid)) {
318             WIFI_LOGE("GetHiddenNetworkSsidList failed.\n");
319         }
320     }
321 
322     scanConfig.scanBand = static_cast<ScanBandType>(params.band);
323     scanConfig.scanFreqs.assign(params.freqs.begin(), params.freqs.end());
324     scanConfig.ssid = params.ssid;
325     scanConfig.bssid = params.bssid;
326     scanConfig.scanType = scanType;
327     scanConfig.scanningWithParamFlag = true;
328     scanConfig.scanStyle = SCAN_TYPE_HIGH_ACCURACY;
329 
330     if (!SingleScan(scanConfig)) {
331         WIFI_LOGE("SingleScan failed.\n");
332         return WIFI_OPT_FAILED;
333     }
334 
335     return WIFI_OPT_SUCCESS;
336 }
337 
ScanControlInner(ScanType scanType)338 ErrCode ScanService::ScanControlInner(ScanType scanType)
339 {
340     if (scanType == ScanType::SCAN_TYPE_EXTERN) {
341         ErrCode rlt = ApplyScanPolices(ScanType::SCAN_TYPE_EXTERN);
342         if (rlt != WIFI_OPT_SUCCESS) {
343             return rlt;
344         }
345     } else {
346         if (!AllowScanByDisableScanCtrl()) {
347             WIFI_LOGW("internal scan not allow by disable scan control.");
348             return WIFI_OPT_FAILED;
349         }
350         if (!AllowScanByHid2dState()) {
351             WIFI_LOGW("internal scan not allow by hid2d state");
352             return WIFI_OPT_FAILED;
353         }
354     }
355     return WIFI_OPT_SUCCESS;
356 }
357 
DisableScan(bool disable)358 ErrCode ScanService::DisableScan(bool disable)
359 {
360     LOGI("Enter DisableScan");
361     if (disableScanFlag == disable) {
362         if (!disable) {
363             SystemScanProcess(true);
364         }
365         return WIFI_OPT_SUCCESS;
366     }
367     disableScanFlag = disable;
368     if (disableScanFlag) {
369         pScanStateMachine->SendMessage(static_cast<int>(CMD_DISABLE_SCAN));
370     } else {
371         pScanStateMachine->SendMessage(static_cast<int>(CMD_SCAN_PREPARE));
372     }
373     return WIFI_OPT_SUCCESS;
374 }
375 
StartWifiPnoScan(bool isStartAction,int periodMs,int suspendReason)376 ErrCode ScanService::StartWifiPnoScan(bool isStartAction, int periodMs, int suspendReason)
377 {
378     LOGI("Enter StartWifiPnoScan isStart:%{public}d", isStartAction);
379     if (isStartAction) {
380         StopPnoScan();
381         pnoScanIntervalMode.scanIntervalMode.interval = periodMs / 1000;
382         BeginPnoScan();
383     } else {
384         StopPnoScan();
385         WriteWifiPnoScanHiSysEvent(MODE_STATE_CLOSE, suspendReason);
386     }
387     return WIFI_OPT_SUCCESS;
388 }
389 
StopPnoScan()390 void ScanService::StopPnoScan()
391 {
392     if (!isPnoScanBegined) {
393         return;
394     }
395     EndPnoScan();
396     pnoScanFailedNum = 0;
397     pScanStateMachine->StopTimer(static_cast<int>(RESTART_PNO_SCAN_TIMER));
398 }
399 
SingleScan(ScanConfig & scanConfig)400 bool ScanService::SingleScan(ScanConfig &scanConfig)
401 {
402     WIFI_LOGI("Enter SingleScan.\n");
403 
404     GetAllowBandFreqsControlInfo(scanConfig.scanBand, scanConfig.scanFreqs);
405     if ((scanConfig.scanBand == SCAN_BAND_UNSPECIFIED) && (scanConfig.scanFreqs.empty())) {
406         WIFI_LOGE("Have no allowed band or freq.\n");
407         return false;
408     }
409 
410     InterScanConfig interConfig;
411     interConfig.fullScanFlag = scanConfig.fullScanFlag;
412     interConfig.hiddenNetworkSsid.assign(scanConfig.hiddenNetworkSsid.begin(), scanConfig.hiddenNetworkSsid.end());
413     interConfig.scanStyle = scanConfig.scanStyle;
414 
415     /* Specified frequency */
416     if (scanConfig.scanBand == SCAN_BAND_UNSPECIFIED) {
417         interConfig.scanFreqs.assign(scanConfig.scanFreqs.begin(), scanConfig.scanFreqs.end());
418         /*
419          * When band is SCAN_BAND_BOTH_WITH_DFS, need to scan all frequency,
420          * scanFreqs can be empty.
421          */
422     } else if (scanConfig.scanBand != SCAN_BAND_BOTH_WITH_DFS) {
423         /* Converting frequency bands to frequencies. */
424         if (!WifiChannelHelper::GetInstance().GetAvailableScanFreqs(scanConfig.scanBand, interConfig.scanFreqs)) {
425             WIFI_LOGE("GetBandFreqs failed.\n");
426             return false;
427         }
428     }
429 
430     /* Save the configuration. */
431     int requestIndex = StoreRequestScanConfig(scanConfig, interConfig);
432     if (requestIndex == MAX_SCAN_CONFIG_STORE_INDEX) {
433         WIFI_LOGE("StoreRequestScanConfig failed.\n");
434         return false;
435     }
436 
437     if (pScanStateMachine == nullptr) {
438         WIFI_LOGE("pScanStateMachine is null.\n");
439         return false;
440     }
441     /* Construct a message. */
442     InternalMessagePtr interMessage =
443         pScanStateMachine->CreateMessage(static_cast<int>(CMD_START_COMMON_SCAN), requestIndex);
444     if (interMessage == nullptr) {
445         std::unique_lock<std::mutex> lock(scanConfigMapMutex);
446         scanConfigMap.erase(requestIndex);
447         WIFI_LOGE("CreateMessage failed.\n");
448         return false;
449     }
450 
451     if (!AddScanMessageBody(interMessage, interConfig)) {
452         std::unique_lock<std::mutex> lock(scanConfigMapMutex);
453         scanConfigMap.erase(requestIndex);
454         MessageManage::GetInstance().ReclaimMsg(interMessage);
455         WIFI_LOGE("AddScanMessageBody failed.\n");
456         return false;
457     }
458     pScanStateMachine->SendMessage(interMessage);
459 
460     return true;
461 }
462 
GetBandFreqs(ScanBandType band,std::vector<int> & freqs)463 bool ScanService::GetBandFreqs(ScanBandType band, std::vector<int> &freqs)
464 {
465     WIFI_LOGI("Enter GetBandFreqs.\n");
466 
467     switch (band) {
468         case SCAN_BAND_24_GHZ: {
469             freqs.assign(freqs2G.begin(), freqs2G.end());
470             return true;
471         }
472 
473         case SCAN_BAND_5_GHZ: {
474             freqs.assign(freqs5G.begin(), freqs5G.end());
475             return true;
476         }
477 
478         case SCAN_BAND_BOTH: {
479             freqs.insert(freqs.end(), freqs2G.begin(), freqs2G.end());
480             freqs.insert(freqs.end(), freqs5G.begin(), freqs5G.end());
481             return true;
482         }
483 
484         case SCAN_BAND_5_GHZ_DFS_ONLY: {
485             freqs.assign(freqsDfs.begin(), freqsDfs.end());
486             return true;
487         }
488 
489         case SCAN_BAND_5_GHZ_WITH_DFS: {
490             freqs.insert(freqs.end(), freqs5G.begin(), freqs5G.end());
491             freqs.insert(freqs.end(), freqsDfs.begin(), freqsDfs.end());
492             return true;
493         }
494 
495         case SCAN_BAND_BOTH_WITH_DFS: {
496             freqs.insert(freqs.end(), freqs2G.begin(), freqs2G.end());
497             freqs.insert(freqs.end(), freqs5G.begin(), freqs5G.end());
498             freqs.insert(freqs.end(), freqsDfs.begin(), freqsDfs.end());
499             return true;
500         }
501 
502         default:
503             WIFI_LOGE("bandType(%{public}d) is error.\n", band);
504             return false;
505     }
506 }
507 
AddScanMessageBody(InternalMessagePtr interMessage,const InterScanConfig & interConfig)508 bool ScanService::AddScanMessageBody(InternalMessagePtr interMessage, const InterScanConfig &interConfig)
509 {
510     WIFI_LOGI("Enter AddScanMessageBody.\n");
511 
512     if (interMessage == nullptr) {
513         WIFI_LOGE("interMessage is null.\n");
514         return false;
515     }
516 
517     interMessage->AddIntMessageBody(interConfig.hiddenNetworkSsid.size());
518     std::vector<std::string>::const_iterator iter = interConfig.hiddenNetworkSsid.begin();
519     for (; iter != interConfig.hiddenNetworkSsid.end(); ++iter) {
520         interMessage->AddStringMessageBody(*iter);
521     }
522 
523     interMessage->AddIntMessageBody(interConfig.scanFreqs.size());
524     std::vector<int>::const_iterator iterFreq = interConfig.scanFreqs.begin();
525     for (; iterFreq != interConfig.scanFreqs.end(); ++iterFreq) {
526         interMessage->AddIntMessageBody(*iterFreq);
527     }
528 
529     interMessage->AddIntMessageBody(static_cast<int>(interConfig.fullScanFlag));
530     interMessage->AddIntMessageBody(interConfig.backScanPeriod);
531     interMessage->AddIntMessageBody(interConfig.bssidsNumPerScan);
532     interMessage->AddIntMessageBody(interConfig.maxScansCache);
533     interMessage->AddIntMessageBody(interConfig.maxBackScanPeriod);
534     interMessage->AddIntMessageBody(interConfig.scanStyle);
535 
536     return true;
537 }
538 
StoreRequestScanConfig(const ScanConfig & scanConfig,const InterScanConfig & interConfig)539 int ScanService::StoreRequestScanConfig(const ScanConfig &scanConfig, const InterScanConfig &interConfig)
540 {
541     WIFI_LOGI("Enter StoreRequestScanConfig.\n");
542 
543     int i = 0;
544     for (i = 0; i < MAX_SCAN_CONFIG_STORE_INDEX; i++) {
545         scanConfigStoreIndex++;
546         if (scanConfigStoreIndex >= MAX_SCAN_CONFIG_STORE_INDEX) {
547             scanConfigStoreIndex = 0;
548         }
549 
550         ScanConfigMap::iterator iter = scanConfigMap.find(scanConfigStoreIndex);
551         if (iter == scanConfigMap.end()) {
552             break;
553         }
554     }
555 
556     if (i == MAX_SCAN_CONFIG_STORE_INDEX) {
557         return MAX_SCAN_CONFIG_STORE_INDEX;
558     }
559 
560     StoreScanConfig storeScanConfig;
561     storeScanConfig.ssid = scanConfig.ssid;
562     storeScanConfig.bssid = scanConfig.bssid;
563     storeScanConfig.scanFreqs.assign(interConfig.scanFreqs.begin(), interConfig.scanFreqs.end());
564 
565     struct timespec times = {0, 0};
566     clock_gettime(CLOCK_MONOTONIC, &times);
567     storeScanConfig.scanTime =
568         static_cast<int64_t>(times.tv_sec) * SECOND_TO_MICRO_SECOND + times.tv_nsec / SECOND_TO_MILLI_SECOND;
569     storeScanConfig.fullScanFlag = scanConfig.fullScanFlag;
570     storeScanConfig.scanType = scanConfig.scanType;
571     storeScanConfig.scanningWithParamFlag = scanConfig.scanningWithParamFlag;
572 
573     std::unique_lock<std::mutex> lock(scanConfigMapMutex);
574     scanConfigMap.insert(std::pair<int, StoreScanConfig>(scanConfigStoreIndex, storeScanConfig));
575     WIFI_LOGI("StoreRequestScanConfig, add success, scanConfigStoreIndex: %{public}d", scanConfigStoreIndex);
576     return scanConfigStoreIndex;
577 }
578 
HandleCommonScanFailed(std::vector<int> & requestIndexList)579 void ScanService::HandleCommonScanFailed(std::vector<int> &requestIndexList)
580 {
581     WIFI_LOGI("Enter HandleCommonScanFailed, requestIndexList size: %{public}d.",
582         static_cast<int>(requestIndexList.size()));
583 
584     std::unique_lock<std::mutex> lock(scanConfigMapMutex);
585     bool needRestartSystemScan = false;
586     bool needReportScanResult = false;
587     for (std::vector<int>::iterator reqIter = requestIndexList.begin(); reqIter != requestIndexList.end(); ++reqIter) {
588         ScanConfigMap::iterator configIter = scanConfigMap.find(*reqIter);
589         /* No configuration found. */
590         if (configIter == scanConfigMap.end()) {
591             continue;
592         }
593         if (configIter->second.scanType != ScanType::SCAN_TYPE_SYSTEMTIMER) {
594             needReportScanResult = true;
595         } else {
596             needRestartSystemScan = true;
597             systemScanFailedNum++;
598         }
599         scanConfigMap.erase(*reqIter);
600     }
601     if (pScanStateMachine != nullptr && needRestartSystemScan && systemScanFailedNum < MAX_SYSTEM_SCAN_FAILED_NUM
602         && staStatus == static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED)) {
603         pScanStateMachine->StopTimer(static_cast<int>(RESTART_SYSTEM_SCAN_TIMER));
604         pScanStateMachine->StartTimer(static_cast<int>(RESTART_SYSTEM_SCAN_TIMER), RESTART_SYSTEM_SCAN_TIME);
605     }
606     if (needReportScanResult) {
607         /* Notification of the end of scanning. */
608         ReportScanFinishEvent(static_cast<int>(ScanHandleNotify::SCAN_FAIL));
609         scanResultBackup = static_cast<int>(ScanHandleNotify::SCAN_FAIL);
610     }
611     WifiCommonEventHelper::PublishScanFinishedEvent(static_cast<int>(ScanHandleNotify::SCAN_FAIL), "OnScanFinished");
612     return;
613 }
614 
HandleCommonScanInfo(std::vector<int> & requestIndexList,std::vector<InterScanInfo> & scanInfoList)615 void ScanService::HandleCommonScanInfo(
616     std::vector<int> &requestIndexList, std::vector<InterScanInfo> &scanInfoList)
617 {
618     WIFI_LOGI("HandleCommonScanInfo, requestIndexList size: %{public}d.", static_cast<int>(requestIndexList.size()));
619     if (!isChipsetInfoObtained) {
620         InitChipsetInfo();
621     }
622     bool fullScanStored = false;
623     {
624         std::unique_lock<std::mutex> lock(scanConfigMapMutex);
625         HandleScanResults(requestIndexList, scanInfoList, fullScanStored);
626     }
627     pScanStateMachine->StopTimer(static_cast<int>(RESTART_SYSTEM_SCAN_TIMER));
628     if (fullScanStored) {
629         TryToRestoreSavedNetwork();
630     }
631     struct timespec times = {0, 0};
632     clock_gettime(CLOCK_MONOTONIC, &times);
633     int64_t availableTime = static_cast<int64_t>(times.tv_sec) * SECOND_TO_MICRO_SECOND +
634         times.tv_nsec / SECOND_TO_MILLI_SECOND;
635     if (mEnhanceService != nullptr) {
636         mEnhanceService->SetEnhanceParam(availableTime);
637     }
638     /* Send the scanning result to the module registered for listening. */
639     ScanInfoHandlerMap::iterator handleIter = scanInfoHandlerMap.begin();
640     for (; handleIter != scanInfoHandlerMap.end(); ++handleIter) {
641         if (handleIter->second) {
642             handleIter->second(scanInfoList);
643         }
644     }
645 
646     /* Send the result to the interface service. */
647     ReportScanInfos(scanInfoList);
648 
649     return;
650 }
651 
HandleScanResults(std::vector<int> & requestIndexList,std::vector<InterScanInfo> & scanInfoList,bool & fullScanStored)652 void ScanService::HandleScanResults(std::vector<int> &requestIndexList, std::vector<InterScanInfo> &scanInfoList,
653     bool &fullScanStored)
654 {
655     bool needReportScanResult = false;
656     for (std::vector<int>::iterator reqIter = requestIndexList.begin(); reqIter != requestIndexList.end(); ++reqIter) {
657         ScanConfigMap::iterator configIter = scanConfigMap.find(*reqIter);
658         /* No configuration found. */
659         if (configIter == scanConfigMap.end()) {
660             continue;
661         }
662         if (configIter->second.scanType != ScanType::SCAN_TYPE_SYSTEMTIMER) {
663             needReportScanResult = true;
664         } else {
665             systemScanFailedNum = 0;
666         }
667         /* Full Scan Info. */
668         if (configIter->second.fullScanFlag) {
669             if (fullScanStored) {
670                 scanConfigMap.erase(*reqIter);
671                 continue;
672             }
673             if (StoreFullScanInfo(configIter->second, scanInfoList)) {
674                 fullScanStored = true;
675                 scanResultBackup = static_cast<int>(ScanHandleNotify::SCAN_OK);
676             } else {
677                 WIFI_LOGE("StoreFullScanInfo failed.\n");
678             }
679             /* Specify Scan Info. */
680         } else {
681             if (!StoreUserScanInfo(configIter->second, scanInfoList)) {
682                 WIFI_LOGE("StoreUserScanInfo failed.\n");
683             }
684             scanResultBackup = static_cast<int>(ScanHandleNotify::SCAN_OK);
685         }
686         scanConfigMap.erase(*reqIter);
687     }
688     if (needReportScanResult) {
689         ReportScanFinishEvent(static_cast<int>(ScanHandleNotify::SCAN_OK));
690     } else {
691         WIFI_LOGI("No need to report scan finish event.\n");
692     }
693     WifiCommonEventHelper::PublishScanFinishedEvent(static_cast<int>(ScanHandleNotify::SCAN_OK), "OnScanFinished");
694 }
695 
GetWifiMaxSupportedMaxSpeed(const InterScanInfo & scanInfo,const int & maxNumberSpatialStreams)696 int ScanService::GetWifiMaxSupportedMaxSpeed(const InterScanInfo &scanInfo, const int &maxNumberSpatialStreams)
697 {
698     int wifiStandard = 0;
699     bool is11bMode = scanInfo.IsWifi11bMode();
700     scanInfo.GetWifiStandard(wifiStandard);
701     return WifiMaxThroughput(wifiStandard, is11bMode, scanInfo.channelWidth,
702         MAX_RSSI, maxNumberSpatialStreams, 0);
703 }
704 
ConvertScanInfo(WifiScanInfo & scanInfo,const InterScanInfo & interInfo)705 void ScanService::ConvertScanInfo(WifiScanInfo &scanInfo, const InterScanInfo &interInfo)
706 {
707     scanInfo.bssid = interInfo.bssid;
708     scanInfo.bssidType = REAL_DEVICE_ADDRESS;
709     scanInfo.ssid = interInfo.ssid;
710     scanInfo.oriSsid = interInfo.oriSsid;
711     scanInfo.capabilities = interInfo.capabilities;
712     scanInfo.frequency = interInfo.frequency;
713     scanInfo.channelWidth = interInfo.channelWidth;
714     scanInfo.centerFrequency0 = interInfo.centerFrequency0;
715     scanInfo.centerFrequency1 = interInfo.centerFrequency1;
716     scanInfo.rssi = interInfo.rssi;
717     scanInfo.securityType = interInfo.securityType;
718     scanInfo.infoElems = interInfo.infoElems;
719     scanInfo.features = interInfo.features;
720     scanInfo.timestamp = interInfo.timestamp;
721     scanInfo.band = interInfo.band;
722     scanInfo.disappearCount = 0;
723     scanInfo.maxSupportedRxLinkSpeed = GetWifiMaxSupportedMaxSpeed(interInfo, MAX_RX_SPATIAL_STREAMS);
724     scanInfo.maxSupportedTxLinkSpeed = GetWifiMaxSupportedMaxSpeed(interInfo, MAX_TX_SPATIAL_STREAMS);
725     interInfo.GetWifiStandard(scanInfo.wifiStandard);
726     scanInfo.isHiLinkNetwork = interInfo.isHiLinkNetwork;
727     scanInfo.supportedWifiCategory = interInfo.supportedWifiCategory;
728 }
729 
MergeScanResult(std::vector<WifiScanInfo> & results,std::vector<WifiScanInfo> & storeInfoList)730 void ScanService::MergeScanResult(std::vector<WifiScanInfo> &results, std::vector<WifiScanInfo> &storeInfoList)
731 {
732     for (auto storedIter = storeInfoList.begin(); storedIter != storeInfoList.end(); ++storedIter) {
733         bool find = false;
734         for (auto iter = results.begin(); iter != results.end(); ++iter) {
735             if (iter->bssid == storedIter->bssid) {
736                 iter = results.erase(iter);
737                 find = true;
738                 break;
739             }
740         }
741         if (!find) {
742 #ifdef SUPPORT_RANDOM_MAC_ADDR
743             WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(WifiMacAddrInfoType::WIFI_SCANINFO_MACADDR_INFO,
744                 storedIter->bssid, "");
745 #endif
746             WIFI_LOGI("ScanInfo add new ssid=%{public}s bssid=%{public}s rssi=%{public}d.\n",
747                 SsidAnonymize(storedIter->ssid).c_str(), MacAnonymize(storedIter->bssid).c_str(), storedIter->rssi);
748         }
749         results.push_back(*storedIter);
750     }
751 
752     WIFI_LOGI("Save %{public}d scan results.", (int)(results.size()));
753     if (WifiConfigCenter::GetInstance().GetWifiScanConfig()->SaveScanInfoList(results) != 0) {
754         WIFI_LOGE("SaveScanInfoList failed.\n");
755     }
756     WifiConfigCenter::GetInstance().UpdateLinkedInfo(m_instId);
757 }
758 
TryToRestoreSavedNetwork()759 void ScanService::TryToRestoreSavedNetwork()
760 {
761     WifiScanParams params;
762     std::vector<WifiScanInfo> results;
763     WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(results);
764     std::vector<std::string> savedNetworkSsid;
765     GetSavedNetworkSsidList(savedNetworkSsid);
766     for (auto iter = results.begin(); iter != results.end(); ++iter) {
767         if (iter->disappearCount > 0
768             && std::find(savedNetworkSsid.begin(), savedNetworkSsid.end(), iter->ssid) != savedNetworkSsid.end()) {
769             params.freqs.push_back(iter->frequency);
770         }
771     }
772     if (!params.freqs.empty()) {
773         ScanWithParam(params, ScanType::SCAN_TYPE_SYSTEMTIMER);
774     }
775 }
776 
StoreFullScanInfo(const StoreScanConfig & scanConfig,std::vector<InterScanInfo> & scanInfoList)777 bool ScanService::StoreFullScanInfo(
778     const StoreScanConfig &scanConfig, std::vector<InterScanInfo> &scanInfoList)
779 {
780     WIFI_LOGI("Enter StoreFullScanInfo.\n");
781     /* Filtering result. */
782     WIFI_LOGI("scanConfig.scanTime is %" PRId64 ".\n", scanConfig.scanTime);
783     WIFI_LOGI("Receive %{public}d scan results.\n", (int)(scanInfoList.size()));
784     if (scanInfoList.size() == 0) {
785         /* Don't overwrite ScanInfoList */
786         std::vector<WifiScanInfo> results;
787         int ret = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(results);
788         if (ret != 0) {
789             WIFI_LOGW("GetScanInfoList return error. \n");
790         }
791         for (auto iter = results.begin(); iter != results.end(); ++iter) {
792             iter->disappearCount++;
793         }
794         if (WifiConfigCenter::GetInstance().GetWifiScanConfig()->SaveScanInfoList(results) != 0) {
795             WIFI_LOGE("SaveScanInfoList failed.\n");
796         }
797         return true;
798     }
799 
800     std::vector<WifiScanInfo> storeInfoList;
801     for (auto iter = scanInfoList.begin(); iter != scanInfoList.end(); ++iter) {
802         WifiScanInfo scanInfo;
803         if (mEnhanceService != nullptr) {
804             iter->supportedWifiCategory = mEnhanceService->GetWifiCategory(iter->infoElems,
805                 chipsetCategory, chipsetFeatrureCapability);
806             WifiConfigCenter::GetInstance().GetWifiScanConfig()->RecordWifiCategory(
807                 iter->bssid, iter->supportedWifiCategory);
808             WIFI_LOGD("GetWifiCategory supportedWifiCategory=%{public}d.\n",
809                 static_cast<int>(iter->supportedWifiCategory));
810         }
811         ConvertScanInfo(scanInfo, *iter);
812         storeInfoList.push_back(scanInfo);
813     }
814 
815     std::vector<WifiScanInfo> results;
816     int ret = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(results);
817     if (ret != 0) {
818         WIFI_LOGW("GetScanInfoList return error. \n");
819     }
820     for (auto iter = results.begin(); iter != results.end(); ++iter) {
821         iter->disappearCount++;
822     }
823     MergeScanResult(results, storeInfoList);
824 
825     return true;
826 }
827 
StoreUserScanInfo(const StoreScanConfig & scanConfig,std::vector<InterScanInfo> & scanInfoList)828 bool ScanService::StoreUserScanInfo(const StoreScanConfig &scanConfig, std::vector<InterScanInfo> &scanInfoList)
829 {
830     WIFI_LOGI("Enter StoreUserScanInfo.\n");
831 
832     std::vector<WifiScanInfo> storeInfoList;
833     std::vector<InterScanInfo>::const_iterator iter = scanInfoList.begin();
834     for (; iter != scanInfoList.end(); ++iter) {
835         /* frequency filtering. */
836         if (!scanConfig.scanFreqs.empty()) {
837             if (std::find(scanConfig.scanFreqs.begin(), scanConfig.scanFreqs.end(), iter->frequency) ==
838                 scanConfig.scanFreqs.end()) {
839                 continue;
840             }
841         }
842 
843         /* SSID filtering. */
844         if ((!scanConfig.ssid.empty()) && (scanConfig.ssid != iter->ssid)) {
845             continue;
846         }
847 
848         /* BSSID filtering. */
849         if ((!scanConfig.bssid.empty()) && (scanConfig.bssid != iter->bssid)) {
850             continue;
851         }
852 
853         WifiScanInfo scanInfo;
854         ConvertScanInfo(scanInfo, *iter);
855         storeInfoList.push_back(scanInfo);
856     }
857     if (storeInfoList.empty()) {
858         WIFI_LOGI("Specified channel scan no results.\n");
859         return false;
860     }
861 
862     std::vector<WifiScanInfo> results;
863     int ret = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanInfoList(results);
864     if (ret != 0) {
865         WIFI_LOGW("GetScanInfoList return error. \n");
866     }
867     MergeScanResult(results, storeInfoList);
868 
869     /*
870      * The specified parameter scanning is initiated by the system and
871      * store in the configuration center.
872      */
873     ReportStoreScanInfos(scanInfoList);
874 
875     return true;
876 }
877 
ReportScanStartEvent()878 void ScanService::ReportScanStartEvent()
879 {
880     std::shared_lock<std::shared_mutex> lock(mScanCallbackMutex);
881     mScanSerivceCallbacks.OnScanStartEvent(m_instId);
882 }
883 
ReportScanStopEvent()884 void ScanService::ReportScanStopEvent()
885 {
886     std::shared_lock<std::shared_mutex> lock(mScanCallbackMutex);
887     mScanSerivceCallbacks.OnScanStopEvent(m_instId);
888 }
889 
ReportScanFinishEvent(int event)890 void ScanService::ReportScanFinishEvent(int event)
891 {
892     std::shared_lock<std::shared_mutex> lock(mScanCallbackMutex);
893     mScanSerivceCallbacks.OnScanFinishEvent(event, m_instId);
894 }
895 
ReportScanInfos(std::vector<InterScanInfo> & interScanList)896 void ScanService::ReportScanInfos(std::vector<InterScanInfo> &interScanList)
897 {
898     WIFI_LOGI("Enter ScanService::ReportScanInfos.\n");
899     std::shared_lock<std::shared_mutex> lock(mScanCallbackMutex);
900     mScanSerivceCallbacks.OnScanInfoEvent(interScanList, m_instId);
901     return;
902 }
903 
ReportStoreScanInfos(std::vector<InterScanInfo> & interScanList)904 void ScanService::ReportStoreScanInfos(std::vector<InterScanInfo> &interScanList)
905 {
906     WIFI_LOGI("Enter ScanService::ReportStoreScanInfos.\n");
907     std::shared_lock<std::shared_mutex> lock(mScanCallbackMutex);
908     mScanSerivceCallbacks.OnStoreScanInfoEvent(interScanList, m_instId);
909     return;
910 }
911 
BeginPnoScan()912 bool ScanService::BeginPnoScan()
913 {
914     WIFI_LOGI("Enter BeginPnoScan.\n");
915 
916     if (isPnoScanBegined) {
917         WIFI_LOGI("PNO scan has started.\n");
918         return false;
919     }
920 
921     ErrCode rlt = ApplyScanPolices(ScanType::SCAN_TYPE_PNO);
922     if (rlt != WIFI_OPT_SUCCESS) {
923         return false;
924     }
925 
926     PnoScanConfig pnoScanConfig;
927     /* Obtain the network list from the configuration center. */
928     if (!GetSavedNetworkSsidList(pnoScanConfig.savedNetworkSsid)) {
929         WIFI_LOGE("GetSavedNetworkSsidList failed.\n");
930         return false;
931     }
932     if (pnoScanConfig.savedNetworkSsid.size() == 0) {
933         WIFI_LOGE("Have no saved network, not need to start PNO scan.\n");
934         return false;
935     }
936     if (!GetHiddenNetworkSsidList(pnoScanConfig.hiddenNetworkSsid)) {
937         WIFI_LOGE("GetHiddenNetworkSsidList failed.\n");
938         return false;
939     }
940 
941     pnoScanConfig.scanInterval = DEFAULT_PNO_SCAN_INTERVAL;
942     /* Querying a Scan Policy */
943     if (pnoScanIntervalMode.scanIntervalMode.interval > 0) {
944         pnoScanConfig.scanInterval = pnoScanIntervalMode.scanIntervalMode.interval;
945     }
946 
947     pnoScanConfig.minRssi2Dot4Ghz = WifiSettings::GetInstance().GetMinRssi2Dot4Ghz(m_instId);
948     pnoScanConfig.minRssi5Ghz = WifiSettings::GetInstance().GetMinRssi5Ghz(m_instId);
949 
950     InterScanConfig interConfig;
951     interConfig.fullScanFlag = true;
952     if (!WifiChannelHelper::GetInstance().GetAvailableScanFreqs(SCAN_BAND_BOTH_WITH_DFS, interConfig.scanFreqs)) {
953         WIFI_LOGE("GetBandFreqs failed.\n");
954         return false;
955     }
956 
957     if (!PnoScan(pnoScanConfig, interConfig)) {
958         WIFI_LOGE("PnoScan failed.\n");
959         return false;
960     }
961     isPnoScanBegined = true;
962     WriteWifiPnoScanHiSysEvent(MODE_STATE_OPEN, 0);
963 
964     return true;
965 }
966 
PnoScan(const PnoScanConfig & pnoScanConfig,const InterScanConfig & interScanConfig)967 bool ScanService::PnoScan(const PnoScanConfig &pnoScanConfig, const InterScanConfig &interScanConfig)
968 {
969     WIFI_LOGI("Enter PnoScan.\n");
970     if (pScanStateMachine == nullptr) {
971         WIFI_LOGE("pScanStateMachine is null.\n");
972         return false;
973     }
974     /* Construct a message. */
975     InternalMessagePtr interMessage = pScanStateMachine->CreateMessage(CMD_START_PNO_SCAN);
976     if (interMessage == nullptr) {
977         WIFI_LOGE("CreateMessage failed.\n");
978         return false;
979     }
980 
981     if (!AddPnoScanMessageBody(interMessage, pnoScanConfig)) {
982         MessageManage::GetInstance().ReclaimMsg(interMessage);
983         WIFI_LOGE("AddPnoScanMessageBody failed.\n");
984         return false;
985     }
986 
987     if (!AddScanMessageBody(interMessage, interScanConfig)) {
988         MessageManage::GetInstance().ReclaimMsg(interMessage);
989         WIFI_LOGE("AddScanMessageBody failed.\n");
990         return false;
991     }
992 
993     WIFI_LOGI("Begin: send message.");
994     pScanStateMachine->SendMessage(interMessage);
995     WIFI_LOGI("End: send message.");
996 
997     struct timespec times = {0, 0};
998     clock_gettime(CLOCK_MONOTONIC, &times);
999     pnoScanStartTime =
1000         static_cast<int64_t>(times.tv_sec) * SECOND_TO_MILLI_SECOND + times.tv_nsec / SECOND_TO_MICRO_SECOND;
1001 
1002     return true;
1003 }
1004 
AddPnoScanMessageBody(InternalMessagePtr interMessage,const PnoScanConfig & pnoScanConfig)1005 bool ScanService::AddPnoScanMessageBody(InternalMessagePtr interMessage, const PnoScanConfig &pnoScanConfig)
1006 {
1007     WIFI_LOGI("Enter AddPnoScanMessageBody.\n");
1008 
1009     if (interMessage == nullptr) {
1010         WIFI_LOGE("interMessage is null.\n");
1011         return false;
1012     }
1013 
1014     interMessage->AddIntMessageBody(pnoScanConfig.scanInterval);
1015     interMessage->AddIntMessageBody(pnoScanConfig.minRssi2Dot4Ghz);
1016     interMessage->AddIntMessageBody(pnoScanConfig.minRssi5Ghz);
1017 
1018     interMessage->AddIntMessageBody(pnoScanConfig.hiddenNetworkSsid.size());
1019     auto iter = pnoScanConfig.hiddenNetworkSsid.begin();
1020     for (; iter != pnoScanConfig.hiddenNetworkSsid.end(); ++iter) {
1021         interMessage->AddStringMessageBody(*iter);
1022     }
1023 
1024     interMessage->AddIntMessageBody(pnoScanConfig.savedNetworkSsid.size());
1025     auto iter2 = pnoScanConfig.savedNetworkSsid.begin();
1026     for (; iter2 != pnoScanConfig.savedNetworkSsid.end(); ++iter2) {
1027         interMessage->AddStringMessageBody(*iter2);
1028     }
1029 
1030     interMessage->AddIntMessageBody(pnoScanConfig.freqs.size());
1031     auto iter3 = pnoScanConfig.freqs.begin();
1032     for (; iter3 != pnoScanConfig.freqs.end(); ++iter3) {
1033         interMessage->AddIntMessageBody(*iter3);
1034     }
1035 
1036     return true;
1037 }
1038 
HandlePnoScanInfo(std::vector<InterScanInfo> & scanInfoList)1039 void ScanService::HandlePnoScanInfo(std::vector<InterScanInfo> &scanInfoList)
1040 {
1041     WIFI_LOGI("Enter HandlePnoScanInfo.\n");
1042     InitChipsetInfo();
1043     std::vector<InterScanInfo> filterScanInfo;
1044     std::vector<InterScanInfo>::iterator iter = scanInfoList.begin();
1045     for (; iter != scanInfoList.end(); ++iter) {
1046         if ((iter->timestamp / SECOND_TO_MILLI_SECOND) > pnoScanStartTime) {
1047             filterScanInfo.push_back(*iter);
1048             WIFI_LOGD("InterScanInfo bssid:%{public}s, ssid:%{public}s, capabilities:%{public}s,"
1049                 "frequency:%{public}d, rssi:%{public}d, timestamp:%" PRId64 ".\n",
1050                 MacAnonymize(iter->bssid).c_str(), SsidAnonymize(iter->ssid).c_str(), iter->capabilities.c_str(),
1051                 iter->frequency, iter->rssi, iter->timestamp);
1052         }
1053         if (mEnhanceService != nullptr) {
1054             WifiCategory category = mEnhanceService->GetWifiCategory(iter->infoElems,
1055                 chipsetCategory, chipsetFeatrureCapability);
1056             WifiConfigCenter::GetInstance().GetWifiScanConfig()->RecordWifiCategory(iter->bssid, category);
1057         }
1058     }
1059 
1060     /* Send the scanning result to the module registered for listening. */
1061     PnoScanInfoHandlerMap::iterator handleIter = pnoScanInfoHandlerMap.begin();
1062     for (; handleIter != pnoScanInfoHandlerMap.end(); ++handleIter) {
1063         if (handleIter->second) {
1064             handleIter->second(filterScanInfo);
1065         }
1066     }
1067 
1068     /* send message to main service. */
1069     ReportScanInfos(filterScanInfo);
1070 
1071     return;
1072 }
1073 
EndPnoScan()1074 void ScanService::EndPnoScan()
1075 {
1076     WIFI_LOGI("Enter EndPnoScan.\n");
1077 
1078     if (!isPnoScanBegined) {
1079         return;
1080     }
1081     if (pScanStateMachine == nullptr) {
1082         WIFI_LOGE("pScanStateMachine is null.\n");
1083         return;
1084     }
1085     pScanStateMachine->SendMessage(CMD_STOP_PNO_SCAN);
1086     isPnoScanBegined = false;
1087     return;
1088 }
1089 
HandleScreenStatusChanged()1090 void ScanService::HandleScreenStatusChanged()
1091 {
1092     WIFI_LOGI("Enter HandleScreenStatusChanged.");
1093     SystemScanProcess(staStatus == static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED));
1094     return;
1095 }
1096 
HandleStaStatusChanged(int status)1097 void ScanService::HandleStaStatusChanged(int status)
1098 {
1099     WIFI_LOGI("Enter HandleStaStatusChanged, change to status: %{public}d.", status);
1100 
1101     staStatus = status;
1102     switch (staStatus) {
1103         case static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED): {
1104             DisconnectedTimerScan();
1105             SystemScanProcess(true);
1106             break;
1107         }
1108         case static_cast<int>(OperateResState::CONNECT_AP_CONNECTED): {
1109             SystemScanProcess(false);
1110             std::unique_lock<std::mutex> lock(scanConfigMapMutex);
1111             scanConfigMap.clear();
1112             break;
1113         }
1114         default: {
1115             StopSystemScan();
1116         }
1117     }
1118     WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetStaScene(GetStaScene());
1119     WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetStaSceneForbidCount(0);
1120     return;
1121 }
1122 
HandleNetworkQualityChanged(int status)1123 void ScanService::HandleNetworkQualityChanged(int status)
1124 {
1125     WIFI_LOGI("Enter HandleNetworkQualityChanged, change to status: %{public}d.", status);
1126     if (lastNetworkQuality == status) {
1127         return;
1128     }
1129     switch (status) {
1130         case static_cast<int>(OperateResState::CONNECT_NETWORK_DISABLED): {
1131             SystemScanProcess(true);
1132             break;
1133         }
1134         case static_cast<int>(OperateResState::CONNECT_NETWORK_ENABLED): {
1135             SystemScanProcess(false);
1136             break;
1137         }
1138         default: {
1139             break;
1140         }
1141     }
1142     lastNetworkQuality = status;
1143 }
1144 
HandleMovingFreezeChanged()1145 void ScanService::HandleMovingFreezeChanged()
1146 {
1147     LOGI("Enter HandleMovingFreezeChanged.");
1148     int freezeState = WifiConfigCenter::GetInstance().GetFreezeModeState();
1149     /* Moving -> Freeze, set the scanned flag to false. */
1150     if (!lastFreezeState && freezeState) {
1151         WIFI_LOGW("set movingFreeze scanned false.");
1152         WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetMovingFreezeScaned(false);
1153     }
1154     int screenState = WifiConfigCenter::GetInstance().GetScreenState();
1155     if (staStatus != static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED) || screenState == MODE_STATE_CLOSE) {
1156         WIFI_LOGW("Moving change do nothing.");
1157         return;
1158     }
1159     {
1160         std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1161         lastFreezeState = freezeState;
1162     }
1163     SystemScanProcess(false);
1164 }
1165 
HandleCustomStatusChanged(int customScene,int customSceneStatus)1166 void ScanService::HandleCustomStatusChanged(int customScene, int customSceneStatus)
1167 {
1168     WIFI_LOGI("Enter HandleCustomStatusChanged.");
1169     WIFI_LOGD("sizeof(time_t):%{public}d", int(sizeof(time_t)));
1170 
1171     time_t now = time(nullptr);
1172     WIFI_LOGI("customScene:%{public}d, status:%{public}d", customScene, customSceneStatus);
1173     if (customSceneStatus == MODE_STATE_OPEN) {
1174         customSceneTimeMap.insert(std::pair<int, int>(customScene, now));
1175     }
1176     if (customSceneStatus == MODE_STATE_CLOSE) {
1177         customSceneTimeMap.erase(customScene);
1178     }
1179     SystemScanProcess(false);
1180     customSceneForbidCount = 0;
1181 
1182     return;
1183 }
1184 
HandleGetCustomSceneState(std::map<int,time_t> & sceneMap) const1185 void ScanService::HandleGetCustomSceneState(std::map<int, time_t>& sceneMap) const
1186 {
1187     sceneMap = customSceneTimeMap;
1188 }
1189 
HandleAutoConnectStateChanged(bool success)1190 void ScanService::HandleAutoConnectStateChanged(bool success)
1191 {
1192     WIFI_LOGI("Enter HandleAutoConnectStateChanged\n");
1193     int screenState = WifiConfigCenter::GetInstance().GetScreenState();
1194     if (staStatus == static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED)
1195         && screenState != MODE_STATE_CLOSE && !success && systemScanIntervalMode.scanIntervalMode.count <= 1) {
1196         if (Scan(ScanType::SCAN_TYPE_SYSTEMTIMER) != WIFI_OPT_SUCCESS) {
1197             WIFI_LOGE("Scan failed.");
1198         }
1199         std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1200         systemScanIntervalMode.scanIntervalMode.count++;
1201     }
1202 }
1203 
SystemScanProcess(bool scanAtOnce)1204 void ScanService::SystemScanProcess(bool scanAtOnce)
1205 {
1206     WIFI_LOGI("Enter SystemScanProcess, scanAtOnce:%{public}d.", scanAtOnce);
1207     StopSystemScan();
1208 
1209     int state = WifiConfigCenter::GetInstance().GetScreenState();
1210     WIFI_LOGI("Screen state(1:OPEN, 2:CLOSE): %{public}d.", state);
1211     if (state == MODE_STATE_OPEN || state == MODE_STATE_DEFAULT) {
1212         {
1213             std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1214             int i = 0;
1215             for (auto iter = scanControlInfo.scanIntervalList.begin(); iter != scanControlInfo.scanIntervalList.end();
1216                 ++iter) {
1217                 if (iter->scanScene == SCAN_SCENE_ALL && iter->scanMode == ScanMode::SYSTEM_TIMER_SCAN &&
1218                     iter->isSingle == false) {
1219                     WIFI_LOGI("iter[%{public}d]: intervalMode:%{public}d, interval:%{public}d, count:%{public}d",
1220                         i++, iter->intervalMode, iter->interval, iter->count);
1221                     systemScanIntervalMode.scanIntervalMode.intervalMode = iter->intervalMode;
1222                     systemScanIntervalMode.scanIntervalMode.interval = iter->interval;
1223                     systemScanIntervalMode.scanIntervalMode.count = iter->count;
1224                     systemScanIntervalMode.expScanCount = 0;
1225                 }
1226             }
1227         }
1228         StartSystemTimerScan(scanAtOnce);
1229     } else {
1230         if (!BeginPnoScan()) {
1231             WIFI_LOGE("BeginPnoScan failed.");
1232             return;
1233         }
1234     }
1235 
1236     return;
1237 }
1238 
StopSystemScan()1239 void ScanService::StopSystemScan()
1240 {
1241     WIFI_LOGI("Enter StopSystemScan.");
1242     if (pScanStateMachine == nullptr) {
1243         WIFI_LOGE("pScanStateMachine is null.\n");
1244         return;
1245     }
1246     pScanStateMachine->StopTimer(static_cast<int>(SYSTEM_SCAN_TIMER));
1247     pScanStateMachine->StopTimer(static_cast<int>(RESTART_SYSTEM_SCAN_TIMER));
1248     EndPnoScan();
1249     pnoScanFailedNum = 0;
1250     systemScanFailedNum = 0;
1251     pScanStateMachine->StopTimer(static_cast<int>(RESTART_PNO_SCAN_TIMER));
1252     return;
1253 }
1254 
StartSystemTimerScan(bool scanAtOnce)1255 void ScanService::StartSystemTimerScan(bool scanAtOnce)
1256 {
1257     WIFI_LOGI("Enter StartSystemTimerScan, scanAtOnce: %{public}d.", scanAtOnce);
1258     ErrCode rlt = ApplyScanPolices(ScanType::SCAN_TYPE_SYSTEMTIMER);
1259     if (rlt == WIFI_OPT_FAILED) {
1260         return;
1261     }
1262     int scanTime = SYSTEM_SCAN_INIT_TIME;
1263     if (systemScanIntervalMode.scanIntervalMode.interval > 0) {
1264         scanTime = systemScanIntervalMode.scanIntervalMode.interval;
1265     }
1266     if (rlt == WIFI_OPT_SUCCESS) {
1267         struct timespec times = { 0, 0 };
1268         clock_gettime(CLOCK_MONOTONIC, &times);
1269         int64_t nowTime =
1270             static_cast<int64_t>(times.tv_sec) * SECOND_TO_MILLI_SECOND + times.tv_nsec / SECOND_TO_MICRO_SECOND;
1271         int sinceLastScan = 0;
1272         if (lastSystemScanTime != 0) {
1273             sinceLastScan = nowTime - lastSystemScanTime;
1274         }
1275 
1276         /*
1277         * The scan is performed immediately, the first scan is required,
1278         * or the time since the last scan is longer than the scan interval.
1279         */
1280         if (scanAtOnce || (lastSystemScanTime == 0) ||
1281             (sinceLastScan / SECOND_TO_MILLI_SECOND >= systemScanIntervalMode.scanIntervalMode.interval)) {
1282             if (Scan(ScanType::SCAN_TYPE_SYSTEMTIMER) != WIFI_OPT_SUCCESS) {
1283                 WIFI_LOGE("Scan failed.");
1284             }
1285             lastSystemScanTime = nowTime;
1286         } else {
1287             scanTime = systemScanIntervalMode.scanIntervalMode.interval - sinceLastScan / SECOND_TO_MILLI_SECOND;
1288         }
1289     }
1290     WIFI_LOGI("StartSystemTimerScan, scanTime: %{public}d,  interval:%{public}d,  count:%{public}d",
1291         scanTime,
1292         systemScanIntervalMode.scanIntervalMode.interval,
1293         systemScanIntervalMode.scanIntervalMode.count);
1294     pScanStateMachine->StartTimer(static_cast<int>(SYSTEM_SCAN_TIMER), scanTime * SECOND_TO_MILLI_SECOND);
1295 
1296     return;
1297 }
1298 
HandleSystemScanTimeout()1299 void ScanService::HandleSystemScanTimeout()
1300 {
1301     StartSystemTimerScan(true);
1302     return;
1303 }
1304 
DisconnectedTimerScan()1305 void ScanService::DisconnectedTimerScan()
1306 {
1307     WIFI_LOGI("Enter DisconnectedTimerScan.\n");
1308     if (pScanStateMachine == nullptr) {
1309         WIFI_LOGE("pScanStateMachine is null.\n");
1310         return;
1311     }
1312     if (WifiConfigCenter::GetInstance().GetWifiState(m_instId) != static_cast<int>(WifiState::ENABLED)) {
1313         return;
1314     }
1315     pScanStateMachine->StopTimer(static_cast<int>(DISCONNECTED_SCAN_TIMER));
1316     pScanStateMachine->StartTimer(static_cast<int>(DISCONNECTED_SCAN_TIMER), DISCONNECTED_SCAN_INTERVAL);
1317     return;
1318 }
1319 
HandleDisconnectedScanTimeout()1320 void ScanService::HandleDisconnectedScanTimeout()
1321 {
1322     WIFI_LOGI("Enter HandleDisconnectedScanTimeout.\n");
1323 
1324     if (WifiConfigCenter::GetInstance().GetWifiState(m_instId) != static_cast<int>(WifiState::ENABLED)) {
1325         return;
1326     }
1327     if (staStatus != static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED)) {
1328         return;
1329     }
1330     if (pScanStateMachine == nullptr) {
1331         WIFI_LOGE("pScanStateMachine is null.\n");
1332         return;
1333     }
1334     if (Scan(ScanType::SCAN_TYPE_SYSTEMTIMER) != WIFI_OPT_SUCCESS) {
1335         WIFI_LOGE("Scan failed.");
1336     }
1337     pScanStateMachine->StopTimer(static_cast<int>(DISCONNECTED_SCAN_TIMER));
1338     pScanStateMachine->StartTimer(static_cast<int>(DISCONNECTED_SCAN_TIMER), DISCONNECTED_SCAN_INTERVAL);
1339 
1340     return;
1341 }
1342 
RestartPnoScanTimeOut()1343 void ScanService::RestartPnoScanTimeOut()
1344 {
1345     WIFI_LOGI("Enter RestartPnoScanTimeOut.\n");
1346     pnoScanFailedNum++;
1347     if (pnoScanFailedNum > MAX_PNO_SCAN_FAILED_NUM) {
1348         WIFI_LOGE("Over max pno failed number.");
1349         return;
1350     }
1351 
1352     if (!BeginPnoScan()) {
1353         WIFI_LOGE("BeginPnoScan failed.");
1354         return;
1355     }
1356 
1357     return;
1358 }
1359 
RestartSystemScanTimeOut()1360 void ScanService::RestartSystemScanTimeOut()
1361 {
1362     WIFI_LOGI("Enter RestartSystemScanTimeOut.\n");
1363     if (Scan(ScanType::SCAN_TYPE_SYSTEMTIMER) != WIFI_OPT_SUCCESS) {
1364         WIFI_LOGE("RestartSystemScanTimeOut failed.");
1365     }
1366 }
1367 
GetScanControlInfo()1368 void ScanService::GetScanControlInfo()
1369 {
1370     WIFI_LOGI("Enter GetScanControlInfo.\n");
1371 
1372     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1373     if (WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetScanControlInfo(scanControlInfo) != 0) {
1374         WIFI_LOGE("GetScanControlInfo failed");
1375     }
1376     std::map<std::string, std::vector<std::string>> filterMap;
1377     if (WifiSettings::GetInstance().GetPackageFilterMap(filterMap) != 0) {
1378         WIFI_LOGE("WifiSettings::GetInstance().GetPackageFilterMap failed");
1379     }
1380     WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetPackageFilter(filterMap);
1381     scan_thermal_trust_list = filterMap["scan_thermal_filter"];
1382     scan_frequency_trust_list = filterMap["scan_frequency_filter"];
1383     scan_screen_off_trust_list = filterMap["scan_screen_off_filter"];
1384     scan_gps_block_list = filterMap["scan_gps_filter"];
1385     scan_hid2d_list = filterMap["scan_hid2d_filter"];
1386     return;
1387 }
1388 
AllowExternScan()1389 ErrCode ScanService::AllowExternScan()
1390 {
1391     WIFI_LOGI("Enter AllowExternScan SUPPORT_SCAN_CONTROL.\n");
1392     int appId = 0;
1393 #ifndef OHOS_ARCH_LITE
1394     appId = GetCallingUid();
1395 #endif
1396     ScanMode scanMode = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetAppRunningState();
1397     WIFI_LOGI("AllowExternScan, scanMode is %{public}d", (int)scanMode);
1398 
1399     if (!AllowExternScanByIntervalMode(appId, SCAN_SCENE_FREQUENCY_ORIGIN, scanMode)) {
1400         WIFI_LOGW("extern scan not allow by origin interval mode");
1401         return WIFI_OPT_FAILED;
1402     }
1403 
1404     if (!AllowScanByDisableScanCtrl()) {
1405         WIFI_LOGW("extern scan not allow by disable scan control.");
1406         return WIFI_OPT_FAILED;
1407     }
1408 
1409     WIFI_LOGI("extern scan has allowed");
1410     return WIFI_OPT_SUCCESS;
1411 }
1412 
AllowSystemTimerScan()1413 ErrCode ScanService::AllowSystemTimerScan()
1414 {
1415     WIFI_LOGI("Enter AllowSystemTimerScan.\n");
1416 
1417     if (WifiConfigCenter::GetInstance().GetWifiState(m_instId) != static_cast<int>(WifiState::ENABLED)) {
1418         WIFI_LOGW("system timer scan not allow when wifi disable");
1419         return WIFI_OPT_FAILED;
1420     }
1421     if (!AllowScanByDisableScanCtrl()) {
1422         WIFI_LOGW("system timer scan not allow by disable scan control.");
1423         return WIFI_OPT_FAILED;
1424     }
1425     /* The network is connected and cannot be automatically switched. */
1426     autoNetworkSelection = WifiSettings::GetInstance().GetWhetherToAllowNetworkSwitchover(m_instId);
1427     if ((staStatus == static_cast<int>(OperateResState::CONNECT_AP_CONNECTED)) && (!autoNetworkSelection)) {
1428         WIFI_LOGW("system timer scan not allowed for CONNECT_AP_CONNECTED");
1429         return WIFI_OPT_FAILED;
1430     }
1431 
1432     if (staStatus != static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED) &&
1433         staStatus != static_cast<int>(OperateResState::CONNECT_AP_CONNECTED)) {
1434         WIFI_LOGW("system timer scan not allowed for staStatus: %{public}d.", staStatus);
1435         return WIFI_OPT_SCAN_NEXT_PERIOD;
1436     }
1437 
1438     int staScene = GetStaScene();
1439     /* Determines whether to allow scanning based on the STA status. */
1440     if (staScene == SCAN_SCENE_MAX) {
1441         WIFI_LOGW("system timer scan not allowed for invalid staScene: %{public}d", staScene);
1442         return WIFI_OPT_SCAN_NEXT_PERIOD;
1443     }
1444 
1445     if (!AllowScanByHid2dState()) {
1446         WIFI_LOGW("system timer scan not allow by hid2d state");
1447         return WIFI_OPT_SCAN_NEXT_PERIOD;
1448     }
1449 
1450     if (!AllowScanDuringStaScene(staScene, ScanMode::SYSTEM_TIMER_SCAN)) {
1451         WIFI_LOGW("system timer scan not allowed, staScene: %{public}d", staScene);
1452         return WIFI_OPT_SCAN_NEXT_PERIOD;
1453     }
1454 
1455     if (!AllowScanDuringCustomScene(ScanMode::SYSTEM_TIMER_SCAN)) {
1456         WIFI_LOGW("system timer scan not allowed");
1457         return WIFI_OPT_SCAN_NEXT_PERIOD;
1458     }
1459 
1460 #ifdef SUPPORT_SCAN_CONTROL
1461     SystemScanByInterval(staScene, systemScanIntervalMode.scanIntervalMode.interval,
1462         systemScanIntervalMode.scanIntervalMode.count);
1463 #else
1464     if (!AllowScanByMovingFreeze(ScanMode::SYSTEM_TIMER_SCAN)) {
1465         return WIFI_OPT_MOVING_FREEZE_CTRL;
1466     }
1467 
1468     {
1469         std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1470         for (auto iter = scanControlInfo.scanIntervalList.begin(); iter != scanControlInfo.scanIntervalList.end();
1471             ++iter) {
1472             if (iter->scanScene == SCAN_SCENE_ALL && iter->scanMode == ScanMode::SYSTEM_TIMER_SCAN &&
1473                 iter->isSingle == false) {
1474                 if (!SystemScanByInterval(systemScanIntervalMode.expScanCount,
1475                     systemScanIntervalMode.scanIntervalMode.interval, systemScanIntervalMode.scanIntervalMode.count)) {
1476                     return WIFI_OPT_FAILED;
1477                 }
1478             }
1479         }
1480     }
1481 #endif
1482     WIFI_LOGI("allow system timer scan");
1483     return WIFI_OPT_SUCCESS;
1484 }
1485 
AllowPnoScan()1486 ErrCode ScanService::AllowPnoScan()
1487 {
1488     WIFI_LOGD("Enter AllowPnoScan.\n");
1489 
1490     if (WifiConfigCenter::GetInstance().GetWifiState(m_instId) != static_cast<int>(WifiState::ENABLED)) {
1491         WIFI_LOGW("pnoScan not allow when wifi disable");
1492         return WIFI_OPT_FAILED;
1493     }
1494     if (staStatus != static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED)) {
1495         WIFI_LOGE("NOT allow PNO scan for staStatus: %{public}d", staStatus);
1496         return WIFI_OPT_FAILED;
1497     }
1498 
1499     if (!AllowScanByHid2dState()) {
1500         WIFI_LOGW("pnoScan scan not allow by hid2d state");
1501         return WIFI_OPT_FAILED;
1502     }
1503     int staScene = GetStaScene();
1504     if (staScene == SCAN_SCENE_MAX) {
1505         WIFI_LOGE("NOT allow PNO scan for staScene: %{public}d", staScene);
1506         return WIFI_OPT_FAILED;
1507     }
1508     if (!AllowScanDuringStaScene(staScene, ScanMode::PNO_SCAN)) {
1509         WIFI_LOGW("pnoScan is not allowed for forbid map, staScene is %{public}d", staScene);
1510         return WIFI_OPT_FAILED;
1511     }
1512     if (!AllowScanDuringCustomScene(ScanMode::PNO_SCAN)) {
1513         WIFI_LOGD("pnoScan is not allowed for forbid map");
1514         return WIFI_OPT_FAILED;
1515     }
1516 
1517 #ifndef SUPPORT_SCAN_CONTROL
1518     {
1519         std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1520         for (auto iter = scanControlInfo.scanIntervalList.begin(); iter != scanControlInfo.scanIntervalList.end();
1521             ++iter) {
1522             if (iter->scanScene == SCAN_SCENE_ALL && iter->scanMode == ScanMode::PNO_SCAN && iter->isSingle == false) {
1523                 pnoScanIntervalMode.scanIntervalMode.intervalMode = iter->intervalMode;
1524                 pnoScanIntervalMode.scanIntervalMode.interval = iter->interval;
1525                 pnoScanIntervalMode.scanIntervalMode.count = iter->count;
1526                 if (!PnoScanByInterval(pnoScanIntervalMode.fixedScanCount, pnoScanIntervalMode.fixedCurrentTime,
1527                     pnoScanIntervalMode.scanIntervalMode.interval, pnoScanIntervalMode.scanIntervalMode.count)) {
1528                     WIFI_LOGW("pnoScan is not allowed for interval mode");
1529                     return WIFI_OPT_FAILED;
1530                 }
1531             }
1532         }
1533     }
1534 #endif
1535 
1536     if (!AllowScanByDisableScanCtrl()) {
1537         WIFI_LOGW("pnoScan not allow by disable scan control.");
1538         return WIFI_OPT_FAILED;
1539     }
1540 
1541     WIFI_LOGI("pno scan is allowed");
1542     return WIFI_OPT_SUCCESS;
1543 }
1544 
AllowScanByType(ScanType scanType)1545 ErrCode ScanService::AllowScanByType(ScanType scanType)
1546 {
1547     ErrCode allScanResult = WIFI_OPT_SUCCESS;
1548     switch (scanType) {
1549         case ScanType::SCAN_TYPE_EXTERN:
1550             allScanResult = AllowExternScan();
1551             break;
1552         case ScanType::SCAN_TYPE_SYSTEMTIMER:
1553             allScanResult = AllowSystemTimerScan();
1554             break;
1555         case ScanType::SCAN_TYPE_PNO:
1556             allScanResult = AllowPnoScan();
1557             break;
1558         default:
1559             LOGE("scanType error.\n");
1560             break;
1561     }
1562 
1563     WIFI_LOGI("AllowScanByType, scanType:%{public}d, allScanResult:%{public}d",
1564         scanType, static_cast<int>(allScanResult));
1565     return allScanResult;
1566 }
1567 
SetScanTrustMode()1568 void ScanService::SetScanTrustMode()
1569 {
1570     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1571     scanTrustMode = true;
1572 }
1573 
ResetToNonTrustMode()1574 void ScanService::ResetToNonTrustMode()
1575 {
1576     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1577     scanTrustMode = false;
1578 }
1579 
IsScanTrustMode() const1580 bool ScanService::IsScanTrustMode() const
1581 {
1582     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1583     return scanTrustMode;
1584 }
1585 
AddScanTrustSceneId(int sceneId)1586 void ScanService::AddScanTrustSceneId(int sceneId)
1587 {
1588     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1589     scanTrustSceneIds.emplace(sceneId);
1590 }
1591 
ClearScanTrustSceneIds()1592 void ScanService::ClearScanTrustSceneIds()
1593 {
1594     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1595     scanTrustSceneIds.clear();
1596 }
1597 
IsInScanTrust(int sceneId) const1598 bool ScanService::IsInScanTrust(int sceneId) const
1599 {
1600     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1601     if (scanTrustSceneIds.find(sceneId) != scanTrustSceneIds.end()) {
1602         return true;
1603     }
1604 
1605     return false;
1606 }
1607 
IsMovingFreezeState(ScanMode appRunMode) const1608 bool ScanService::IsMovingFreezeState(ScanMode appRunMode) const
1609 {
1610     int freezeState = WifiConfigCenter::GetInstance().GetFreezeModeState();
1611     int noChargerPlugModeState = WifiConfigCenter::GetInstance().GetNoChargerPlugModeState();
1612     if (appRunMode == ScanMode::APP_BACKGROUND_SCAN || appRunMode == ScanMode::SYS_BACKGROUND_SCAN) {
1613         return freezeState == MODE_STATE_OPEN && noChargerPlugModeState == MODE_STATE_OPEN;
1614     } else if (appRunMode == ScanMode::SYSTEM_TIMER_SCAN || appRunMode == ScanMode::PNO_SCAN) {
1615         return freezeState == MODE_STATE_OPEN;
1616     } else {
1617         return false;
1618     }
1619 }
1620 
IsMovingFreezeScaned() const1621 bool ScanService::IsMovingFreezeScaned() const
1622 {
1623     return WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetMovingFreezeScaned();
1624 }
1625 
ApplyTrustListPolicy(ScanType scanType)1626 ErrCode ScanService::ApplyTrustListPolicy(ScanType scanType)
1627 {
1628     LOGI("Enter ApplyTrustListPolicy.");
1629     ErrCode policyResult = WIFI_OPT_SUCCESS;
1630 
1631     SetScanTrustMode();
1632     policyResult = AllowScanByType(scanType);
1633     if (policyResult != WIFI_OPT_SUCCESS) {
1634         WIFI_LOGW("AllowScanByType failed.");
1635     }
1636     ResetToNonTrustMode();
1637     WIFI_LOGI("apply trust list policy, ErrCode=%{public}d", static_cast<int>(policyResult));
1638 
1639     return policyResult;
1640 }
1641 
ApplyScanPolices(ScanType type)1642 ErrCode ScanService::ApplyScanPolices(ScanType type)
1643 {
1644     LOGD("Enter ApplyScanPolices, type: %{public}d", type);
1645     /* Obtains app parameters and scenario status parameters. */
1646     auto appPackageName = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetAppPackageName();
1647     auto trustListPolicies = WifiSettings::GetInstance().ReloadTrustListPolicies();
1648     auto movingFreezePolicy = WifiSettings::GetInstance().ReloadMovingFreezePolicy();
1649     ErrCode rlt = WIFI_OPT_SUCCESS;
1650     if (appPackageName.empty()) {
1651         rlt = AllowScanByType(type);
1652         WIFI_LOGD("appPackageName empty, apply scan polices rlt: %{public}d.", static_cast<int>(rlt));
1653         if (scanResultBackup != -1 && rlt == WIFI_OPT_MOVING_FREEZE_CTRL) {
1654             ReportScanFinishEvent(scanResultBackup);
1655         }
1656         return rlt;
1657     }
1658 
1659     /* Generates an scene id list based on appPackageName. */
1660     ClearScanTrustSceneIds();
1661     for (auto &policy : trustListPolicies) {
1662         if (IsPackageInTrustList(policy.trustList, policy.sceneId, appPackageName)) {
1663             AddScanTrustSceneId(policy.sceneId);
1664         }
1665     }
1666     const int movingFreezeSceneId = -1;
1667     if (IsPackageInTrustList(movingFreezePolicy.trustList, movingFreezeSceneId, appPackageName)) {
1668         AddScanTrustSceneId(movingFreezeSceneId);
1669     }
1670 
1671     rlt = ApplyTrustListPolicy(type);
1672     if (rlt != WIFI_OPT_SUCCESS) {
1673         if (scanResultBackup != -1 && rlt == WIFI_OPT_MOVING_FREEZE_CTRL) {
1674             WIFI_LOGE("trust list policy, but moving freeze ctrl failed.");
1675             ReportScanFinishEvent(scanResultBackup);
1676         }
1677         return rlt;
1678     }
1679     WIFI_LOGD("apply scan policies result: scan control ok.");
1680     return WIFI_OPT_SUCCESS;
1681 }
1682 
GetStaScene()1683 int ScanService::GetStaScene()
1684 {
1685     WIFI_LOGD("Enter GetStaScene.\n");
1686 
1687     switch (staStatus) {
1688         case static_cast<int>(OperateResState::CONNECT_AP_CONNECTED):
1689             return SCAN_SCENE_CONNECTED;
1690 
1691         case static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED):
1692             return SCAN_SCENE_DISCONNCTED;
1693 
1694         case static_cast<int>(OperateResState::CONNECT_CONNECTING):
1695             return SCAN_SCENE_CONNECTING;
1696 
1697         case static_cast<int>(OperateResState::CONNECT_OBTAINING_IP):
1698             return SCAN_SCENE_OBTAINING_IP;
1699 
1700         case static_cast<int>(OperateResState::CONNECT_ASSOCIATING):
1701             return SCAN_SCENE_ASSOCIATING;
1702 
1703         case static_cast<int>(OperateResState::CONNECT_ASSOCIATED):
1704             return SCAN_SCENE_ASSOCIATED;
1705 
1706         default:
1707             return SCAN_SCENE_MAX;
1708     }
1709 }
1710 
IsExternScanning() const1711 bool ScanService::IsExternScanning() const
1712 {
1713     WIFI_LOGI("Enter IsExternScanning.\n");
1714 
1715     std::unique_lock<std::mutex> lock(scanConfigMapMutex);
1716     for (auto iter = scanConfigMap.begin(); iter != scanConfigMap.end(); ++iter) {
1717         if (iter->second.scanType != ScanType::SCAN_TYPE_SYSTEMTIMER) {
1718             return true;
1719         }
1720     }
1721     return false;
1722 }
1723 
IsScanningWithParam()1724 bool ScanService::IsScanningWithParam()
1725 {
1726     WIFI_LOGI("Enter IsScanningWithParam.\n");
1727 
1728     std::unique_lock<std::mutex> lock(scanConfigMapMutex);
1729     for (auto iter = scanConfigMap.begin(); iter != scanConfigMap.end(); ++iter) {
1730         if (iter->second.scanningWithParamFlag) {
1731             return true;
1732         }
1733     }
1734     return false;
1735 }
1736 
GetAllowBandFreqsControlInfo(ScanBandType & scanBand,std::vector<int> & freqs)1737 void ScanService::GetAllowBandFreqsControlInfo(ScanBandType &scanBand, std::vector<int> &freqs)
1738 {
1739     WIFI_LOGI("Enter GetAllowBandFreqsControlInfo.\n");
1740 
1741     int staScene = GetStaScene();
1742 
1743     bool allow24Ghz = true;
1744     bool allow5Ghz = true;
1745     if (!AllowScanDuringStaScene(staScene, ScanMode::BAND_24GHZ_SCAN)) {
1746         allow24Ghz = false;
1747     }
1748     if (!AllowScanDuringStaScene(staScene, ScanMode::BAND_5GHZ_SCAN)) {
1749         allow5Ghz = false;
1750     }
1751     if (!AllowScanDuringCustomScene(ScanMode::BAND_24GHZ_SCAN)) {
1752         allow24Ghz = false;
1753     }
1754     if (!AllowScanDuringCustomScene(ScanMode::BAND_5GHZ_SCAN)) {
1755         allow5Ghz = false;
1756     }
1757 
1758     {
1759         std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1760         for (auto iter = scanControlInfo.scanForbidList.begin(); iter != scanControlInfo.scanForbidList.end(); ++iter) {
1761             if (iter->scanScene == SCAN_SCENE_ALL) {
1762                 if (iter->scanMode == ScanMode::BAND_24GHZ_SCAN) {
1763                     allow24Ghz = false;
1764                 }
1765                 if (iter->scanMode == ScanMode::BAND_5GHZ_SCAN) {
1766                     allow5Ghz = false;
1767                 }
1768             }
1769         }
1770     }
1771 
1772     if ((!allow24Ghz) && (!allow5Ghz)) {
1773         WIFI_LOGE("Both 2.4G and 5G are not allowed");
1774         scanBand = SCAN_BAND_UNSPECIFIED;
1775         freqs.clear();
1776         return;
1777     }
1778 
1779     if (!allow24Ghz) {
1780         scanBand = ConvertBandNotAllow24G(scanBand);
1781         Delete24GhzFreqs(freqs);
1782     }
1783 
1784     if (!allow5Ghz) {
1785         scanBand = ConvertBandNotAllow5G(scanBand);
1786         Delete5GhzFreqs(freqs);
1787     }
1788 
1789     return;
1790 }
1791 
ConvertBandNotAllow24G(ScanBandType scanBand)1792 ScanBandType ScanService::ConvertBandNotAllow24G(ScanBandType scanBand)
1793 {
1794     WIFI_LOGI("Enter ConvertBandNotAllow24G.\n");
1795 
1796     switch (scanBand) {
1797         case SCAN_BAND_24_GHZ:
1798             return SCAN_BAND_UNSPECIFIED;
1799 
1800         case SCAN_BAND_5_GHZ:
1801         case SCAN_BAND_5_GHZ_DFS_ONLY:
1802         case SCAN_BAND_5_GHZ_WITH_DFS:
1803             return scanBand;
1804 
1805         case SCAN_BAND_BOTH:
1806             return SCAN_BAND_5_GHZ;
1807 
1808         case SCAN_BAND_BOTH_WITH_DFS:
1809             return SCAN_BAND_5_GHZ_WITH_DFS;
1810 
1811         default:
1812             return SCAN_BAND_UNSPECIFIED;
1813     }
1814 }
1815 
ConvertBandNotAllow5G(ScanBandType scanBand)1816 ScanBandType ScanService::ConvertBandNotAllow5G(ScanBandType scanBand)
1817 {
1818     WIFI_LOGI("Enter ConvertBandNotAllow5G.\n");
1819 
1820     switch (scanBand) {
1821         case SCAN_BAND_24_GHZ:
1822         case SCAN_BAND_BOTH:
1823         case SCAN_BAND_BOTH_WITH_DFS:
1824             return SCAN_BAND_24_GHZ;
1825 
1826         case SCAN_BAND_5_GHZ:
1827         case SCAN_BAND_5_GHZ_DFS_ONLY:
1828         case SCAN_BAND_5_GHZ_WITH_DFS:
1829         default:
1830             return SCAN_BAND_UNSPECIFIED;
1831     }
1832 }
1833 
Delete24GhzFreqs(std::vector<int> & freqs)1834 void ScanService::Delete24GhzFreqs(std::vector<int> &freqs)
1835 {
1836     WIFI_LOGI("Enter Delete24GhzFreqs.\n");
1837 
1838     auto iter = freqs.begin();
1839     while (iter != freqs.end()) {
1840         if (*iter < FREQS_24G_MAX_VALUE) {
1841             iter = freqs.erase(iter);
1842         } else {
1843             ++iter;
1844         }
1845     }
1846 
1847     return;
1848 }
1849 
Delete5GhzFreqs(std::vector<int> & freqs)1850 void ScanService::Delete5GhzFreqs(std::vector<int> &freqs)
1851 {
1852     WIFI_LOGI("Enter Delete24GhzFreqs.\n");
1853 
1854     auto iter = freqs.begin();
1855     while (iter != freqs.end()) {
1856         if (*iter > FREQS_5G_MIN_VALUE) {
1857             iter = freqs.erase(iter);
1858         } else {
1859             ++iter;
1860         }
1861     }
1862 
1863     return;
1864 }
1865 
GetSavedNetworkSsidList(std::vector<std::string> & savedNetworkSsid)1866 bool ScanService::GetSavedNetworkSsidList(std::vector<std::string> &savedNetworkSsid)
1867 {
1868     WIFI_LOGI("Enter GetSavedNetworkSsidList.\n");
1869 
1870     std::vector<WifiDeviceConfig> deviceConfigs;
1871     if (WifiSettings::GetInstance().GetDeviceConfig(deviceConfigs) != 0) {
1872         WIFI_LOGE("WifiSettings::GetInstance().GetDeviceConfig failed");
1873         return false;
1874     }
1875     std::sort(deviceConfigs.begin(), deviceConfigs.end(), [](WifiDeviceConfig deviceA, WifiDeviceConfig deviceB) {
1876         return deviceA.lastConnectTime > deviceB.lastConnectTime;
1877     });
1878     for (auto iter = deviceConfigs.begin(); iter != deviceConfigs.end(); ++iter) {
1879         if ((iter->status == static_cast<int>(WifiDeviceConfigStatus::ENABLED)) && (!(iter->isPasspoint)) &&
1880             (!(iter->isEphemeral))) {
1881             savedNetworkSsid.push_back(iter->ssid);
1882         }
1883     }
1884     WIFI_LOGI("Saved network list size:%{public}d", (int)savedNetworkSsid.size());
1885     return true;
1886 }
1887 
GetHiddenNetworkSsidList(std::vector<std::string> & hiddenNetworkSsid)1888 bool ScanService::GetHiddenNetworkSsidList(std::vector<std::string> &hiddenNetworkSsid)
1889 {
1890     WIFI_LOGI("Enter GetHiddenNetworkSsidList.\n");
1891 
1892     std::vector<WifiDeviceConfig> deviceConfigs;
1893     if (WifiSettings::GetInstance().GetDeviceConfig(deviceConfigs) != 0) {
1894         WIFI_LOGE("WifiSettings::GetInstance().GetDeviceConfig failed");
1895         return false;
1896     }
1897     for (auto iter = deviceConfigs.begin(); iter != deviceConfigs.end();) {
1898         if (!iter->hiddenSSID) {
1899             iter = deviceConfigs.erase(iter);
1900         } else {
1901             ++iter;
1902         }
1903     }
1904     std::sort(deviceConfigs.begin(), deviceConfigs.end(), [](WifiDeviceConfig deviceA, WifiDeviceConfig deviceB) {
1905         time_t aTime = deviceA.lastHasInternetTime == -1 ? deviceA.lastConnectTime : deviceA.lastHasInternetTime;
1906         time_t bTime = deviceB.lastHasInternetTime == -1 ? deviceB.lastConnectTime : deviceB.lastHasInternetTime;
1907         return aTime > bTime;
1908     });
1909     for (auto iter = deviceConfigs.begin(); iter != deviceConfigs.end(); ++iter) {
1910         hiddenNetworkSsid.push_back(iter->ssid);
1911         // for gbk hiddenNetworkSsID
1912         std::string gbkSsid = WifiCodeConvertUtil::Utf8ToGbk(iter->ssid);
1913         if (gbkSsid != iter->ssid && !gbkSsid.empty()) {
1914             hiddenNetworkSsid.push_back(gbkSsid);
1915         }
1916     }
1917 
1918     WIFI_LOGI("Find %{public}d hidden NetworkSsid.\n", (int)hiddenNetworkSsid.size());
1919     return true;
1920 }
1921 
ClearScanControlValue()1922 void ScanService::ClearScanControlValue()
1923 {
1924     WIFI_LOGI("Enter ClearScanControlValue.\n");
1925 
1926     customCurrentTime = 0;
1927     appForbidList.clear();
1928     scanBlocklist.clear();
1929     fullAppForbidList.clear();
1930     customSceneTimeMap.clear();
1931 }
1932 
SetStaCurrentTime()1933 void ScanService::SetStaCurrentTime()
1934 {
1935     WIFI_LOGD("Enter SetStaCurrentTime.\n");
1936     time_t now = time(nullptr);
1937     WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetStaCurrentTime(now);
1938 
1939     int state = WifiConfigCenter::GetInstance().GetScreenState();
1940     if (state == MODE_STATE_CLOSE) {
1941         if (ApplyScanPolices(ScanType::SCAN_TYPE_PNO) != WIFI_OPT_SUCCESS) {
1942             EndPnoScan();
1943             pnoScanFailedNum = 0;
1944             pScanStateMachine->StopTimer(static_cast<int>(RESTART_PNO_SCAN_TIMER));
1945         }
1946     }
1947     return;
1948 }
1949 
AllowScanDuringScanning(ScanMode scanMode) const1950 bool ScanService::AllowScanDuringScanning(ScanMode scanMode) const
1951 {
1952     WIFI_LOGI("Enter AllowScanDuringScanning.\n");
1953 
1954     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1955     for (auto iter = scanControlInfo.scanForbidList.begin(); iter != scanControlInfo.scanForbidList.end(); ++iter) {
1956         if (iter->scanScene == SCAN_SCENE_SCANNING && iter->scanMode == scanMode) {
1957             WIFI_LOGW("scan not allow by scanning scene.");
1958             return false;
1959         }
1960     }
1961     return true;
1962 }
1963 
AllowScanDuringStaScene(int staScene,ScanMode scanMode)1964 bool ScanService::AllowScanDuringStaScene(int staScene, ScanMode scanMode)
1965 {
1966     WIFI_LOGI("Enter AllowScanDuringStaScene, staScene:%{public}d, scanMode:%{public}d",
1967         staScene, scanMode);
1968 
1969     time_t now = time(nullptr);
1970     if (now < 0) {
1971         WIFI_LOGW("time return invalid!\n.");
1972         return false;
1973     }
1974     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
1975     for (auto iter = scanControlInfo.scanForbidList.begin(); iter != scanControlInfo.scanForbidList.end(); ++iter) {
1976         /* forbid scan mode found in scan scene. */
1977         if (iter->scanScene == staScene && iter->scanMode == scanMode) {
1978             /* forbidCount=0 and forbidTime=0, directly forbid scan. */
1979             if ((iter->forbidTime == 0) && (iter->forbidCount == 0)) {
1980                 WIFI_LOGW("Scan is forbidden by staScene.");
1981                 return false;
1982             }
1983             /* Unconditional scan control for forbidCount times */
1984             int staSceneForbidCount = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetStaSceneForbidCount();
1985             if ((iter->forbidCount > 0) && (iter->forbidCount - staSceneForbidCount > 0)) {
1986                 WIFI_LOGW("Scan is forbidden in forbidCount.");
1987                 staSceneForbidCount++;
1988                 return false;
1989             }
1990             /* Scan interval less than forbidTime, forbid scan. */
1991             time_t staCurrentTime = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetStaCurrentTime();
1992             if ((iter->forbidTime > 0) && (now - staCurrentTime <= iter->forbidTime)) {
1993                 WIFI_LOGW("Scan is forbidden in forbidTime.");
1994                 return false;
1995             }
1996         }
1997     }
1998 
1999     return true;
2000 }
2001 
AllowScanDuringCustomScene(ScanMode scanMode)2002 bool ScanService::AllowScanDuringCustomScene(ScanMode scanMode)
2003 {
2004     WIFI_LOGD("Enter AllowScanDuringCustomScene.\n");
2005 
2006     bool isTrustListMode = IsScanTrustMode();
2007     for (auto customIter = customSceneTimeMap.begin(); customIter != customSceneTimeMap.end(); ++customIter) {
2008         if (isTrustListMode && IsInScanTrust(customIter->first)) {
2009             WIFI_LOGD("Trust list mode,sceneId(%{public}d) in the list, continue.", customIter->first);
2010             continue;
2011         }
2012 
2013         if (!AllowCustomSceneCheck(customIter, scanMode)) {
2014             return false;
2015         }
2016     }
2017     return true;
2018 }
2019 
AllowCustomSceneCheck(const std::map<int,time_t>::const_iterator & customIter,ScanMode scanMode)2020 bool ScanService::AllowCustomSceneCheck(const std::map<int, time_t>::const_iterator &customIter, ScanMode scanMode)
2021 {
2022     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
2023     for (auto iter = scanControlInfo.scanForbidList.begin(); iter != scanControlInfo.scanForbidList.end(); ++iter) {
2024         if (iter->scanScene == customIter->first && iter->scanMode == scanMode) {
2025             /* forbidCount=0 and forbidTime=0, directly forbid scan. */
2026             if ((iter->forbidTime == 0) && (iter->forbidCount == 0)) {
2027                 WIFI_LOGW("Scan is forbidden by staScene.");
2028                 return false;
2029             }
2030             /* Unconditional scan control for forbidCount times. */
2031             if (iter->forbidCount > 0 && iter->forbidCount - customSceneForbidCount > 0) {
2032                 customSceneForbidCount++;
2033                 WIFI_LOGW("Unconditional scan control for forbidCount times, customSceneForbidCount:%{public}d.",
2034                     customSceneForbidCount);
2035                 return false;
2036             }
2037             /* Scan interval less than forbidTime, forbid scan. */
2038             time_t now = time(nullptr);
2039             if (iter->forbidTime > 0 && iter->forbidTime > now - customIter->second) {
2040                 WIFI_LOGW("Scan interval less than forbidTime, forbid scan, forbidTime:%{public}d.",
2041                     iter->forbidTime);
2042                 return false;
2043             }
2044         }
2045     }
2046 
2047     return true;
2048 }
2049 
AllowExternScanByIntervalMode(int appId,int scanScene,ScanMode scanMode)2050 bool ScanService::AllowExternScanByIntervalMode(int appId, int scanScene, ScanMode scanMode)
2051 {
2052     WIFI_LOGI("Enter AllowExternScanByIntervalMode.\n");
2053 
2054     if (IsAppInFilterList(scan_frequency_trust_list)) {
2055         return true;
2056     }
2057     bool isTrustListMode = IsScanTrustMode();
2058     if (isTrustListMode && IsInScanTrust(scanScene)) {
2059         WIFI_LOGD("Trust list mode,sceneId(%{public}d) in the list, return true.", scanScene);
2060         return true;
2061     }
2062 
2063     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
2064     for (auto intervalListIter = scanControlInfo.scanIntervalList.begin();
2065          intervalListIter != scanControlInfo.scanIntervalList.end();
2066          ++intervalListIter) {
2067         /* Determine whether control is required in the current scene and scan mode. */
2068         if (intervalListIter->scanScene == scanScene && intervalListIter->scanMode == scanMode) {
2069             /* If a single application is distinguished. */
2070             if (intervalListIter->isSingle) {
2071                 if (!AllowSingleAppScanByInterval(appId, *intervalListIter)) {
2072                     return false;
2073                 }
2074             } else {
2075                 if (!AllowFullAppScanByInterval(appId, *intervalListIter)) {
2076                     return false;
2077                 }
2078             }
2079         }
2080     }
2081     return true;
2082 }
2083 
PnoScanByInterval(int & fixedScanCount,time_t & fixedScanTime,int interval,int count)2084 bool ScanService::PnoScanByInterval(int &fixedScanCount, time_t &fixedScanTime, int interval, int count)
2085 {
2086     WIFI_LOGI("Enter PnoScanByInterval.\n");
2087 
2088     time_t now = time(nullptr);
2089     /* First scan */
2090     if (fixedScanCount == 0) {
2091         fixedScanCount++;
2092         fixedScanTime = now;
2093         return true;
2094     }
2095     if (now - fixedScanTime >= interval) {
2096         fixedScanCount = 1;
2097         fixedScanTime = now;
2098         return true;
2099     }
2100     if (fixedScanCount > count) {
2101         return false;
2102     }
2103     fixedScanCount++;
2104     return true;
2105 }
2106 
2107 #ifdef SUPPORT_SCAN_CONTROL
SystemScanByInterval(int staScene,int & interval,int & count)2108 bool ScanService::SystemScanByInterval(int staScene, int &interval, int &count)
2109 {
2110     WIFI_LOGI("Enter SystemScanByInterval.\n");
2111     int state = WifiConfigCenter::GetInstance().GetScreenState();
2112     if (state == MODE_STATE_OPEN || state == MODE_STATE_DEFAULT) {
2113         if (staScene == SCAN_SCENE_CONNECTED) {
2114             SystemScanConnectedPolicy(interval);
2115         } else if (staScene == SCAN_SCENE_DISCONNCTED) {
2116             SystemScanDisconnectedPolicy(interval, count);
2117         }
2118     }
2119     return true;
2120 }
2121 #else
SystemScanByInterval(int & expScanCount,int & interval,int & count)2122 bool ScanService::SystemScanByInterval(int &expScanCount, int &interval, int &count)
2123 {
2124     WIFI_LOGI("Enter SystemScanByInterval.\n");
2125     /*
2126      * Exponential interval. The value of interval is the initial value.
2127      * After the value is multiplied by 2, the last fixed interval is used.
2128      */
2129     if (expScanCount > 0 && count > 1) {
2130         interval *= DOUBLE_SCAN_INTERVAL;
2131         count--;
2132     }
2133     expScanCount++;
2134     return true;
2135 }
2136 #endif
2137 
ExternScanByInterval(int appId,SingleAppForbid & singleAppForbid)2138 bool ScanService::ExternScanByInterval(int appId, SingleAppForbid &singleAppForbid)
2139 {
2140     WIFI_LOGI("Enter ExternScanByInterval.\n");
2141 
2142     switch (singleAppForbid.scanIntervalMode.intervalMode) {
2143         case IntervalMode::INTERVAL_FIXED:
2144             return AllowScanByIntervalFixed(singleAppForbid.fixedScanCount, singleAppForbid.fixedCurrentTime,
2145                 singleAppForbid.scanIntervalMode.interval, singleAppForbid.scanIntervalMode.count);
2146 
2147         case IntervalMode::INTERVAL_EXP:
2148             return AllowScanByIntervalExp(singleAppForbid.expScanCount, singleAppForbid.scanIntervalMode.interval,
2149                 singleAppForbid.scanIntervalMode.count);
2150 
2151         case IntervalMode::INTERVAL_CONTINUE:
2152             return AllowScanByIntervalContinue(singleAppForbid.continueScanTime, singleAppForbid.lessThanIntervalCount,
2153                 singleAppForbid.scanIntervalMode.interval, singleAppForbid.scanIntervalMode.count);
2154 
2155         case IntervalMode::INTERVAL_BLOCKLIST:
2156             WIFI_LOGI("INTERVAL_BLOCKLIST IntervalMode.\n");
2157             return AllowScanByIntervalBlocklist(appId, singleAppForbid.blockListScanTime,
2158                 singleAppForbid.lessThanIntervalCount, singleAppForbid.scanIntervalMode.interval,
2159                 singleAppForbid.scanIntervalMode.count);
2160 
2161         default:
2162             return true;
2163     }
2164 }
2165 
AllowSingleAppScanByInterval(int appId,ScanIntervalMode scanIntervalMode)2166 bool ScanService::AllowSingleAppScanByInterval(int appId, ScanIntervalMode scanIntervalMode)
2167 {
2168     WIFI_LOGI("Enter AllowSingleAppScanByInterval.\n");
2169     bool appIdExisted = false;
2170     for (auto forbidListIter = appForbidList.begin(); forbidListIter != appForbidList.end(); ++forbidListIter) {
2171         if (forbidListIter->appID == appId &&
2172             forbidListIter->scanIntervalMode.scanScene == scanIntervalMode.scanScene &&
2173             forbidListIter->scanIntervalMode.scanMode == scanIntervalMode.scanMode) {
2174             appIdExisted = true;
2175         }
2176     }
2177     /* If the appId is the first scan request, add it to appForbidList. */
2178     if (!appIdExisted) {
2179         SingleAppForbid singleAppForbid;
2180         singleAppForbid.appID = appId;
2181         singleAppForbid.scanIntervalMode.scanScene = scanIntervalMode.scanScene;
2182         singleAppForbid.scanIntervalMode.scanMode = scanIntervalMode.scanMode;
2183         singleAppForbid.scanIntervalMode.interval = scanIntervalMode.interval;
2184         singleAppForbid.scanIntervalMode.intervalMode = scanIntervalMode.intervalMode;
2185         singleAppForbid.scanIntervalMode.count = scanIntervalMode.count;
2186         appForbidList.push_back(singleAppForbid);
2187     }
2188     for (auto iter = appForbidList.begin(); iter != appForbidList.end(); ++iter) {
2189         if (iter->appID == appId && iter->scanIntervalMode.scanScene == scanIntervalMode.scanScene &&
2190             iter->scanIntervalMode.scanMode == scanIntervalMode.scanMode) {
2191             if (!ExternScanByInterval(appId, *iter)) {
2192                 WIFI_LOGI("AllowSingleAppScanByInterval:false.");
2193                 return false;
2194             }
2195         }
2196     }
2197     WIFI_LOGI("AllowSingleAppScanByInterval:true.");
2198     return true;
2199 }
2200 
AllowFullAppScanByInterval(int appId,ScanIntervalMode scanIntervalMode)2201 bool ScanService::AllowFullAppScanByInterval(int appId, ScanIntervalMode scanIntervalMode)
2202 {
2203     WIFI_LOGI("Enter AllowFullAppScanByInterval.\n");
2204 
2205     bool fullAppExisted = false;
2206     for (auto fullAppForbidIter = fullAppForbidList.begin(); fullAppForbidIter != fullAppForbidList.end();
2207         ++fullAppForbidIter) {
2208         if (fullAppForbidIter->scanIntervalMode.scanScene == scanIntervalMode.scanScene &&
2209             fullAppForbidIter->scanIntervalMode.scanMode == scanIntervalMode.scanMode) {
2210             fullAppExisted = true;
2211         }
2212     }
2213     if (!fullAppExisted) {
2214         SingleAppForbid singleAppForbid;
2215         singleAppForbid.scanIntervalMode.scanScene = scanIntervalMode.scanScene;
2216         singleAppForbid.scanIntervalMode.scanMode = scanIntervalMode.scanMode;
2217         singleAppForbid.scanIntervalMode.interval = scanIntervalMode.interval;
2218         singleAppForbid.scanIntervalMode.intervalMode = scanIntervalMode.intervalMode;
2219         singleAppForbid.scanIntervalMode.count = scanIntervalMode.count;
2220         fullAppForbidList.push_back(singleAppForbid);
2221     }
2222     for (auto iter = fullAppForbidList.begin(); iter != fullAppForbidList.end(); ++iter) {
2223         if (iter->scanIntervalMode.scanScene == scanIntervalMode.scanScene &&
2224             iter->scanIntervalMode.scanMode == scanIntervalMode.scanMode) {
2225             if (!ExternScanByInterval(appId, *iter)) {
2226                 WIFI_LOGI("AllowFullAppScanByInterval:false.");
2227                 return false;
2228             }
2229         }
2230     }
2231     WIFI_LOGI("AllowFullAppScanByInterval:true.");
2232     return true;
2233 }
2234 
AllowScanByIntervalFixed(int & fixedScanCount,time_t & fixedScanTime,int & interval,int & count)2235 bool ScanService::AllowScanByIntervalFixed(int &fixedScanCount, time_t &fixedScanTime, int &interval, int &count)
2236 {
2237     WIFI_LOGI("Enter AllowScanByIntervalFixed.\n");
2238 
2239     time_t now = time(nullptr);
2240     /* First scan */
2241     if (fixedScanCount == 0) {
2242         fixedScanCount++;
2243         fixedScanTime = now;
2244         return true;
2245     }
2246     /* The scanning interval is greater than interval, and counting is restarted. */
2247     if (now - fixedScanTime >= interval) {
2248         fixedScanCount = 1;
2249         fixedScanTime = now;
2250         return true;
2251     }
2252     /* *
2253      * Scan is forbidden because the scanning interval is less than interval
2254      * and the number of scan times exceeds count.
2255      */
2256     if (fixedScanCount >= count) {
2257         return false;
2258     }
2259     fixedScanCount++;
2260     return true;
2261 }
2262 
AllowScanByIntervalExp(int & expScanCount,int & interval,int & count)2263 bool ScanService::AllowScanByIntervalExp(int &expScanCount, int &interval, int &count)
2264 {
2265     WIFI_LOGI("Enter AllowScanByIntervalExp.\n");
2266 
2267     /*
2268      * Exponential interval. The value of interval is the initial value.
2269      * After the value is multiplied by 2, the last fixed interval is used.
2270      */
2271     if (expScanCount > 0 && count > 1) {
2272         interval *= DOUBLE_SCAN_INTERVAL;
2273         count--;
2274     }
2275     expScanCount++;
2276     return true;
2277 }
2278 
AllowScanByIntervalContinue(time_t & continueScanTime,int & lessThanIntervalCount,int & interval,int & count)2279 bool ScanService::AllowScanByIntervalContinue(time_t &continueScanTime, int &lessThanIntervalCount, int &interval,
2280     int &count)
2281 {
2282     WIFI_LOGI("Enter AllowScanByIntervalContinue.\n");
2283 
2284     WIFI_LOGD("lessThanIntervalCount:%{public}d, interval:%{public}d, count:%{public}d", lessThanIntervalCount,
2285         interval, count);
2286     time_t now = time(nullptr);
2287     /* First scan */
2288     if (continueScanTime == 0) {
2289         continueScanTime = now;
2290         return true;
2291     }
2292     /* If count is less than interval, the subsequent interval must be greater than interval. */
2293     if (now - continueScanTime < interval) {
2294         lessThanIntervalCount++;
2295         if (lessThanIntervalCount < count) {
2296             continueScanTime = now;
2297             return true;
2298         }
2299         /* If the scanning interval is not exceeded continuously, the counter is cleared. */
2300         lessThanIntervalCount = 0;
2301         return false;
2302     }
2303     /* If the scanning interval is not exceeded continuously, the counter is cleared. */
2304     lessThanIntervalCount = 0;
2305     continueScanTime = now;
2306     return true;
2307 }
2308 
AllowScanByIntervalBlocklist(int appId,time_t & blockListScanTime,int & lessThanIntervalCount,int & interval,int & count)2309 bool ScanService::AllowScanByIntervalBlocklist(
2310     int appId, time_t &blockListScanTime, int &lessThanIntervalCount, int &interval, int &count)
2311 {
2312     WIFI_LOGI("Enter AllowScanByIntervalBlocklist.\n");
2313 
2314     time_t now = time(nullptr);
2315     if (now - blockListScanTime >= interval) {
2316         for (auto iter = scanBlocklist.begin(); iter != scanBlocklist.end();) {
2317             if (*iter == appId) {
2318                 iter = scanBlocklist.erase(iter);
2319             } else {
2320                 ++iter;
2321             }
2322         }
2323         blockListScanTime = now;
2324         return true;
2325     }
2326     /* If the app ID is in the blocklist, extern scan is forbidden. */
2327     if (std::find(scanBlocklist.begin(), scanBlocklist.end(), appId) != scanBlocklist.end()) {
2328         WIFI_LOGW("extern scan not allowed by blocklist");
2329         return false;
2330     }
2331     /* First scan */
2332     if (blockListScanTime == 0) {
2333         blockListScanTime = now;
2334         WIFI_LOGW("blockListScanTime, first scan.");
2335         return true;
2336     }
2337     /**
2338      * If the number of consecutive count times is less than the value of interval,
2339      * the user is added to the blocklist and cannot be scanned.
2340      */
2341     if (now - blockListScanTime < interval) {
2342         lessThanIntervalCount++;
2343         if (lessThanIntervalCount < count) {
2344             blockListScanTime = now;
2345             WIFI_LOGD("blockListScanTime, lessThanIntervalCount(%{public}d),return true.", lessThanIntervalCount);
2346             return true;
2347         }
2348         /**
2349          * If the accumulated scanning interval is less than interval and the number of times
2350          * is greater than count, the user is blocklisted forbidding scanning.
2351          */
2352         scanBlocklist.push_back(appId);
2353         WIFI_LOGI("scanBlocklist.push_back(appId), return false.");
2354         return false;
2355     }
2356     blockListScanTime = now;
2357     return true;
2358 }
2359 
AllowScanByDisableScanCtrl()2360 bool ScanService::AllowScanByDisableScanCtrl()
2361 {
2362     std::unique_lock<std::mutex> lock(scanControlInfoMutex);
2363     return !disableScanFlag;
2364 }
2365 
AllowScanByMovingFreeze(ScanMode appRunMode)2366 bool ScanService::AllowScanByMovingFreeze(ScanMode appRunMode)
2367 {
2368     LOGI("Enter AllowScanByMovingFreeze.\n");
2369 
2370     /* moving freeze trust mode. */
2371     bool isTrustListMode = IsScanTrustMode();
2372     if (isTrustListMode && IsInScanTrust(-1)) {
2373         WIFI_LOGD("Trust list mode,sceneId(MovingFreeze) in the list, return true.");
2374         return true;
2375     }
2376 
2377     if (!IsMovingFreezeState(appRunMode)) {
2378         WIFI_LOGD("It's not in the movingfreeze mode, return true.");
2379         return true;
2380     }
2381 
2382     if (!IsMovingFreezeScaned()) {
2383         WifiConfigCenter::GetInstance().GetWifiScanConfig()->SetMovingFreezeScaned(true);
2384         WIFI_LOGD("In movingfreeze mode, return true for the first scan.");
2385         return true;
2386     } else {
2387         WIFI_LOGW("In movingfreeze mode, return false for the already scanned.");
2388         return false;
2389     }
2390 
2391     return true;
2392 }
2393 
AllowScanByHid2dState()2394 bool ScanService::AllowScanByHid2dState()
2395 {
2396     LOGD("Enter AllowScanByHid2dState.\n");
2397     Hid2dUpperScene softbusScene;
2398     Hid2dUpperScene castScene;
2399     Hid2dUpperScene shareScene;
2400     Hid2dUpperScene mouseCrossScene;
2401     Hid2dUpperScene miracastScene;
2402     WifiP2pLinkedInfo linkedInfo;
2403     WifiConfigCenter::GetInstance().GetHid2dUpperScene(SOFT_BUS_SERVICE_UID, softbusScene);
2404     WifiConfigCenter::GetInstance().GetHid2dUpperScene(CAST_ENGINE_SERVICE_UID, castScene);
2405     WifiConfigCenter::GetInstance().GetHid2dUpperScene(MIRACAST_SERVICE_UID, miracastScene);
2406     WifiConfigCenter::GetInstance().GetHid2dUpperScene(SHARE_SERVICE_UID, shareScene);
2407     WifiConfigCenter::GetInstance().GetHid2dUpperScene(MOUSE_CROSS_SERVICE_UID, mouseCrossScene);
2408     WifiConfigCenter::GetInstance().GetP2pInfo(linkedInfo);
2409 
2410     if (IsAppInFilterList(scan_hid2d_list)) {
2411         WIFI_LOGI("ScanService::AllowScanByHid2dState, no need to control this scan");
2412         return true;
2413     }
2414     if (linkedInfo.GetConnectState() == P2pConnectedState::P2P_DISCONNECTED
2415         && WifiConfigCenter::GetInstance().GetP2pEnhanceState() == 0) {
2416         WIFI_LOGW("allow scan, and clear scene.");
2417         WifiConfigCenter::GetInstance().ClearLocalHid2dInfo();
2418         return true;
2419     }
2420     // scene bit 0-2 is valid, 0x01: video, 0x02: audio, 0x04: file,
2421     // scene & 0x07 > 0 means one of them takes effect.
2422     if ((softbusScene.scene & 0x07) > 0) {
2423         WIFI_LOGW("Scan is not allowed in softbus hid2d.");
2424         return false;
2425     } else if ((castScene.scene & 0x07) > 0) {
2426         WIFI_LOGW("Scan is not allowed in csat hid2d.");
2427         return false;
2428     } else if ((miracastScene.scene & 0x07) > 0) {
2429         WIFI_LOGW("Scan is not allowed in miracast hid2d.");
2430         return false;
2431     } else if ((shareScene.scene & 0x07) > 0) {
2432         WIFI_LOGW("Scan is not allowed in share hid2d.");
2433         return false;
2434     } else if ((mouseCrossScene.scene & 0x07) > 0) {
2435         WIFI_LOGW("Scan is not allowed in mouse cross hid2d.");
2436         return false;
2437     } else {
2438         WIFI_LOGD("allow hid2d scan");
2439     }
2440     return true;
2441 }
2442 
IsPackageInTrustList(const std::string & trustList,int sceneId,const std::string & appPackageName) const2443 bool ScanService::IsPackageInTrustList(const std::string &trustList, int sceneId,
2444     const std::string &appPackageName) const
2445 {
2446     std::vector<std::string> trustPackages;
2447     SplitString(trustList, "|", trustPackages);
2448 
2449     bool bFind = false;
2450     for (const auto &package : trustPackages) {
2451         if (package == appPackageName) {
2452             WIFI_LOGD("IsPackageInTrustList=true");
2453             bFind = true;
2454             break;
2455         }
2456     }
2457 
2458     if (!bFind) {
2459         WIFI_LOGD("sceneId=%{public}d, appName=%{public}s trustList=%{public}s, not in the lists.", sceneId,
2460             appPackageName.c_str(), trustList.c_str());
2461     }
2462 
2463     return bFind;
2464 }
2465 
SetNetworkInterfaceUpDown(bool upDown)2466 ErrCode ScanService::SetNetworkInterfaceUpDown(bool upDown)
2467 {
2468     WIFI_LOGI("Enter ScanService::SetNetworkInterfaceUpDown.\n");
2469     int res = WifiStaHalInterface::GetInstance().SetNetworkInterfaceUpDown(
2470         WifiConfigCenter::GetInstance().GetStaIfaceName(), upDown);
2471     if (res != static_cast<int>(WIFI_HAL_OPT_OK)) {
2472         return WIFI_OPT_FAILED;
2473     }
2474     return WIFI_OPT_SUCCESS;
2475 }
2476 
IsAppInFilterList(const std::vector<std::string> & packageFilter) const2477 bool ScanService::IsAppInFilterList(const std::vector<std::string> &packageFilter) const
2478 {
2479     std::string packageName = WifiConfigCenter::GetInstance().GetWifiScanConfig()->GetAppPackageName();
2480     if (std::find(packageFilter.begin(), packageFilter.end(), packageName) != packageFilter.end()) {
2481         return true;
2482     }
2483     return false;
2484 }
2485 
SystemScanConnectedPolicy(int & interval)2486 void ScanService::SystemScanConnectedPolicy(int &interval)
2487 {
2488     WIFI_LOGI("Enter SystemScanConnectedPolicy");
2489     WifiLinkedInfo linkedInfo;
2490     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo, m_instId);
2491     if (linkedInfo.detailedState == DetailedState::WORKING) {
2492         interval = SYSTEM_SCAN_INTERVAL_ONE_HOUR;
2493     } else {
2494         interval *= DOUBLE_SCAN_INTERVAL;
2495         if (IsMovingFreezeState(ScanMode::SYSTEM_TIMER_SCAN)) {
2496             if (interval > SYSTEM_SCAN_INTERVAL_FIVE_MINUTE) {
2497                 interval = SYSTEM_SCAN_INTERVAL_FIVE_MINUTE;
2498             }
2499         } else {
2500             if (interval > SYSTEM_SCAN_INTERVAL_160_SECOND) {
2501                 interval = SYSTEM_SCAN_INTERVAL_160_SECOND;
2502             }
2503         }
2504     }
2505 }
2506 
SystemScanDisconnectedPolicy(int & interval,int & count)2507 void ScanService::SystemScanDisconnectedPolicy(int &interval, int &count)
2508 {
2509     WIFI_LOGI("Enter SystemScanDisconnectedPolicy");
2510     int scanGenieState = WifiConfigCenter::GetInstance().GetScanGenieState();
2511     if (scanGenieState == MODE_STATE_OPEN) {
2512         if (count < SYSTEM_SCAN_COUNT_3_TIMES) {
2513             interval = SYSTEM_SCAN_INTERVAL_10_SECOND;
2514         } else if (count < SYSTEM_SCAN_COUNT_3_TIMES * DOUBLE_SCAN_INTERVAL) {
2515             interval = SYSTEM_SCAN_INTERVAL_30_SECOND;
2516         } else {
2517             if (IsMovingFreezeState(ScanMode::SYSTEM_TIMER_SCAN)) {
2518                 interval = SYSTEM_SCAN_INTERVAL_FIVE_MINUTE;
2519             } else {
2520                 interval = SYSTEM_SCAN_INTERVAL_60_SECOND;
2521             }
2522         }
2523         count++;
2524     } else {
2525         interval *= DOUBLE_SCAN_INTERVAL;
2526         if (IsMovingFreezeState(ScanMode::SYSTEM_TIMER_SCAN)) {
2527             if (interval > SYSTEM_SCAN_INTERVAL_FIVE_MINUTE) {
2528                 interval = SYSTEM_SCAN_INTERVAL_FIVE_MINUTE;
2529             }
2530         } else {
2531             if (interval > SYSTEM_SCAN_INTERVAL_160_SECOND) {
2532                 interval = SYSTEM_SCAN_INTERVAL_160_SECOND;
2533             }
2534         }
2535     }
2536 }
2537 
InitChipsetInfo()2538 void ScanService::InitChipsetInfo()
2539 {
2540     WIFI_LOGI("Enter InitChipsetInfo");
2541     if (isChipsetInfoObtained) {
2542         return;
2543     }
2544     if (WifiStaHalInterface::GetInstance().GetChipsetCategory(
2545         WifiConfigCenter::GetInstance().GetStaIfaceName(), chipsetCategory) != WIFI_HAL_OPT_OK
2546         || WifiStaHalInterface::GetInstance().GetChipsetWifiFeatrureCapability(
2547             WifiConfigCenter::GetInstance().GetStaIfaceName(), chipsetFeatrureCapability) != WIFI_HAL_OPT_OK) {
2548                 WIFI_LOGE("GetChipsetCategory or GetChipsetWifiFeatrureCapability failed.\n");
2549                 isChipsetInfoObtained = false;
2550     } else {
2551         isChipsetInfoObtained = true;
2552     }
2553 }
2554 
2555 #ifndef OHOS_ARCH_LITE
OnWifiCountryCodeChanged(const std::string & wifiCountryCode)2556 ErrCode ScanService::WifiCountryCodeChangeObserver::OnWifiCountryCodeChanged(const std::string &wifiCountryCode)
2557 {
2558     if (strcasecmp(m_lastWifiCountryCode.c_str(), wifiCountryCode.c_str()) == 0) {
2559         WIFI_LOGI("wifi country code is same, scan not update, code=%{public}s", wifiCountryCode.c_str());
2560         return WIFI_OPT_SUCCESS;
2561     }
2562     WIFI_LOGI("deal wifi country code changed, code=%{public}s", wifiCountryCode.c_str());
2563     InternalMessagePtr msg = m_stateMachineObj.CreateMessage();
2564     CHECK_NULL_AND_RETURN(msg, WIFI_OPT_FAILED);
2565     msg->SetMessageName(static_cast<int>(SCAN_UPDATE_COUNTRY_CODE));
2566     msg->AddStringMessageBody(wifiCountryCode);
2567     m_stateMachineObj.SendMessage(msg);
2568     m_lastWifiCountryCode = wifiCountryCode;
2569     return WIFI_OPT_SUCCESS;
2570 }
2571 
GetListenerModuleName()2572 std::string ScanService::WifiCountryCodeChangeObserver::GetListenerModuleName()
2573 {
2574     return m_listenerModuleName;
2575 }
2576 #endif
2577 
CalculateBitPerTone(int snrDb)2578 int CalculateBitPerTone(int snrDb)
2579 {
2580     int bitPerTone;
2581     if (snrDb <= SNR_BIT_PER_TONE_LUT_MAX) {
2582         int lutInIdx = MAX(snrDb, SNR_BIT_PER_TONE_LUT_MIN) - SNR_BIT_PER_TONE_LUT_MIN;
2583         lutInIdx = MIN(lutInIdx, sizeof(SNR_BIT_PER_TONE_LUT) / sizeof(int) - 1);
2584         bitPerTone = SNR_BIT_PER_TONE_LUT[lutInIdx];
2585     } else {
2586         bitPerTone = snrDb * SNR_BIT_PER_TONE_HIGH_SNR_SCALE;
2587     }
2588     return bitPerTone;
2589 }
2590 
CalculateAirTimeFraction(int channelUtilization,int channelWidthFactor)2591 int CalculateAirTimeFraction(int channelUtilization, int channelWidthFactor)
2592 {
2593     int airTimeFraction20MHZ = MAX_CHANNEL_UTILIZATION - channelUtilization;
2594     int airTimeFraction = airTimeFraction20MHZ;
2595 
2596     for (int i = 1; i <= channelWidthFactor; ++i) {
2597         airTimeFraction *= airTimeFraction;
2598         airTimeFraction /= MAX_CHANNEL_UTILIZATION;
2599     }
2600     WIFI_LOGD("airTime20: %{public}d airTime: %{public}d", airTimeFraction20MHZ, airTimeFraction);
2601     return airTimeFraction;
2602 }
2603 
WifiMaxThroughput(int wifiStandard,bool is11bMode,WifiChannelWidth channelWidth,int rssiDbm,int maxNumSpatialStream,int channelUtilization)2604 int WifiMaxThroughput(int wifiStandard, bool is11bMode, WifiChannelWidth channelWidth, int rssiDbm,
2605                       int maxNumSpatialStream, int channelUtilization)
2606 {
2607     int channelWidthFactor;
2608     int numTonePerSym;
2609     int symDurationNs;
2610     int maxBitsPerTone;
2611     if (maxNumSpatialStream < 1) {
2612         WIFI_LOGI("maxNumSpatialStream < 1 due to wrong implementation. Overridden to 1");
2613         maxNumSpatialStream = 1;
2614     }
2615     if (wifiStandard == WIFI_MODE_UNDEFINED) {
2616         return -1;
2617     } else if (wifiStandard == WIFI_802_11A ||
2618     wifiStandard == WIFI_802_11B ||
2619     wifiStandard == WIFI_802_11G) {
2620         numTonePerSym = TONE_PER_SYM_11ABG;
2621         channelWidthFactor = 0;
2622         maxNumSpatialStream = MAX_NUM_SPATIAL_STREAM_11ABG;
2623         maxBitsPerTone = MAX_BITS_PER_TONE_11ABG;
2624         symDurationNs = SYM_DURATION_11ABG_NS;
2625     } else if (wifiStandard == WIFI_802_11N) {
2626         if (channelWidth == WifiChannelWidth::WIDTH_20MHZ) {
2627             numTonePerSym = TONE_PER_SYM_11N_20MHZ;
2628             channelWidthFactor = 0;
2629         } else {
2630             numTonePerSym = TONE_PER_SYM_11N_40MHZ;
2631             channelWidthFactor = 1;
2632         }
2633         maxNumSpatialStream = MIN(maxNumSpatialStream, MAX_NUM_SPATIAL_STREAM_11N);
2634         maxBitsPerTone = MAX_BITS_PER_TONE_11N;
2635         symDurationNs = SYM_DURATION_11N_NS;
2636     } else if (wifiStandard == WIFI_802_11AC) {
2637         if (channelWidth == WifiChannelWidth::WIDTH_20MHZ) {
2638             numTonePerSym = TONE_PER_SYM_11AC_20MHZ;
2639             channelWidthFactor = 0;
2640         } else if (channelWidth == WifiChannelWidth::WIDTH_40MHZ) {
2641             numTonePerSym = TONE_PER_SYM_11AC_40MHZ;
2642             channelWidthFactor = 1;
2643         } else if (channelWidth == WifiChannelWidth::WIDTH_80MHZ) {
2644             numTonePerSym = TONE_PER_SYM_11AC_80MHZ;
2645             channelWidthFactor = 2;
2646         } else {
2647             numTonePerSym = TONE_PER_SYM_11AC_160MHZ;
2648             channelWidthFactor = 3;
2649         }
2650         maxNumSpatialStream = MIN(maxNumSpatialStream, MAX_NUM_SPATIAL_STREAM_11AC);
2651         maxBitsPerTone = MAX_BITS_PER_TONE_11AC;
2652         symDurationNs = SYM_DURATION_11AC_NS;
2653     } else {
2654         if (channelWidth == WifiChannelWidth::WIDTH_20MHZ) {
2655             numTonePerSym = TONE_PER_SYM_11AX_20MHZ;
2656             channelWidthFactor = 0;
2657         } else if (channelWidth == WifiChannelWidth::WIDTH_40MHZ) {
2658             numTonePerSym = TONE_PER_SYM_11AX_40MHZ;
2659             channelWidthFactor = 1;
2660         } else if (channelWidth == WifiChannelWidth::WIDTH_80MHZ) {
2661             numTonePerSym = TONE_PER_SYM_11AX_80MHZ;
2662             channelWidthFactor = 2;
2663         } else {
2664             numTonePerSym = TONE_PER_SYM_11AX_160MHZ;
2665             channelWidthFactor = 3;
2666         }
2667         maxNumSpatialStream = MIN(maxNumSpatialStream, MAX_NUM_SPATIAL_STREAM_11AX);
2668         maxBitsPerTone = MAX_BITS_PER_TONE_11AX;
2669         symDurationNs = SYM_DURATION_11AX_NS;
2670     }
2671     int noiseFloorDbBoost = TWO_DB * channelWidthFactor;
2672     int noiseFloorDbm = NOISE_FLOOR_20MHZ_DBM + noiseFloorDbBoost + SNR_MARGIN_DB;
2673     int snrDb = rssiDbm - noiseFloorDbm;
2674 
2675     int bitPerTone = CalculateBitPerTone(snrDb);
2676     bitPerTone = MIN(bitPerTone, maxBitsPerTone);
2677 
2678     long long bitPerToneTotal = static_cast<long long>(bitPerTone) * maxNumSpatialStream;
2679     long long numBitPerSym = bitPerToneTotal * numTonePerSym;
2680     long phyRateMbps = static_cast<int>(((numBitPerSym * MICRO_TO_NANO_RATIO) / (symDurationNs * BIT_PER_TONE_SCALE)));
2681     int airTimeFraction = CalculateAirTimeFraction(channelUtilization, channelWidthFactor);
2682     int throughputMbps = (phyRateMbps * airTimeFraction) / MAX_CHANNEL_UTILIZATION;
2683     if (is11bMode) {
2684         throughputMbps = MIN(throughputMbps, B_MODE_MAX_MBPS);
2685     }
2686     return throughputMbps;
2687 }
2688 }  // namespace Wifi
2689 }  // namespace OHOS