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_WIFI_AUTO_CONNECT_SERVICE_H
17 #define OHOS_WIFI_AUTO_CONNECT_SERVICE_H
18 
19 #include <ctime>
20 #include <string>
21 #include <unordered_map>
22 #include <vector>
23 #include "wifi_log.h"
24 #include "wifi_errcode.h"
25 #include "wifi_msg.h"
26 #include "log_helper.h"
27 #include "sta_define.h"
28 #include "sta_state_machine.h"
29 #include "sta_saved_device_appraisal.h"
30 #include "network_selection_manager.h"
31 #include "magic_enum.h"
32 
33 namespace OHOS {
34 namespace Wifi {
35 static const int MAX_BSSID_BLOCKLIST_COUNT = 3;
36 static const int AP_CANNOT_HANDLE_NEW_STA = 17;
37 static const int MAX_BSSID_BLOCKLIST_TIME = 60; // 60s
38 static const int BLOCKLIST_INVALID_SIZE = -1;
39 static const int STA_CAP_ROAMING = 0x800000;
40 static const int MIN_APPRAISAL_PRIORITY = 6;
41 static const int MAX_APPRAISAL_NUM = 6;
42 static const int MIN_SELECT_NETWORK_TIME = 30;
43 static const int MIN_5GHZ_BAND_FREQUENCY = 5000;
44 static const int RSSI_DELIMITING_VALUE = -65;
45 static const int MIN_RSSI_VALUE_24G = -77;
46 static const int MIN_RSSI_VALUE_5G = -80;
47 static const int TIME_FROM_LAST_SELECTION = 60;
48 static const int MIN_ROAM_RSSI_DIFF = 6;
49 class StaAutoConnectService {
50     FRIEND_GTEST(StaAutoConnectService);
51 public:
52     StaAutoConnectService(StaStateMachine *staStateMachine, int instId = 0);
53     virtual ~StaAutoConnectService();
54     /**
55      * @Description  Initialize StaAutoConnectService
56      *
57      */
58     virtual ErrCode InitAutoConnectService();
59     /**
60      * @Description  Processing scan results
61      *
62      * @param scanInfos - The list of scanning results(in)
63      */
64     virtual void OnScanInfosReadyHandler(const std::vector<InterScanInfo> &scanInfos);
65     /**
66      * @Description  Whether tracking should enable or disable scanned BSSIDs
67      *
68      * @param bssid - BSSID to be enabled/disabled(in)
69      * @param enable - true: Enable the BSSID. false: disable the BSSID.(in)
70      * @param reason - Enable/Disable reason code.(in)
71      * @Return success: true. failed: false.
72      */
73     virtual bool EnableOrDisableBssid(std::string bssid, bool enable, int reason);
74     /**
75      * @Description  Select the best device from the range.
76      *
77      * @param scanInfos - WifiScanInfo list of all APs in the range(in)
78      * @param blockedBssids - Blocklisted BSSID List(in)
79      * @param info - Current Connected Device(in)
80      * @param electedDevice - Elected Device(out)
81      * @Return success : WIFI_OPT_SUCCESS  failed : WIFI_OPT_FAILED
82      */
83     virtual ErrCode AutoSelectDevice(WifiDeviceConfig &electedDevice, const std::vector<InterScanInfo> &scanInfos,
84         std::vector<std::string> &blockedBssids, WifiLinkedInfo &info);
85     /**
86      * @Description  Registering the Device Appraisal
87      *
88      * @param appraisal - Device appraisal to be registered(in)
89      * @param priority - Value between 0 and (SCORER_MIN_PRIORITY – 1)(in)
90      * @Return success : true  failed : false
91      */
92     virtual bool RegisterDeviceAppraisal(StaDeviceAppraisal *appraisal, int priority);
93 
94     /**
95      * @Description  disable auto join.
96      *
97      * @param conditionName autoJoinDisabled condition.
98      */
99     virtual void DisableAutoJoin(const std::string &conditionName);
100 
101     /**
102      * @Description  enable auto join.
103      *
104      * @param conditionName autoJoinDisabled condition.
105      */
106     virtual void EnableAutoJoin(const std::string &conditionName);
107 
108     /**
109      * @Description  register auto join condition.
110      *
111      * @param conditionName the name of condition.
112      * @param autoJoinCondition condition.
113      */
114     virtual void RegisterAutoJoinCondition(const std::string &conditionName,
115                                            const std::function<bool()> &autoJoinCondition);
116 
117     /**
118      * @Description  deregister auto join condition.
119      *
120      * @param conditionName the name of condition.
121      */
122     virtual void DeregisterAutoJoinCondition(const std::string &conditionName);
123 
124     /**
125      * @Description  set auto connect state callback.
126      *
127      * @param callbacks callbacks.
128      */
129     virtual void SetAutoConnectStateCallback(const std::vector<StaServiceCallback> &callbacks);
130 private:
131     StaStateMachine *pStaStateMachine;
132     StaDeviceAppraisal *pSavedDeviceAppraisal;
133     std::unique_ptr<NetworkSelectionManager> pNetworkSelectionManager = nullptr;
134     bool firmwareRoamFlag;
135     int maxBlockedBssidNum;
136     int selectDeviceLastTime;
137     StaDeviceAppraisal *pAppraisals[MAX_APPRAISAL_NUM];
138     int m_instId;
139     std::map<std::string, std::function<bool()>> autoJoinConditionsMap{};
140     std::mutex autoJoinMutex;
141     std::vector<StaServiceCallback> mStaCallbacks;
142     struct BlockedBssidInfo {
143         int count; /* Number of times the BSSID is rejected. */
144         bool blockedFlag;
145         int blockedTime;
BlockedBssidInfoBlockedBssidInfo146         BlockedBssidInfo()
147         {
148             count = 0;
149             blockedFlag = false;
150             blockedTime = 0;
151         }
~BlockedBssidInfoBlockedBssidInfo152         ~BlockedBssidInfo(){}
153     };
154     std::unordered_map<std::string, BlockedBssidInfo> blockedBssidMap;
155     std::mutex m_blockBssidMapMutex;
156     /**
157      * @Description  Clear all BSSIDs in BSSID Blocklist
158      *
159      */
160     void ClearAllBlockedBssids();
161     /**
162      * @Description  Refreshing the BSSID Blocklist
163      *
164      */
165     void ClearOvertimeBlockedBssid();
166     /**
167      * @Description  Compiles and returns the hash set of the blocklist BSSID.
168      *
169      * @param blockedBssids - Blocklisted BSSID List(out)
170      */
171     void GetBlockedBssids(std::vector<std::string> &blockedBssids);
172     /**
173      * @Description  Update the BSSID blocklist when the BSSID is enabled or disabled.
174      *
175      * @param bssid - BSSID to be enabled/disabled(in)
176      * @param enable - true: Enable the BSSID. false: disable the BSSID.(in)
177      * @param reasonCode - Enable/Disable reason code.(in)
178      * @Return: If the blocklist is updated, The value is true. Otherwise, the value is false.
179      */
180     bool AddOrDelBlockedBssids(std::string bssid, bool enable, int reason);
181     /**
182      * @Description  If the firmware roaming function is supported,
183                      update the firmware roaming config.
184      *
185      */
186     void SyncBlockedSsidFirmware();
187     /**
188      * @Description  Querying Firmware Information
189      *
190      * @Return: If the operation is successful, true is returned.
191                 If firmware roaming is supported but the valid roaming
192                 capability cannot be obtained, false is returned.
193      */
194     bool ObtainRoamCapFromFirmware();
195     /**
196      * @Description  Write Firmware Roaming Configuration to Firmware
197      *
198      * @param blocklistBssids - List of BSSIDs to Be Added to the Blocklist(in)
199      * @Return: True if successful, false otherwise
200      */
201     bool SetRoamBlockedBssidFirmware(const std::vector<std::string> &blocklistBssids) const;
202     /**
203      * @Description  Connect to an elected device
204      *
205      * @param electedDevice - Elected Device(in)
206      */
207     void ConnectElectedDevice(WifiDeviceConfig &electedDevice);
208     /**
209      * @Description  Get available device
210      *
211      * @param scanInfos - WifiScanInfo list of all APs in the range(in)
212      * @param blockedBssids - Blocklisted BSSID List(in)
213      * @param info - Current Connected Device(in)
214      * @param availableScanInfos - Available Scan Info(out)
215      */
216     void GetAvailableScanInfos(std::vector<InterScanInfo> &availableScanInfos,
217         const std::vector<InterScanInfo> &scanInfos, std::vector<std::string> &blockedBssids, WifiLinkedInfo &info);
218     /**
219      * @Description  Whether the device needs to be switched.
220      *
221      * @param info - Current Connected Device(in)
222      * @Return success : true  failed : false
223      */
224     bool AllowAutoSelectDevice(WifiLinkedInfo &info);
225     /**
226      * @Description  Whether the device needs to be switched.
227      *
228      * @param scanInfos - WifiScanInfo list of all APs in the range(in)
229      * @param info - Current Connected Device(in)
230      * @Return success : true  failed : false
231      */
232     bool AllowAutoSelectDevice(const std::vector<InterScanInfo> &scanInfos, WifiLinkedInfo &info);
233     /**
234      * @Description  Whether the device strength is sufficient.
235      *
236      * @param scanInfos - WifiScanInfo list of all APs in the range(in)
237      * @param info - Current Connected Device(in)
238      * @Return success : true  failed : false
239      */
240     bool CurrentDeviceGoodEnough(const std::vector<InterScanInfo> &scanInfos, WifiLinkedInfo &info);
241     /**
242      * @Description  Whether 5G devices are available.
243      *
244      * @param scanInfos - WifiScanInfo list of all APs in the range(in)
245      * @Return success : true  failed : false
246      */
247     bool WhetherDevice5GAvailable(const std::vector<InterScanInfo> &scanInfos);
248     /**
249      * @Description  Select Roaming Device.
250      *
251      * @param availableScanInfos - Available device(in)
252      * @param scanInfos - WifiScanInfo list of all APs in the range(in)
253      * @param info - Current Connected Device(in)
254      * @param electedDevice - Elected Device(out)
255      * @Return success : true  failed : false
256      */
257     bool RoamingSelection(
258         WifiDeviceConfig &electedDevice, std::vector<InterScanInfo> &availableScanInfos, WifiLinkedInfo &info);
259     /**
260      * @Description  Select Roaming Device.
261      *
262      * @param WifiScanInfo - A scan result(in)
263      * @param info - Current Connected Device(in)
264      * @param electedDevice - Elected Device(out)
265      * @Return success : true  failed : false
266      */
267     bool RoamingEncryptionModeCheck(WifiDeviceConfig &electedDevice, InterScanInfo scanInfo, WifiLinkedInfo &info);
268     /**
269      * @Description  Whether the device is a 2.4G device.
270      *
271      * @param frequency(in)
272      * @Return success : true  failed : false
273      */
274     bool Whether24GDevice(int frequency);
275     /**
276      * @Description Whether allow auto join.
277      *
278      * @return true if allow autoJoin.
279      */
280     bool IsAllowAutoJoin();
281     /**
282      * @Description  Whether the device is a 5G device.
283      *
284      * @param frequency(in)
285      * @Return success : true  failed : false
286      */
287     bool Whether5GDevice(int frequency);
288 };
289 }  // namespace Wifi
290 }  // namespace OHOS
291 #endif