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