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