1 /*
2  * Copyright (C) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <sstream>
17 #include "network_selector_impl.h"
18 #include "wifi_comparator_impl.h"
19 #include "wifi_scorer_impl.h"
20 #include "network_selection_utils.h"
21 #include "external_wifi_common_builder_manager.h"
22 #include "external_wifi_filter_builder_manager.h"
23 #include "wifi_filter_impl.h"
24 #include "wifi_logger.h"
25 #include "parameters.h"
26 
27 using namespace std;
28 
29 namespace OHOS::Wifi::NetworkSelection {
30 
31 DEFINE_WIFILOG_LABEL("NetworkSelector")
32 
GetCandidatesFromSubNetworkSelector()33 void AutoConnectIntegrator::GetCandidatesFromSubNetworkSelector()
34 {
35     for (const auto &subNetworkSelector : subNetworkSelectors) {
36         subNetworkSelector->GetBestCandidates(networkCandidates);
37     }
38 }
39 
AutoConnectIntegrator()40 AutoConnectIntegrator::AutoConnectIntegrator() : CompositeNetworkSelector(
41     "autoConnectIntegrator")
42 {
43     auto filters = make_shared<AndWifiFilter>();
44     filters->AddFilter(make_shared<HiddenWifiFilter>());
45     filters->AddFilter(make_shared<SignalStrengthWifiFilter>());
46     if (OHOS::system::GetParameter("ohos.boot.advsecmode.state", "0") != "0") {
47         filters->AddFilter(make_shared<WeakAlgorithmWifiFilter>());
48     }
49     SetWifiFilter(filters);
50     AddSubNetworkSelector(make_shared<SavedNetworkTracker>());
51     auto comparator = make_shared<WifiScorerComparator>(m_networkSelectorName);
52     comparator->AddScorer(make_shared<ThroughputScorer>());
53     SetWifiComparator(comparator);
54 }
55 
Nominate(NetworkCandidate & networkCandidate)56 bool AutoConnectIntegrator::Nominate(NetworkCandidate &networkCandidate)
57 {
58     for (auto &networkSelector : subNetworkSelectors) {
59         networkSelector->TryNominate(networkCandidate);
60     }
61     return false;
62 }
63 
GetCandidatesFromSubNetworkSelector()64 void Wifi2WifiIntegrator::GetCandidatesFromSubNetworkSelector()
65 {
66     for (const auto &subNetworkSelector : subNetworkSelectors) {
67         subNetworkSelector->GetBestCandidates(networkCandidates);
68     }
69 }
70 
Wifi2WifiIntegrator()71 Wifi2WifiIntegrator::Wifi2WifiIntegrator() : CompositeNetworkSelector("Wifi2WifiIntegrator")
72 {
73     auto andFilters = make_shared<AndWifiFilter>();
74     andFilters->AddFilter(make_shared<ValidNetworkIdFilter>());
75     andFilters->AddFilter(make_shared<NotCurrentNetworkFilter>());
76     andFilters->AddFilter(make_shared<NotNetworkBlackListFilter>());
77     ExternalWifiCommonBuildManager::GetInstance().BuildFilter(TagType::NOT_P2P_ENHANCE_FREQ_AT_5G_FILTER_TAG,
78         *andFilters);
79     andFilters->AddFilter(make_shared<NotP2pFreqAt5gFilter>());
80     andFilters->AddFilter(make_shared<SignalLevelFilter>());
81     andFilters->AddFilter(make_shared<WifiSwitchThresholdFilter>());
82     andFilters->AddFilter(make_shared<ValidConfigNetworkFilter>());
83     SetWifiFilter(andFilters);
84 
85     AddSubNetworkSelector(make_shared<PreferredApSelector>());
86 }
87 
Nominate(NetworkCandidate & networkCandidate)88 bool Wifi2WifiIntegrator::Nominate(NetworkCandidate &networkCandidate)
89 {
90     for (auto &networkSelector : subNetworkSelectors) {
91         networkSelector->TryNominate(networkCandidate);
92     }
93     return false;
94 }
95 
SavedNetworkTracker()96 SavedNetworkTracker::SavedNetworkTracker() : CompositeNetworkSelector("savedNetworkTracker")
97 {
98     auto andFilter = make_shared<AndWifiFilter>();
99     andFilter->AddFilter(make_shared<SavedWifiFilter>());
100     andFilter->AddFilter(make_shared<PassPointWifiFilter>());
101     andFilter->AddFilter(make_shared<EphemeralWifiFilter>());
102     andFilter->AddFilter(make_shared<DisableWifiFilter>());
103     andFilter->AddFilter(make_shared<MatchedUserSelectBssidWifiFilter>());
104     ExternalWifiFilterBuildManager::GetInstance().BuildFilter(FilterTag::SAVED_NETWORK_TRACKER_FILTER_TAG, *andFilter);
105 #ifdef FEATURE_ITNETWORK_PREFERRED_SUPPORT
106     shared_ptr<CustNetPreferredNetworkSelector> custNetPreferredNetworkSelector = nullptr;
107     if (NetworkSelectionUtils::CheckDeviceTypeByVendorCountry()) {
108         custNetPreferredNetworkSelector = make_shared<CustNetPreferredNetworkSelector>();
109     }
110 #endif
111     auto blackListNetworkSelector = make_shared<BlackListNetworkSelector>();
112     auto hasInternetNetworkSelector = make_shared<HasInternetNetworkSelector>();
113     auto recoveryNetworkSelector = make_shared<RecoveryNetworkSelector>();
114     auto portalNetworkSelector = make_shared<PortalNetworkSelector>();
115     portalNetworkSelector->InitFilter();
116     auto noInternetNetworkSelector = make_shared<NoInternetNetworkSelector>();
117 
118 #ifdef FEATURE_ITNETWORK_PREFERRED_SUPPORT
119     andFilter->AddFilter(custNetPreferredNetworkSelector);
120 #endif
121     andFilter->AddFilter(blackListNetworkSelector);
122     andFilter->AddFilter(hasInternetNetworkSelector);
123     andFilter->AddFilter(recoveryNetworkSelector);
124     andFilter->AddFilter(portalNetworkSelector);
125     andFilter->AddFilter(noInternetNetworkSelector);
126     SetWifiFilter(andFilter);
127     /*
128      * current networkSelector only obtains one non-empty network selection result of subNetworkSelector, which is
129      * depends on the sequence of the subNetworkSelectors, When the network selection result of one of the
130      * subNetworkSelectors is not empty, the network selection result of other subNetworkSelectors inserted later will
131      * be abandoned.
132      */
133 #ifdef FEATURE_ITNETWORK_PREFERRED_SUPPORT
134     AddSubNetworkSelector(custNetPreferredNetworkSelector);
135 #endif
136     AddSubNetworkSelector(hasInternetNetworkSelector);
137     AddSubNetworkSelector(recoveryNetworkSelector);
138     AddSubNetworkSelector(portalNetworkSelector);
139     AddSubNetworkSelector(noInternetNetworkSelector);
140     AddSubNetworkSelector(blackListNetworkSelector);
141 }
142 
Nominate(NetworkCandidate & networkCandidate)143 bool SavedNetworkTracker::Nominate(NetworkCandidate &networkCandidate)
144 {
145     return false;
146 }
147 
GetCandidatesFromSubNetworkSelector()148 void SavedNetworkTracker::GetCandidatesFromSubNetworkSelector()
149 {
150     for (const auto &subNetworkSelector : subNetworkSelectors) {
151         subNetworkSelector->GetBestCandidates(networkCandidates);
152         if (!networkCandidates.empty()) {
153             /* abandon networkCandidates from other low-priority networkSelectors */
154             return;
155         }
156     }
157 }
158 
SimpleFilterNetworkSelector(const std::string & networkSelectorName)159 SimpleFilterNetworkSelector::SimpleFilterNetworkSelector(const std::string &networkSelectorName)
160     : SimpleNetworkSelector(networkSelectorName), SimpleWifiFilter(networkSelectorName) {}
161 
~SimpleFilterNetworkSelector()162 SimpleFilterNetworkSelector::~SimpleFilterNetworkSelector()
163 {
164     if (!networkCandidates.empty()) {
165         WIFI_LOGI("networkCandidates in %{public}s: %{public}s",
166                   m_networkSelectorName.c_str(),
167                   NetworkSelectionUtils::GetNetworkCandidatesInfo(networkCandidates).c_str());
168     }
169     if (!filteredNetworkCandidates.empty()) {
170         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
171                   m_networkSelectorName.c_str(),
172                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
173     }
174 }
175 
BlackListNetworkSelector()176 BlackListNetworkSelector::BlackListNetworkSelector() : SimpleFilterNetworkSelector("blackListNetworkSelector")
177 {
178     SetWifiFilter(make_shared<WifiFunctionFilterAdapter>(NetworkSelectionUtils::IsBlackListNetwork, "isBlackList"));
179 }
180 
Nominate(NetworkCandidate & networkCandidate)181 bool BlackListNetworkSelector::Nominate(NetworkCandidate &networkCandidate)
182 {
183     if (!networkCandidates.empty()) {
184         networkCandidates.at(0) = &networkCandidate;
185     } else {
186         networkCandidates.emplace_back(&networkCandidate);
187     }
188     return true;
189 }
190 
Filter(NetworkCandidate & networkCandidate)191 bool BlackListNetworkSelector::Filter(NetworkCandidate &networkCandidate)
192 {
193     return !TryNominate(networkCandidate);
194 }
195 
HasInternetNetworkSelector()196 HasInternetNetworkSelector::HasInternetNetworkSelector() : SimpleFilterNetworkSelector("hasInternetNetworkSelector")
197 {
198     auto filters = make_shared<AndWifiFilter>();
199     ExternalWifiFilterBuildManager::GetInstance().BuildFilter(FilterTag::HAS_INTERNET_NETWORK_SELECTOR_FILTER_TAG,
200                                                               *filters);
201     filters->AddFilter(make_shared<HasInternetWifiFilter>());
202     SetWifiFilter(filters);
203     auto networkScoreComparator = make_shared<WifiScorerComparator>(m_networkSelectorName);
204     networkScoreComparator->AddScorer(make_shared<NetworkStatusHistoryScorer>());
205     networkScoreComparator->AddScorer(make_shared<SavedNetworkScorer>("hasInternetNetworkScorer"));
206     networkScoreComparator->AddScorer(make_shared<RssiScorer>());
207     SetWifiComparator(networkScoreComparator);
208 }
209 
Filter(NetworkCandidate & networkCandidate)210 bool HasInternetNetworkSelector::Filter(NetworkCandidate &networkCandidate)
211 {
212     TryNominate(networkCandidate);
213     return networkCandidates.empty();
214 }
215 
216 #ifdef FEATURE_ITNETWORK_PREFERRED_SUPPORT
CustNetPreferredNetworkSelector()217 CustNetPreferredNetworkSelector::CustNetPreferredNetworkSelector()
218     : SimpleFilterNetworkSelector("custNetPreferredNetworkSelector")
219 {
220     auto filters = make_shared<OrWifiFilter>();
221     ExternalWifiFilterBuildManager::GetInstance().BuildFilter(FilterTag::IT_NETWORK_SELECTOR_FILTER_TAG,
222                                                               *filters);
223     SetWifiFilter(filters);
224     auto networkScoreComparator = make_shared<WifiScorerComparator>(m_networkSelectorName);
225     networkScoreComparator->AddScorer(make_shared<SavedNetworkScorer>("custNetPreferredNetworkScorer"));
226     networkScoreComparator->AddScorer(make_shared<RssiScorer>());
227     SetWifiComparator(networkScoreComparator);
228 }
229 
Filter(NetworkCandidate & networkCandidate)230 bool CustNetPreferredNetworkSelector::Filter(NetworkCandidate &networkCandidate)
231 {
232     return !NetworkSelector::TryNominate(networkCandidate);
233 }
234 #endif
235 
RecoveryNetworkSelector()236 RecoveryNetworkSelector::RecoveryNetworkSelector() : SimpleFilterNetworkSelector("recoveryNetworkSelector")
237 {
238     auto filters = make_shared<AndWifiFilter>();
239     ExternalWifiFilterBuildManager::GetInstance().BuildFilter(FilterTag::RECOVERY_NETWORK_SELECTOR_FILTER_TAG,
240                                                               *filters);
241     filters->AddFilter(make_shared<RecoveryWifiFilter>());
242     SetWifiFilter(filters);
243     auto networkScorerComparator = make_shared<WifiScorerComparator>(m_networkSelectorName);
244     networkScorerComparator->AddScorer(make_shared<SavedNetworkScorer>("recoveryNetworkScorer"));
245     networkScorerComparator->AddScorer(make_shared<RssiScorer>());
246     SetWifiComparator(networkScorerComparator);
247 }
248 
Filter(NetworkCandidate & networkCandidate)249 bool RecoveryNetworkSelector::Filter(NetworkCandidate &networkCandidate)
250 {
251     TryNominate(networkCandidate);
252     return networkCandidates.empty();
253 }
254 
PortalNetworkSelector()255 PortalNetworkSelector::PortalNetworkSelector() : SimpleNetworkSelector("portalNetworkSelector"), OrWifiFilter()
256 {
257     SetWifiFilter(make_shared<PoorPortalWifiFilter>());
258     auto networkScorerComparator = make_shared<WifiScorerComparator>(m_networkSelectorName);
259     networkScorerComparator->AddScorer(make_shared<LastHaveInternetTimeScorer>());
260     networkScorerComparator->AddScorer(make_shared<SavedNetworkScorer>("portalNetworkScorer"));
261     networkScorerComparator->AddScorer(make_shared<RssiScorer>());
262     SetWifiComparator(networkScorerComparator);
263 }
264 
~PortalNetworkSelector()265 PortalNetworkSelector::~PortalNetworkSelector()
266 {
267     if (!filteredNetworkCandidates.empty()) {
268         WIFI_LOGI("filteredNetworkCandidates in %{public}s: %{public}s",
269                   m_networkSelectorName.c_str(),
270                   NetworkSelectionUtils::GetNetworkCandidatesInfo(filteredNetworkCandidates).c_str());
271     }
272 }
273 
InitFilter()274 void PortalNetworkSelector::InitFilter()
275 {
276     AddFilter(make_shared<PortalWifiFilter>());
277     AddFilter(make_shared<MaybePortalWifiFilter>());
278     ExternalWifiFilterBuildManager::GetInstance().BuildFilter(FilterTag::PORTAL_NETWORK_SELECTOR_FILTER_TAG, *this);
279 }
280 
Filter(NetworkCandidate & networkCandidate)281 bool PortalNetworkSelector::Filter(NetworkCandidate &networkCandidate)
282 {
283     if (OrWifiFilter::Filter(networkCandidate)) {
284         TryNominate(networkCandidate);
285     }
286     if (networkCandidates.empty()) {
287         return true;
288     }
289     filteredNetworkCandidates.emplace_back(&networkCandidate);
290     return false;
291 }
292 
GetNetworkSelectorMsg()293 string PortalNetworkSelector::GetNetworkSelectorMsg()
294 {
295     stringstream networkSelectorMsg;
296     networkSelectorMsg << R"({ "name": ")" << m_networkSelectorName << "\" ";
297     string filterMsg;
298     if (!filters.empty()) {
299         filterMsg += OrWifiFilter::GetFilterMsg();
300     }
301     if (filter) {
302         if (!filterMsg.empty()) {
303             filterMsg += "&&";
304         }
305         filterMsg += filter->GetFilterMsg();
306     }
307     if (!filterMsg.empty()) {
308         networkSelectorMsg << R"(,"filter": ")" << filterMsg << "\"";
309     }
310     networkSelectorMsg << "}";
311     return networkSelectorMsg.str();
312 }
313 
NoInternetNetworkSelector()314 NoInternetNetworkSelector::NoInternetNetworkSelector() : SimpleFilterNetworkSelector("noInternetNetworkSelector")
315 {
316     SetWifiFilter(make_shared<NoInternetWifiFilter>());
317     auto networkScorerComparator = make_shared<WifiScorerComparator>(m_networkSelectorName);
318     auto noInternetNetworkScorer = make_shared<SavedNetworkScorer>("noInternetNetworkScorer");
319     noInternetNetworkScorer->AddScorer(make_shared<NoInternetNetworkStatusHistoryScorer>());
320     networkScorerComparator->AddScorer(noInternetNetworkScorer);
321     networkScorerComparator->AddScorer(make_shared<RssiScorer>());
322     SetWifiComparator(networkScorerComparator);
323 }
324 
Filter(NetworkCandidate & networkCandidate)325 bool NoInternetNetworkSelector::Filter(NetworkCandidate &networkCandidate)
326 {
327     TryNominate(networkCandidate);
328     return false;
329 }
330 
PreferredApSelector()331 PreferredApSelector::PreferredApSelector() : SimpleFilterNetworkSelector("PreferredApSelector")
332 {
333     // The filtering conditions have already been done outside, so no further filtering is needed here.
334     auto networkScoreComparator = make_shared<WifiScorerComparator>(m_networkSelectorName);
335     networkScoreComparator->AddScorer(make_shared<ApQualityScorer>("ApQualityScorer"));
336     networkScoreComparator->AddScorer(make_shared<RssiScorer>());
337     SetWifiComparator(networkScoreComparator);
338 }
339 
Filter(NetworkCandidate & networkCandidate)340 bool PreferredApSelector::Filter(NetworkCandidate &networkCandidate)
341 {
342     TryNominate(networkCandidate);
343     return false;
344 }
345 }
346