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 #ifndef OHOS_SCAN_STATE_MACHINE_H
17 #define OHOS_SCAN_STATE_MACHINE_H
18 
19 #include <algorithm>
20 #include <atomic>
21 #include <map>
22 #include <shared_mutex>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 #include "scan_common.h"
27 #include "state_machine.h"
28 #include "wifi_errcode.h"
29 #include "wifi_log.h"
30 #include "wifi_msg.h"
31 #include "wifi_native_struct.h"
32 
33 namespace OHOS {
34 namespace Wifi {
35 const int SCAN_TYPE_LOW_SPAN = 0;
36 const int SCAN_TYPE_LOW_POWER = 1;
37 const int SCAN_TYPE_HIGH_ACCURACY = 2;
38 const int SCAN_TYPE_INVALID = 0xFF;
39 const int MAX_WAIT_SCAN_RESULT_TIME = 5 * 1000;
40 const int SCAN_24GHZ_MAX_FREQUENCY = 2500;
41 const int SCAN_5GHZ_MIN_FREQUENCY = 5000;
42 const int SCAN_24GHZ_BAND = 1;
43 const int SCAN_5GHZ_BAND = 2;
44 const int MAX_RATES_24G = 24000000;
45 
46 class ScanStateMachine : public StateMachine {
47     FRIEND_GTEST(ScanStateMachine);
48 public:
49     explicit ScanStateMachine(int instId = 0);
50     ~ScanStateMachine();
51     /**
52     * @Description  Initialize the scanning state machine,construct the state tree,
53                     set the initialization state, and start the state machine.
54     *
55     * @return success: true, failed: false
56     */
57     bool InitScanStateMachine();
58     /**
59      * @Description  Registers the scan status change callback function for ScanService.
60      *
61      * @param handler - Function handle[in]
62      * @return success: true, failed: false
63      */
64     bool EnrollScanStatusListener(ScanStatusReportHandler handler);
65 
66     class InitState : public State {
67         FRIEND_GTEST(ScanStateMachine);
68     public:
69         /**
70          * @Description  Initial state of the scanning state machine
71          *
72          */
73         explicit InitState(ScanStateMachine *paraScanStateMachine);
74         ~InitState();
75         void GoInState();
76         void GoOutState();
77         bool ExecuteStateMsg(InternalMessagePtr msg);
78 
79     private:
80         ScanStateMachine *pScanStateMachine;
81         /**
82          * @Description  load hardware
83          *
84          */
85         void LoadDriver();
86         /**
87          * @Description  unload hardware
88          *
89          */
90         void UnLoadDriver();
91         void DisableScan();
92         void HandleUpdateCountryCode(InternalMessagePtr msg);
93     };
94 
95     class HardwareReady : public State {
96     public:
97         /**
98          * @Description  The hardware is successfully loaded. The scanning request can be processed.
99          *
100          */
101         explicit HardwareReady(ScanStateMachine *paraScanStateMachine);
102         ~HardwareReady();
103         void GoInState();
104         void GoOutState();
105         bool ExecuteStateMsg(InternalMessagePtr msg);
106 
107     private:
108         ScanStateMachine *pScanStateMachine;
109     };
110 
111     class CommonScan : public State {
112     public:
113         /**
114          * @Description  Normal Scan Status.
115          *
116          */
117         explicit CommonScan(ScanStateMachine *paraScanStateMachine);
118         ~CommonScan();
119         void GoInState();
120         void GoOutState();
121         bool ExecuteStateMsg(InternalMessagePtr msg);
122 
123     private:
124         ScanStateMachine *pScanStateMachine;
125     };
126 
127     class CommonScanUnworked : public State {
128     public:
129         /**
130          * @Description  Normal Scan Idle State.
131          *
132          */
133         explicit CommonScanUnworked(ScanStateMachine *paraScanStateMachine);
134         ~CommonScanUnworked();
135         void GoInState();
136         void GoOutState();
137         bool ExecuteStateMsg(InternalMessagePtr msg);
138 
139     private:
140         ScanStateMachine *pScanStateMachine;
141     };
142 
143     class CommonScanning : public State {
144     public:
145         /**
146          * @Description  Normal scan in progress.
147          *
148          */
149         explicit CommonScanning(ScanStateMachine *paraScanStateMachine);
150         ~CommonScanning();
151         void GoInState();
152         void GoOutState();
153         bool ExecuteStateMsg(InternalMessagePtr msg);
154 
155     private:
156         ScanStateMachine *pScanStateMachine;
157     };
158 
159     class PnoScan : public State {
160     public:
161         /**
162          * @Description  PNO scanning status
163          *
164          */
165         explicit PnoScan(ScanStateMachine *paraScanStateMachine);
166         ~PnoScan();
167         void GoInState();
168         void GoOutState();
169         bool ExecuteStateMsg(InternalMessagePtr msg);
170 
171     private:
172         ScanStateMachine *pScanStateMachine;
173     };
174 
175     class PnoScanHardware : public State {
176     public:
177         /**
178          * @Description  PNO hardware scanning status.
179          *
180          */
181         explicit PnoScanHardware(ScanStateMachine *paraScanStateMachine);
182         ~PnoScanHardware();
183         void GoInState();
184         void GoOutState();
185         bool ExecuteStateMsg(InternalMessagePtr msg);
186 
187     private:
188         ScanStateMachine *pScanStateMachine;
189     };
190 
191     class CommonScanAfterPno : public State {
192     public:
193         /**
194          * @Description  Single scanning status after PNO scanning.
195          *
196          */
197         explicit CommonScanAfterPno(ScanStateMachine *paraScanStateMachine);
198         ~CommonScanAfterPno();
199         void GoInState();
200         void GoOutState();
201         bool ExecuteStateMsg(InternalMessagePtr msg);
202 
203     private:
204         ScanStateMachine *pScanStateMachine;
205     };
206 
207     class PnoScanSoftware : public State {
208     public:
209         /**
210          * @Description  PNO software scanning status.
211          *
212          */
213         explicit PnoScanSoftware(ScanStateMachine *paraScanStateMachine);
214         ~PnoScanSoftware();
215         void GoInState();
216         void GoOutState();
217         bool ExecuteStateMsg(InternalMessagePtr msg);
218 
219     private:
220         ScanStateMachine *pScanStateMachine;
221     };
222 
223     class PnoSwScanFree : public State {
224     public:
225         /**
226          * @Description  PNO software scans the idle state.
227          *
228          */
229         explicit PnoSwScanFree(ScanStateMachine *paraScanStateMachine);
230         ~PnoSwScanFree();
231         void GoInState();
232         void GoOutState();
233         bool ExecuteStateMsg(InternalMessagePtr msg);
234 
235     private:
236         ScanStateMachine *pScanStateMachine;
237     };
238 
239     class PnoSwScanning : public State {
240     public:
241         /**
242          * @Description  PNO software scanning status.
243          *
244          */
245         explicit PnoSwScanning(ScanStateMachine *paraScanStateMachine);
246         ~PnoSwScanning();
247         void GoInState();
248         void GoOutState();
249         bool ExecuteStateMsg(InternalMessagePtr msg);
250 
251     private:
252         ScanStateMachine *pScanStateMachine;
253     };
254 
255 private:
256     std::atomic<bool> quitFlag;                               /* Scanning state machine exit flag */
257     InitState *initState;                        /* Scanning initial status pointer */
258     HardwareReady *hardwareReadyState;           /* Pointer to the hardware startup completion status */
259     CommonScan *commonScanState;                 /* Pointer to the common scanning status */
260     CommonScanUnworked *commonScanUnworkedState; /* Pointer to the common scanning idle state */
261     CommonScanning *commonScanningState;         /* Pointer to the common scanning status */
262     PnoScan *pnoScanState;                       /* PNO scanning status */
263     PnoScanHardware *pnoScanHardwareState;       /* PNO hardware scanning status */
264     CommonScanAfterPno *commonScanAfterPnoState; /*
265                                                   * After obtaining the scanning result,
266                                                   * determine whether to perform a single scan
267                                                   */
268     PnoScanSoftware *pnoScanSoftwareState;       /* PNO software scanning status */
269     PnoSwScanFree *pnoSwScanFreeState;           /* PNO software scans the idle state */
270     PnoSwScanning *pnoSwScanningState;           /* PNO software scanning status */
271 
272     std::map<int, InterScanConfig> runningScans;     /*
273                                                       * Saves the parameter information about the scan that is
274                                                       * being performed
275                                                       */
276     std::map<int, InterScanConfig> waitingScans;     /* Saves the parameters to be scanned */
277     WifiHalScanParam runningScanSettings;               /*
278                                                       * Parameter information about the scan
279                                                       * that is being performed
280                                                       */
281     bool runningFullScanFlag;                        /* Full scan is in progress. */
282     ScanStatusReportHandler scanStatusReportHandler; /* Status reporting callback function */
283 
284     bool supportHwPnoFlag;                   /* Whether to support hardware PNO scanning */
285     bool pnoConfigStoredFlag;                /* The PNO configuration information has been saved */
286     bool runningHwPnoFlag;                   /* PNO scanning is in progress. */
287     bool remainWaitResultTimer;              /* Waiting for scanning results timer */
288     PnoScanConfig runningPnoScanConfig;      /* PNO scan configuration in progress */
289     InterScanConfig runningScanConfigForPno; /*
290                                               * Common scan configuration for
291                                               * ongoing PNO scans
292                                               */
293     bool runningSwPnoFlag;                   /* Software PNO scanning is in progress. */
294 
295     static std::shared_mutex lock;                  /* data lock */
296     int64_t lastScanStartTime;                   /* the scan time for last single scan */
297     int m_instId;
298 
299     class FilterScanResultRecord {
300     public:
301         /**
302          * record filtered scanResult
303          *
304          * @param interScanInfo the scanInfo filtered
305          */
306         void RecordFilteredScanResult(const InterScanInfo& interScanInfo);
307 
308         /**
309          *  GetFilteredScanResultMsg
310          *
311          * @return filterMsg
312          */
313         std::string GetFilteredScanResultMsg();
314     private:
315 
316         std::stringstream GetScanInfoMsg(const InterScanInfo& interScanInfo);
317         std::map<std::string, std::stringstream> filteredMsgs;
318     };
319 
320     /**
321      * @Description  Processing of Scan Requests Received in Idle State.
322      *
323      * @param interMessage - internal message
324      */
325     void CommonScanRequestProcess(InternalMessagePtr interMessage);
326     /**
327      * @Description  Obtains the scanning request parameters carried in an internal message.
328      *
329      * @param interMessage - internal message[in]
330      * @param requestIndex - Request index carried in the message[out]
331      * @param scanConfig - Scan configuration carried in the message[out]
332      * @return success - true, failed - false
333      */
334     bool GetCommonScanRequestInfo(InternalMessagePtr interMessage, int &requestIndex, InterScanConfig &scanConfig);
335     /**
336      * @Description  Obtains the scanning configuration carried in an internal message.
337      *
338      * @param interMessage - internal message[in]
339      * @param scanConfig - Scan configuration carried in the message[out]
340      * @return success - true, failed - false
341      */
342     bool GetCommonScanConfig(InternalMessagePtr interMessage, InterScanConfig &scanConfig);
343     /**
344      * @Description  Start a common scan.
345      *
346      */
347     void StartNewCommonScan();
348     /**
349      * @Description  Clears the scanning information in progress.
350      *
351      */
352     void ClearRunningScanSettings();
353     /**
354      * @Description  Starting a Single Common Scan.
355      *
356      * @param scanParam - Scanning parameters[in]
357      * @return success: true, failed: false
358      */
359     bool StartSingleCommonScan(WifiHalScanParam &scanParam);
360     /**
361      * @Description  Processing of new scan requests received while scanning.
362      *
363      * @param interMessage - internal Message[in]
364      */
365     void CommonScanWhenRunning(InternalMessagePtr interMessage);
366     /**
367     * @Description  Compare the parameters of the current scan with those carried in
368                     the new scan request. If the current scan can overwrite the new
369                     scan, obtain the result from the current scan. Otherwise, start
370                     the new scan.
371     *
372     * @param interScanConfig - Parameters in the scan request[in]
373     * @return success: true, failed: false
374     */
375     bool ActiveCoverNewScan(InterScanConfig &interScanConfig);
376 
377     /**
378      * Filter the scanResults
379      *
380      * @param scanInfoList scanResult
381      */
382     void FilterScanResult(std::vector<InterScanInfo> &scanInfoList);
383     /**
384      * @Description  Processing after the ScanMonitor scan success message is received.
385      *
386      */
387     void CommonScanInfoProcess();
388     /**
389      * @Description Parse security type.
390      *
391      * @param scanInfo - scan result[inout]
392      */
393     void ParseSecurityType(InterScanInfo &scanInfo);
394     /**
395      * @Description The band and security type are parsed from the scanning result obtained by the IDL.
396      *
397      * @param scanInfo - scan result[inout]
398      */
399     void GetSecurityTypeAndBand(std::vector<InterScanInfo> &scanInfo);
400     /**
401      * @Description The wifi mode are parsed from the scanning result obtained by the IDL.
402      *
403      * @param scanInfo - scan result[inout]
404      */
405     void SetWifiMode(InterScanInfo &scanInfo);
406     /**
407      * @Description  Reporting Status to ScanService.
408      *
409      * @param status - status code[in]
410      */
411     void ReportStatusChange(ScanStatus status);
412     /**
413      * @Description  Reports internal events to the ScanService. This parameter is used only for timers.
414      *
415      * @param innerEvent - Internal Event Name[in]
416      */
417     void ReportScanInnerEvent(ScanInnerEventType innerEvent);
418     /**
419      * @Description  Reporting Common Scan Failures to ScanService.
420      *
421      * @param requestIndex - Request index included in the failure[in]
422      */
423     void ReportCommonScanFailed(int requestIndex);
424     /**
425     * @Description  Replying the operation failure message and clearing the request list.
426     *
427     * @param runningFlag - If the value is true, the running list is cleared.
428                         If the value is false, the waiting list is cleared.[in]
429     */
430     void ReportCommonScanFailedAndClear(bool runningFlag);
431     /**
432     * @Description  delete runningScans and waitingScans corresponding request.
433     *
434     * @param requestIndex - The specified element in the map set is deleted
435                             based on the transferred key[in]
436     */
437     void RemoveCommonScanRequest(int requestIndex);
438     /**
439      * @Description  Gets the index of an ongoing scan request.
440      *
441      * @param runningIndexList - List of scan requests in progress[out]
442      */
443     void GetRunningIndexList(std::vector<int> &runningIndexList);
444     /**
445      * @Description  Gets the index of the scanning request that is waiting.
446      *
447      * @param waitingIndexList - List of pending scan request indexes[out]
448      */
449     void GetWaitingIndexList(std::vector<int> &waitingIndexList);
450     /**
451      * @Description  Check whether the scanstyle is valid.
452      *
453      * @param scanStyle - style of scan[in]
454      * @return success:true, failed:false
455      */
456     bool VerifyScanStyle(int scanStyle);
457     /**
458     * @Description  If the new scan request is SCAN_TYPE_HIGH_ACCURACY and the
459                     current scan request is not, a new scan needs to be started.
460     *
461     * @param scanStyle - style of scan[in]
462     * @return success:true, failed:false
463     */
464     bool ActiveScanStyle(int scanStyle);
465     /**
466     * @Description  If there are SCAN_TYPE_HIGH_ACCURACY requests,
467                     the combined requests are SCAN_TYPE_HIGH_ACCURACY requests.
468     *
469     * @param currentScanStyle - current style of scan[in]
470     * @param newScanStyle - new style of scan[in]
471     * @return scantyle
472     */
473     int MergeScanStyle(int currentScanStyle, int newScanStyle);
474     /**
475      * @Description  Processing the received PNO scanning request.
476      *
477      * @param msg - internal message[in]
478      */
479     void PnoScanRequestProcess(InternalMessagePtr interMessage);
480     /**
481     * @Description  If the PNO scanning is interrupted by a single scan,
482                     resume the PNO scanning after the single scan is complete.
483     *
484     */
485     void ContinuePnoScanProcess();
486     /**
487      * @Description  Hardware PNO scanning.
488      *
489      * @param msg - internal message[in]
490      */
491     void PnoScanHardwareProcess(InternalMessagePtr interMessage);
492     /**
493      * @Description  Start hardware PNO scanning.
494      *
495      * @return success: true, failed: false
496      */
497     bool StartPnoScanHardware();
498     /**
499      * @Description  Stop hardware PNO scanning.
500      *
501      */
502     void StopPnoScanHardware();
503     /**
504     * @Description  Obtain the PNO scanning request parameters carried in the internal message
505                     and update the parameters to the saved configuration.
506     *
507     * @param interMessage - internal message[in]
508     */
509     void UpdatePnoScanRequest(InternalMessagePtr interMessage);
510     /**
511     * @Description  Obtain the PNO scanning request parameters carried in the internal message
512                     and update the parameters to the saved configuration.
513     *
514     * @param interMessage - internal message[in]
515     * @return success: true, failed: false
516     */
517     bool GetPnoScanRequestInfo(InternalMessagePtr interMessage);
518     /**
519      * @Description  Obtains the scanning configuration carried in an internal message.
520      *
521      * @param interMessage - internal message[in]
522      * @param pnoScanConfig - PNO scanning configuration carried in the message[out]
523      * @return success: true, failed: false
524      */
525     bool GetPnoScanConfig(InternalMessagePtr interMessage, PnoScanConfig &pnoScanConfig);
526     /**
527      * @Description  Processing after receiving a PNO scan success message from the ScanMonitor.
528      *
529      */
530     void HwPnoScanInfoProcess();
531     /**
532      * @Description  Send the scanning result to ScanService.
533      *
534      * @param scanInfos - pno scan result
535      */
536     void ReportPnoScanInfos(std::vector<InterScanInfo> &scanInfos);
537     /**
538      * @Description  Determine whether to start a common scan after hardware PNO.
539      *
540      * @param scanInfos - PNO scanning result
541      * @return success:true, failed:false
542      */
543     bool NeedCommonScanAfterPno(std::vector<InterScanInfo> &scanInfos);
544     /**
545      * @Description  Common scanning after hardware PNO.
546      *
547      */
548     void CommonScanAfterPnoProcess();
549     /**
550      * @Description  Processing of a success message received after PNO scanning.
551      *
552      */
553     void CommonScanAfterPnoResult();
554     /**
555      * @Description  Clear PNO Scan Configuration.
556      *
557      */
558     void ClearPnoScanConfig();
559     /**
560      * @Description  PNO Scan Failure Handling.
561      *
562      */
563     void PnoScanFailedProcess();
564     /**
565      * @Description  Obtain the scanning result from the IDL.
566      *
567      * @param scanInfos - scan result[out]
568      * @return success:true, failed:false
569      */
570     bool GetScanInfos(std::vector<InterScanInfo> &scanInfos);
571     /**
572      * @Description  start PNO Software Scanning.
573      *
574      * @return success:true, failed:false
575      */
576     bool StartNewSoftwareScan();
577     /**
578      * @Description  This function is called periodically during PNO software scanning.
579      *
580      * @return success:true, failed:false
581      */
582     bool RepeatStartCommonScan();
583     /**
584      * @Description  Stopping PNO Software Scanning.
585      *
586      */
587     void StopPnoScanSoftware();
588     /**
589      * @Description  When the PNO software scanning is started, another PNO software
590      *               scanning request is sent.
591      *
592      * @param interMessage - internal message
593      */
594     void PnoScanSoftwareProcess(InternalMessagePtr interMessage);
595     /**
596      * @Description  Invoke the IDL client to obtain the software scanning result.
597      *
598      */
599     void SoftwareScanInfoProcess();
600     /**
601      * @Description  Constructing the State Tree of the Scan State Machine.
602      *
603      * @return success: true, failed: false
604      */
605     bool InitCommonScanState();
606     /**
607      * @Description  Constructing the State Tree of the Scan State Machine.
608      *
609      * @return success: true, failed: false
610      */
611     bool InitPnoScanState();
612     /**
613      * @Description  Constructing the State Tree of the Scan State Machine.
614      *
615      */
616     void BuildScanStateTree();
617 };
618 }  // namespace Wifi
619 }  // namespace OHOS
620 
621 #endif