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 }