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 "network_selection.h"
17
18 namespace OHOS::Wifi::NetworkSelection {
19
20 std::map<FiltedReason, std::string> filtReasonToString = {
21 {FiltedReason::UNKNOW, "UNKNOW"},
22 {FiltedReason::HIDDEN_NETWORK, "HIDDEN_NETWORK"},
23 {FiltedReason::OPEN_NETWORK, "OPEN_NETWORK"},
24 {FiltedReason::NOT_OPEN_NETWORK, "NOT_OPEN_NETWORK"},
25 {FiltedReason::WEAK_ALGORITHM_WEP_SECURITY, "WEAK_ALGORITHM_WEP_SECURITY"},
26 {FiltedReason::WEAK_ALGORITHM_WPA_SECURITY, "WEAK_ALGORITHM_WPA_SECURITY"},
27 {FiltedReason::HAS_NETWORK_HISTORY, "HAS_NETWORK_HISTORY"},
28 {FiltedReason::PORTAL_NETWORK, "PORTAL_NETWORK"},
29 {FiltedReason::NOT_PORTAL_NETWORK, "NOT_PORTAL_NETWORK"},
30 {FiltedReason::OWE_NETWORK, "OWE_NETWORK"},
31 {FiltedReason::UNRECOVERABLE_NETWORK, "UNRECOVERABLE_NETWORK"},
32 {FiltedReason::NETWORK_STATUS_DISABLE, "NETWORK_STATUS_DISABLE"},
33 {FiltedReason::UNEXPECTED_NETWORK_BY_USER, "UNEXPECTED_NETWORK_BY_USER"},
34 {FiltedReason::NO_INTERNET, "NO_INTERNET"},
35 {FiltedReason::HAS_INTERNET, "HAS_INTERNET"},
36 {FiltedReason::NETWORK_ID_INVALID, "NETWORK_ID_INVALID"},
37 {FiltedReason::NOT_SYSTEM_NETWORK, "NOT_SYSTEM_NETWORK"},
38 {FiltedReason::TIME_INVALID, "TIME_INVALID"},
39 {FiltedReason::EPHEMERAL_NETWORK, "EPHEMERAL_NETWORK"},
40 {FiltedReason::PASSPOINT_NETWORK, "PASSPOINT_NETWORK"},
41 {FiltedReason::POOR_SIGNAL, "POOR_SIGNAL"},
42 {FiltedReason::TIMEOUT_AND_NEED_RECHECK, "TIMEOUT_AND_NEED_RECHECK"},
43 {FiltedReason::NOT_ALLOW_AUTO_CONNECT, "NOT_ALLOW_AUTO_CONNECT"},
44 {FiltedReason::NOT_SECURE_WIFI, "NOT_SECURE_WIFI"},
45 };
46
ToString(const std::string & filterName) const47 std::string NetworkCandidate::ToString(const std::string &filterName) const
48 {
49 std::stringstream networkCandidateInfo;
50 networkCandidateInfo << wifiDeviceConfig.networkId << "-";
51 constexpr int BSSID_MIN_SIZE = 2;
52 if (interScanInfo.bssid.size() <= BSSID_MIN_SIZE) {
53 networkCandidateInfo << interScanInfo.bssid;
54 } else {
55 networkCandidateInfo << interScanInfo.bssid.substr(interScanInfo.bssid.size() - BSSID_MIN_SIZE);
56 }
57 if (filterName.empty()) {
58 return networkCandidateInfo.str();
59 }
60 std::set<FiltedReason, FiltedReasonComparator, std::allocator<FiltedReason>> reasons = filtedReason.at(filterName);
61 if (reasons.empty()) {
62 return networkCandidateInfo.str();
63 }
64 networkCandidateInfo << "-";
65 for (const auto &reason: reasons) {
66 networkCandidateInfo << filtReasonToString[reason] << "&";
67 }
68 std::string candidateInfoStr = networkCandidateInfo.str();
69 candidateInfoStr.erase(candidateInfoStr.size() - 1);
70 return candidateInfoStr;
71 }
72
ToString() const73 std::string ScoreResult::ToString() const
74 {
75 constexpr int precision = 2;
76 std::stringstream scoreMsg;
77 scoreMsg << "{ ";
78 scoreMsg << scorerName << " : " << std::fixed << std::setprecision(precision) << score;
79 if (scoreDetails.empty()) {
80 scoreMsg << " }";
81 return scoreMsg.str();
82 }
83 scoreMsg << ", \"details\" : { ";
84 for (std::size_t i = 0; i < scoreDetails.size(); i++) {
85 scoreMsg << scoreDetails.at(i).ToString();
86 if (i < (scoreDetails.size() - 1)) {
87 scoreMsg << ", ";
88 }
89 }
90 scoreMsg << " }";
91 return scoreMsg.str();
92 }
93
DoFilter(NetworkCandidate & networkCandidate)94 bool IWifiFilter::DoFilter(NetworkCandidate &networkCandidate)
95 {
96 bool filterResult = Filter(networkCandidate);
97 AfterFilter(networkCandidate, filterResult);
98 return filterResult;
99 }
100
AfterFilter(NetworkCandidate & networkCandidate,bool filterResult)101 void IWifiFilter::AfterFilter(NetworkCandidate &networkCandidate,
102 bool filterResult) {}
103
SimpleWifiFilter(const std::string & networkSelectorFilterName)104 SimpleWifiFilter::SimpleWifiFilter(const std::string &networkSelectorFilterName)
105 : IWifiFilter(), filterName(networkSelectorFilterName) {}
106
107 SimpleWifiFilter::~SimpleWifiFilter() = default;
108
AfterFilter(NetworkCandidate & networkCandidate,bool filterResult)109 void SimpleWifiFilter::AfterFilter(NetworkCandidate &networkCandidate, bool filterResult)
110 {
111 if (!filterResult) {
112 filteredNetworkCandidates.emplace_back(&networkCandidate);
113 }
114 }
115
GetFilterMsg()116 std::string SimpleWifiFilter::GetFilterMsg()
117 {
118 return filterName;
119 }
120
WifiFunctionFilterAdapter(const std::function<bool (NetworkCandidate &)> & filter,const std::string & filterName,bool reverse)121 WifiFunctionFilterAdapter::WifiFunctionFilterAdapter(const std::function<bool(NetworkCandidate &)> &filter,
122 const std::string &filterName,
123 bool reverse)
124 : IWifiFilter(), targetFunction(filter), filterName(filterName), iSReverse(reverse) {}
125
126 WifiFunctionFilterAdapter::~WifiFunctionFilterAdapter() = default;
127
GetFilterMsg()128 std::string WifiFunctionFilterAdapter::GetFilterMsg()
129 {
130 return filterName;
131 }
132
Filter(NetworkCandidate & networkCandidate)133 bool WifiFunctionFilterAdapter::Filter(NetworkCandidate &networkCandidate)
134 {
135 return iSReverse != targetFunction.operator()(networkCandidate);
136 }
137
138 CompositeWifiFilter::~CompositeWifiFilter() = default;
139
AddFilter(const std::shared_ptr<IWifiFilter> & filter)140 void CompositeWifiFilter::AddFilter(const std::shared_ptr<IWifiFilter> &filter)
141 {
142 if (filter) {
143 filters.emplace_back(filter);
144 }
145 }
146
147 AndWifiFilter::~AndWifiFilter() = default;
148
Filter(NetworkCandidate & networkCandidate)149 bool AndWifiFilter::Filter(NetworkCandidate &networkCandidate)
150 {
151 return std::all_of(filters.begin(), filters.end(), [&networkCandidate](auto filter) {
152 return filter->DoFilter(networkCandidate);
153 });
154 }
155
GetFilterMsg()156 std::string AndWifiFilter::GetFilterMsg()
157 {
158 std::stringstream filterMsg;
159 filterMsg << "(";
160 for (std::size_t i = 0; i < filters.size(); i++) {
161 filterMsg << filters.at(i)->GetFilterMsg();
162 if (i < filters.size() - 1) {
163 filterMsg << "&&";
164 }
165 }
166 filterMsg << ")";
167 return filterMsg.str();
168 }
169
170 OrWifiFilter::~OrWifiFilter() = default;
171
Filter(NetworkCandidate & networkCandidate)172 bool OrWifiFilter::Filter(NetworkCandidate &networkCandidate)
173 {
174 return std::any_of(filters.begin(), filters.end(), [&networkCandidate](auto filter) {
175 return filter->DoFilter(networkCandidate);
176 });
177 }
178
GetFilterMsg()179 std::string OrWifiFilter::GetFilterMsg()
180 {
181 std::stringstream filterMsg;
182 filterMsg << "(";
183 for (std::size_t i = 0; i < filters.size(); i++) {
184 filterMsg << filters.at(i)->GetFilterMsg();
185 if (i < filters.size() - 1) {
186 filterMsg << "||";
187 }
188 }
189 filterMsg << ")";
190 return filterMsg.str();
191 }
192
SimpleWifiScorer(const std::string & scorerName)193 SimpleWifiScorer::SimpleWifiScorer(const std::string &scorerName) : IWifiScorer(), m_scoreName(scorerName) {}
194
195 SimpleWifiScorer::~SimpleWifiScorer() = default;
196
DoScore(NetworkCandidate & networkCandidate,ScoreResult & scoreResult)197 void SimpleWifiScorer::DoScore(NetworkCandidate &networkCandidate, ScoreResult &scoreResult)
198 {
199 scoreResult.scorerName = m_scoreName;
200 scoreResult.score = Score(networkCandidate);
201 }
202
CompositeWifiScorer(const std::string & scorerName)203 CompositeWifiScorer::CompositeWifiScorer(const std::string &scorerName) : IWifiScorer(), m_scoreName(scorerName) {}
204
205 CompositeWifiScorer::~CompositeWifiScorer() = default;
206
AddScorer(const std::shared_ptr<IWifiScorer> & scorer)207 void CompositeWifiScorer::AddScorer(const std::shared_ptr<IWifiScorer> &scorer)
208 {
209 if (scorer) {
210 scorers.emplace_back(scorer);
211 }
212 }
213
DoScore(NetworkCandidate & networkCandidate,ScoreResult & scoreResult)214 void CompositeWifiScorer::DoScore(NetworkCandidate &networkCandidate,
215 ScoreResult &scoreResult)
216 {
217 scoreResult.scorerName = m_scoreName;
218 for (auto &score : scorers) {
219 if (score) {
220 ScoreResult subScoreResult;
221 score->DoScore(networkCandidate, subScoreResult);
222 scoreResult.scoreDetails.emplace_back(subScoreResult);
223 scoreResult.score += subScoreResult.score;
224 }
225 }
226 }
227
WifiFunctionScorerAdapter(const std::function<double (NetworkCandidate &)> & scorer,const std::string & scorerName)228 WifiFunctionScorerAdapter::WifiFunctionScorerAdapter(const std::function<double(NetworkCandidate &)> &scorer,
229 const std::string &scorerName)
230 :SimpleWifiScorer(scorerName), targetFunction(scorer) {}
231
232 WifiFunctionScorerAdapter::~WifiFunctionScorerAdapter() = default;
233
Score(NetworkCandidate & networkCandidate)234 double WifiFunctionScorerAdapter::Score(NetworkCandidate &networkCandidate)
235 {
236 return targetFunction.operator()(networkCandidate);
237 }
238
NetworkSelector(const std::string & networkSelectorName)239 NetworkSelector::NetworkSelector(const std::string &networkSelectorName) : m_networkSelectorName(networkSelectorName) {}
240
241 NetworkSelector::~NetworkSelector() = default;
242
SetWifiComparator(const std::shared_ptr<IWifiComparator> & networkSelectorComparator)243 void NetworkSelector::SetWifiComparator(const std::shared_ptr<IWifiComparator> &networkSelectorComparator)
244 {
245 comparator = networkSelectorComparator;
246 }
247
SetWifiFilter(const std::shared_ptr<IWifiFilter> & networkSelectorFilter)248 void NetworkSelector::SetWifiFilter(const std::shared_ptr<IWifiFilter> &networkSelectorFilter)
249 {
250 filter = networkSelectorFilter;
251 }
252
TryNominate(NetworkCandidate & networkCandidate)253 bool NetworkSelector::TryNominate(NetworkCandidate &networkCandidate)
254 {
255 bool ret = false;
256 if (DoFilter(networkCandidate)) {
257 ret = Nominate(networkCandidate);
258 }
259 return ret;
260 }
261
DoFilter(NetworkCandidate & networkCandidate)262 bool NetworkSelector::DoFilter(NetworkCandidate &networkCandidate)
263 {
264 return !filter || filter->DoFilter(networkCandidate);
265 }
266
GetBestCandidatesByComparator(std::vector<NetworkCandidate * > & selectedNetworkCandidates)267 void NetworkSelector::GetBestCandidatesByComparator(std::vector<NetworkCandidate *> &selectedNetworkCandidates)
268 {
269 if (comparator) {
270 comparator->GetBestCandidates(networkCandidates, selectedNetworkCandidates);
271 } else {
272 selectedNetworkCandidates.insert(selectedNetworkCandidates.end(),
273 networkCandidates.begin(),
274 networkCandidates.end());
275 }
276 }
277
SimpleNetworkSelector(const std::string & networkSelectorName)278 SimpleNetworkSelector::SimpleNetworkSelector(const std::string &networkSelectorName)
279 : NetworkSelector(networkSelectorName) {}
280
281 SimpleNetworkSelector::~SimpleNetworkSelector() = default;
282
Nominate(NetworkCandidate & networkCandidate)283 bool SimpleNetworkSelector::Nominate(NetworkCandidate &networkCandidate)
284 {
285 networkCandidates.emplace_back(&networkCandidate);
286 return true;
287 }
288
GetNetworkSelectorMsg()289 std::string SimpleNetworkSelector::GetNetworkSelectorMsg()
290 {
291 std::stringstream networkSelectorMsg;
292 networkSelectorMsg << R"({ "name": ")" << m_networkSelectorName << "\" ";
293 if (filter) {
294 networkSelectorMsg << R"(,"filter": ")" << filter->GetFilterMsg() << "\"";
295 }
296 networkSelectorMsg << "}";
297 return networkSelectorMsg.str();
298 }
299
GetBestCandidates(std::vector<NetworkCandidate * > & selectedNetworkCandidates)300 void SimpleNetworkSelector::GetBestCandidates(std::vector<NetworkCandidate *> &selectedNetworkCandidates)
301 {
302 GetBestCandidatesByComparator(selectedNetworkCandidates);
303 }
304
CompositeNetworkSelector(const std::string & networkSelectorName)305 CompositeNetworkSelector::CompositeNetworkSelector(const std::string &networkSelectorName) : NetworkSelector(
306 networkSelectorName) {}
307
308 CompositeNetworkSelector::~CompositeNetworkSelector() = default;
309
AddSubNetworkSelector(const std::shared_ptr<INetworkSelector> & subNetworkSelector)310 void CompositeNetworkSelector::AddSubNetworkSelector(const std::shared_ptr<INetworkSelector> &subNetworkSelector)
311 {
312 if (subNetworkSelector) {
313 subNetworkSelectors.emplace_back(subNetworkSelector);
314 }
315 }
316
GetBestCandidates(std::vector<NetworkCandidate * > & selectedNetworkCandidates)317 void CompositeNetworkSelector::GetBestCandidates(std::vector<NetworkCandidate *> &selectedNetworkCandidates)
318 {
319 GetCandidatesFromSubNetworkSelector();
320 GetBestCandidatesByComparator(selectedNetworkCandidates);
321 }
322
GetNetworkSelectorMsg()323 std::string CompositeNetworkSelector::GetNetworkSelectorMsg()
324 {
325 std::stringstream networkSelectorMsg;
326 networkSelectorMsg << R"({ "name": ")" << m_networkSelectorName << "\" ";
327 if (filter) {
328 networkSelectorMsg << R"(,"filter": ")" << filter->GetFilterMsg() << "\"";
329 }
330 if (!subNetworkSelectors.empty()) {
331 networkSelectorMsg << R"(,"subNetworkSelectors": [)";
332 for (std::size_t i = 0; i < subNetworkSelectors.size(); i++) {
333 networkSelectorMsg << subNetworkSelectors.at(i)->GetNetworkSelectorMsg();
334 if (i < subNetworkSelectors.size() - 1) {
335 networkSelectorMsg << ",";
336 }
337 }
338 networkSelectorMsg << "]";
339 }
340 networkSelectorMsg << "}";
341 return networkSelectorMsg.str();
342 }
343 }