1 /*
2 * Copyright (c) 2021-2024 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 <atomic>
17 #include <cinttypes>
18
19 #include "broadcast_manager.h"
20 #include "net_manager_constants.h"
21 #include "net_mgr_log_wrapper.h"
22 #include "net_supplier.h"
23
24 namespace OHOS {
25 namespace NetManagerStandard {
26 namespace {
27 constexpr int32_t REG_OK = 0;
28 constexpr const char *SIMID_IDENT_PREFIX = "simId";
29 }
30 static std::atomic<uint32_t> g_nextNetSupplierId = 0x03EB;
31
NetSupplier(NetBearType bearerType,const std::string & netSupplierIdent,const std::set<NetCap> & netCaps)32 NetSupplier::NetSupplier(NetBearType bearerType, const std::string &netSupplierIdent, const std::set<NetCap> &netCaps)
33 : netSupplierType_(bearerType),
34 netSupplierIdent_(netSupplierIdent),
35 netCaps_(netCaps),
36 supplierId_(g_nextNetSupplierId++)
37 {
38 netAllCapabilities_.netCaps_ = netCaps;
39 netAllCapabilities_.bearerTypes_.insert(bearerType);
40 ResetNetSupplier();
41 InitNetScore();
42 }
43
GetSupplierCallback()44 sptr<INetSupplierCallback> NetSupplier::GetSupplierCallback()
45 {
46 return netController_;
47 }
48
RegisterSupplierCallback(const sptr<INetSupplierCallback> & callback)49 void NetSupplier::RegisterSupplierCallback(const sptr<INetSupplierCallback> &callback)
50 {
51 netController_ = callback;
52 }
53
InitNetScore()54 void NetSupplier::InitNetScore()
55 {
56 int32_t netScore = 0;
57 auto iter = netTypeScore_.find(netSupplierType_);
58 if (iter == netTypeScore_.end()) {
59 NETMGR_LOG_E("Can not find net bearer type[%{public}d] for this net service", netSupplierType_);
60 return;
61 }
62 NETMGR_LOG_D("Net type[%{public}d],default score[%{public}d]",
63 static_cast<int32_t>(iter->first), static_cast<int32_t>(iter->second));
64 netScore = static_cast<int32_t>(iter->second);
65 netScore_ = netScore;
66 NETMGR_LOG_D("netScore_ = %{public}d", netScore_);
67 }
68
69 /**
70 * Reset all attributes that may change in the supplier, such as detection progress and network quality.
71 */
ResetNetSupplier()72 void NetSupplier::ResetNetSupplier()
73 {
74 // Reset network quality.
75 netQuality_ = QUALITY_NORMAL_STATE;
76 // Reset network detection progress.
77 isFirstTimeDetectionDone = false;
78 //Reset User Selection
79 isAcceptUnvaliad = false;
80 // Reset network capabilities for checking connectivity finished flag.
81 netCaps_.InsertNetCap(NET_CAPABILITY_CHECKING_CONNECTIVITY);
82 netAllCapabilities_.netCaps_.insert(NET_CAPABILITY_CHECKING_CONNECTIVITY);
83 NETMGR_LOG_I("Reset net supplier %{public}u", supplierId_);
84 }
85
operator ==(const NetSupplier & netSupplier) const86 bool NetSupplier::operator==(const NetSupplier &netSupplier) const
87 {
88 return supplierId_ == netSupplier.supplierId_ && netSupplierType_ == netSupplier.netSupplierType_ &&
89 netSupplierIdent_ == netSupplier.netSupplierIdent_ && netCaps_ == netSupplier.netCaps_;
90 }
91
UpdateNetSupplierInfo(const NetSupplierInfo & netSupplierInfo)92 void NetSupplier::UpdateNetSupplierInfo(const NetSupplierInfo &netSupplierInfo)
93 {
94 NETMGR_LOG_D("Update net supplier[%{public}d, %{public}s], netSupplierInfo[%{public}s]", supplierId_,
95 netSupplierIdent_.c_str(), netSupplierInfo_.ToString("").c_str());
96 bool oldAvailable = netSupplierInfo_.isAvailable_;
97 netSupplierInfo_ = netSupplierInfo;
98 netAllCapabilities_.linkUpBandwidthKbps_ = netSupplierInfo_.linkUpBandwidthKbps_;
99 netAllCapabilities_.linkDownBandwidthKbps_ = netSupplierInfo_.linkDownBandwidthKbps_;
100 if (!netSupplierInfo_.ident_.empty()) {
101 netSupplierIdent_ = netSupplierInfo_.ident_;
102 }
103 if (oldAvailable == netSupplierInfo_.isAvailable_) {
104 NETMGR_LOG_W("Same supplier available status:[%{public}d]", oldAvailable);
105 return;
106 }
107 if (network_ == nullptr) {
108 NETMGR_LOG_E("network_ is nullptr!");
109 return;
110 }
111 network_->UpdateBasicNetwork(netSupplierInfo_.isAvailable_);
112 if (!netSupplierInfo_.isAvailable_) {
113 UpdateNetConnState(NET_CONN_STATE_DISCONNECTED);
114 }
115 }
116
UpdateNetLinkInfo(NetLinkInfo & netLinkInfo)117 int32_t NetSupplier::UpdateNetLinkInfo(NetLinkInfo &netLinkInfo)
118 {
119 if (network_ == nullptr) {
120 NETMGR_LOG_E("network_ is nullptr!");
121 return NET_CONN_ERR_INVALID_NETWORK;
122 }
123
124 if (GetNetSupplierIdent().substr(0, strlen(SIMID_IDENT_PREFIX)) == SIMID_IDENT_PREFIX) {
125 netLinkInfo.ident_ = GetNetSupplierIdent().substr(strlen(SIMID_IDENT_PREFIX));
126 }
127 NETMGR_LOG_D("Update netlink info: netLinkInfo[%{public}s]", netLinkInfo.ToString(" ").c_str());
128 if (!network_->UpdateNetLinkInfo(netLinkInfo)) {
129 return NET_CONN_ERR_SERVICE_UPDATE_NET_LINK_INFO_FAIL;
130 }
131 UpdateNetConnState(NET_CONN_STATE_CONNECTED);
132 return NETMANAGER_SUCCESS;
133 }
134
GetNetSupplierType() const135 NetBearType NetSupplier::GetNetSupplierType() const
136 {
137 return netSupplierType_;
138 }
139
GetNetSupplierIdent() const140 std::string NetSupplier::GetNetSupplierIdent() const
141 {
142 return netSupplierIdent_;
143 }
144
CompareNetCaps(const std::set<NetCap> caps) const145 bool NetSupplier::CompareNetCaps(const std::set<NetCap> caps) const
146 {
147 if (caps.empty()) {
148 return true;
149 }
150 return netCaps_.HasNetCaps(caps);
151 }
152
HasNetCap(NetCap cap) const153 bool NetSupplier::HasNetCap(NetCap cap) const
154 {
155 return netCaps_.HasNetCap(cap);
156 }
157
HasNetCaps(const std::set<NetCap> & caps) const158 bool NetSupplier::HasNetCaps(const std::set<NetCap> &caps) const
159 {
160 return netCaps_.HasNetCaps(caps);
161 }
162
GetNetCaps() const163 const NetCaps &NetSupplier::GetNetCaps() const
164 {
165 return netCaps_;
166 }
167
GetNetCapabilities() const168 NetAllCapabilities NetSupplier::GetNetCapabilities() const
169 {
170 return netAllCapabilities_;
171 }
172
SetNetwork(const std::shared_ptr<Network> & network)173 void NetSupplier::SetNetwork(const std::shared_ptr<Network> &network)
174 {
175 network_ = network;
176 if (network_ != nullptr) {
177 netHandle_ = std::make_unique<NetHandle>(network_->GetNetId()).release();
178 }
179 }
180
GetNetwork() const181 std::shared_ptr<Network> NetSupplier::GetNetwork() const
182 {
183 return network_;
184 }
185
GetNetId() const186 int32_t NetSupplier::GetNetId() const
187 {
188 if (network_ == nullptr) {
189 return INVALID_NET_ID;
190 }
191 return network_->GetNetId();
192 }
193
GetNetHandle() const194 sptr<NetHandle> NetSupplier::GetNetHandle() const
195 {
196 return netHandle_;
197 }
198
GetHttpProxy(HttpProxy & httpProxy)199 void NetSupplier::GetHttpProxy(HttpProxy &httpProxy)
200 {
201 if (network_ == nullptr) {
202 NETMGR_LOG_E("network_ is nullptr.");
203 return;
204 }
205 httpProxy = network_->GetHttpProxy();
206 }
207
GetSupplierId() const208 uint32_t NetSupplier::GetSupplierId() const
209 {
210 return supplierId_;
211 }
212
GetRoaming() const213 bool NetSupplier::GetRoaming() const
214 {
215 return netSupplierInfo_.isRoaming_;
216 }
217
GetStrength() const218 int8_t NetSupplier::GetStrength() const
219 {
220 return netSupplierInfo_.strength_;
221 }
222
GetFrequency() const223 uint16_t NetSupplier::GetFrequency() const
224 {
225 return netSupplierInfo_.frequency_;
226 }
227
GetSupplierUid() const228 int32_t NetSupplier::GetSupplierUid() const
229 {
230 return netSupplierInfo_.uid_;
231 }
232
IsAvailable() const233 bool NetSupplier::IsAvailable() const
234 {
235 return netSupplierInfo_.isAvailable_;
236 }
237
SupplierConnection(const std::set<NetCap> & netCaps,const NetRequest & netRequest)238 bool NetSupplier::SupplierConnection(const std::set<NetCap> &netCaps, const NetRequest &netRequest)
239 {
240 NETMGR_LOG_D("Supplier[%{public}d, %{public}s] request connect, available=%{public}d", supplierId_,
241 netSupplierIdent_.c_str(), netSupplierInfo_.isAvailable_);
242 if (netSupplierInfo_.isAvailable_ && (netRequest.ident.empty()) &&
243 netSupplierIdent_.substr(0, strlen(SIMID_IDENT_PREFIX)) != SIMID_IDENT_PREFIX) {
244 NETMGR_LOG_D("The supplier is currently available, there is no need to repeat the request for connection.");
245 return true;
246 }
247 UpdateNetConnState(NET_CONN_STATE_IDLE);
248
249 if (netController_ == nullptr) {
250 NETMGR_LOG_E("netController_ is nullptr");
251 return false;
252 }
253 NETMGR_LOG_D("execute RequestNetwork");
254 int32_t errCode = netController_->RequestNetwork(netSupplierIdent_, netCaps, netRequest);
255 NETMGR_LOG_D("RequestNetwork errCode[%{public}d]", errCode);
256 if (errCode != REG_OK) {
257 NETMGR_LOG_E("RequestNetwork fail");
258 return false;
259 }
260 return true;
261 }
262
SetRestrictBackground(bool restrictBackground)263 void NetSupplier::SetRestrictBackground(bool restrictBackground)
264 {
265 restrictBackground_ = restrictBackground;
266 }
GetRestrictBackground() const267 bool NetSupplier::GetRestrictBackground() const
268 {
269 return restrictBackground_;
270 }
271
SupplierDisconnection(const std::set<NetCap> & netCaps)272 bool NetSupplier::SupplierDisconnection(const std::set<NetCap> &netCaps)
273 {
274 NETMGR_LOG_D("Supplier[%{public}d, %{public}s] request disconnect, available=%{public}d", supplierId_,
275 netSupplierIdent_.c_str(), netSupplierInfo_.isAvailable_);
276 if (!netSupplierInfo_.isAvailable_ &&
277 netSupplierIdent_.substr(0, strlen(SIMID_IDENT_PREFIX)) != SIMID_IDENT_PREFIX) {
278 NETMGR_LOG_D("The supplier is currently unavailable, there is no need to repeat the request to disconnect.");
279 return true;
280 }
281 if (netController_ == nullptr) {
282 NETMGR_LOG_E("netController_ is nullptr");
283 return false;
284 }
285 NETMGR_LOG_D("execute ReleaseNetwork, supplierId[%{public}d]", supplierId_);
286 int32_t errCode = netController_->ReleaseNetwork(netSupplierIdent_, netCaps);
287 NETMGR_LOG_D("ReleaseNetwork retCode[%{public}d]", errCode);
288 if (errCode != REG_OK) {
289 NETMGR_LOG_E("ReleaseNetwork fail");
290 return false;
291 }
292 return true;
293 }
294
UpdateNetConnState(NetConnState netConnState)295 void NetSupplier::UpdateNetConnState(NetConnState netConnState)
296 {
297 if (network_) {
298 network_->UpdateNetConnState(netConnState);
299 }
300 }
301
IsConnecting() const302 bool NetSupplier::IsConnecting() const
303 {
304 if (network_) {
305 return network_->IsConnecting();
306 }
307 return false;
308 }
309
IsConnected() const310 bool NetSupplier::IsConnected() const
311 {
312 if (network_) {
313 return network_->IsConnected();
314 }
315 return false;
316 }
317
RequestToConnect(uint32_t reqId,const NetRequest & netrequest)318 bool NetSupplier::RequestToConnect(uint32_t reqId, const NetRequest &netrequest)
319 {
320 if (requestList_.find(reqId) == requestList_.end()) {
321 requestList_.insert(reqId);
322 }
323 return SupplierConnection(netCaps_.ToSet(), netrequest);
324 }
325
SelectAsBestNetwork(uint32_t reqId)326 int32_t NetSupplier::SelectAsBestNetwork(uint32_t reqId)
327 {
328 NETMGR_LOG_I("Request[%{public}d] select [%{public}d, %{public}s] as best network", reqId, supplierId_,
329 netSupplierIdent_.c_str());
330 if (requestList_.find(reqId) == requestList_.end()) {
331 requestList_.insert(reqId);
332 }
333 if (bestReqList_.find(reqId) == bestReqList_.end()) {
334 bestReqList_.insert(reqId);
335 }
336 return NETMANAGER_SUCCESS;
337 }
338
ReceiveBestScore(uint32_t reqId,int32_t bestScore,uint32_t supplierId)339 void NetSupplier::ReceiveBestScore(uint32_t reqId, int32_t bestScore, uint32_t supplierId)
340 {
341 NETMGR_LOG_D("Supplier[%{public}d, %{public}s] receive best score, bestSupplierId[%{public}d]", supplierId_,
342 netSupplierIdent_.c_str(), supplierId);
343 if (supplierId == supplierId_) {
344 NETMGR_LOG_D("Same net supplier, no need to disconnect.");
345 return;
346 }
347 if (requestList_.empty()) {
348 SupplierDisconnection(netCaps_.ToSet());
349 return;
350 }
351 if (requestList_.find(reqId) == requestList_.end()) {
352 NETMGR_LOG_W("Can not find request[%{public}d]", reqId);
353 return;
354 }
355 if (netScore_ >= bestScore) {
356 NETMGR_LOG_D("High priority network, no need to disconnect");
357 return;
358 }
359 requestList_.erase(reqId);
360 NETMGR_LOG_D("Supplier[%{public}d, %{public}s] remaining request list size[%{public}zd]", supplierId_,
361 netSupplierIdent_.c_str(), requestList_.size());
362 if (requestList_.empty()) {
363 SupplierDisconnection(netCaps_.ToSet());
364 }
365 bestReqList_.erase(reqId);
366 }
367
CancelRequest(uint32_t reqId)368 int32_t NetSupplier::CancelRequest(uint32_t reqId)
369 {
370 auto iter = requestList_.find(reqId);
371 if (iter == requestList_.end()) {
372 return NET_CONN_ERR_SERVICE_NO_REQUEST;
373 }
374 NETMGR_LOG_I("CancelRequest reqId:%{public}u", reqId);
375 requestList_.erase(reqId);
376 if (requestList_.empty()) {
377 SupplierDisconnection(netCaps_.ToSet());
378 }
379 bestReqList_.erase(reqId);
380 return NETMANAGER_SUCCESS;
381 }
382
RemoveBestRequest(uint32_t reqId)383 void NetSupplier::RemoveBestRequest(uint32_t reqId)
384 {
385 auto iter = bestReqList_.find(reqId);
386 if (iter == bestReqList_.end()) {
387 return;
388 }
389 bestReqList_.erase(reqId);
390 NETMGR_LOG_I("RemoveBestRequest supplierId=[%{public}d], reqId=[%{public}u]", supplierId_, reqId);
391 }
392
GetBestRequestList()393 std::set<uint32_t> &NetSupplier::GetBestRequestList()
394 {
395 return bestReqList_;
396 }
397
SetNetValid(NetDetectionStatus netState)398 void NetSupplier::SetNetValid(NetDetectionStatus netState)
399 {
400 NETMGR_LOG_I("Enter SetNetValid. supplier[%{public}d, %{public}s], ifValid[%{public}d]", supplierId_,
401 netSupplierIdent_.c_str(), netState);
402 if (netState == VERIFICATION_STATE) {
403 if (!HasNetCap(NET_CAPABILITY_VALIDATED)) {
404 netCaps_.InsertNetCap(NET_CAPABILITY_VALIDATED);
405 netAllCapabilities_.netCaps_.insert(NET_CAPABILITY_VALIDATED);
406 NETMGR_LOG_I("NetSupplier inserted cap:NET_CAPABILITY_VALIDATED");
407 }
408 if (HasNetCap(NET_CAPABILITY_PORTAL)) {
409 netCaps_.RemoveNetCap(NET_CAPABILITY_PORTAL);
410 netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_PORTAL);
411 NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_PORTAL");
412 }
413 } else if (netState == CAPTIVE_PORTAL_STATE) {
414 if (!HasNetCap(NET_CAPABILITY_PORTAL)) {
415 netCaps_.InsertNetCap(NET_CAPABILITY_PORTAL);
416 netAllCapabilities_.netCaps_.insert(NET_CAPABILITY_PORTAL);
417 NETMGR_LOG_I("NetSupplier inserted cap:NET_CAPABILITY_PORTAL");
418 }
419 if (HasNetCap(NET_CAPABILITY_VALIDATED)) {
420 netCaps_.RemoveNetCap(NET_CAPABILITY_VALIDATED);
421 netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_VALIDATED);
422 NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_VALIDATED");
423 }
424 } else if (netState == QUALITY_POOR_STATE) {
425 netQuality_ = QUALITY_POOR_STATE;
426 } else if (netState == QUALITY_GOOD_STATE) {
427 netQuality_ = QUALITY_GOOD_STATE;
428 } else if (netState == ACCEPT_UNVALIDATED) {
429 netQuality_ = ACCEPT_UNVALIDATED;
430 isAcceptUnvaliad = true;
431 } else {
432 if (HasNetCap(NET_CAPABILITY_VALIDATED)) {
433 netCaps_.RemoveNetCap(NET_CAPABILITY_VALIDATED);
434 netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_VALIDATED);
435 NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_VALIDATED");
436 }
437 if (HasNetCap(NET_CAPABILITY_PORTAL)) {
438 netCaps_.RemoveNetCap(NET_CAPABILITY_PORTAL);
439 netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_PORTAL);
440 NETMGR_LOG_I("NetSupplier remove cap:NET_CAPABILITY_PORTAL");
441 }
442 }
443 }
444
IsNetValidated() const445 bool NetSupplier::IsNetValidated() const
446 {
447 return HasNetCap(NET_CAPABILITY_VALIDATED);
448 }
449
450 /**
451 * This method returns the score of the current network supplier.
452 *
453 * It is used to prioritize network suppliers so that higher priority producers can activate when lower
454 * priority networks are available.
455 *
456 * @return the score of the current network supplier.
457 */
GetNetScore() const458 int32_t NetSupplier::GetNetScore() const
459 {
460 return netScore_;
461 }
462
463 /**
464 * This method returns the real score of current network supplier.
465 *
466 * This method subtracts the score depending on different conditions, or returns netScore_ if the conditions are not
467 * met.
468 * It is used to compare the priorities of different networks.
469 *
470 * @return the real score of current network supplier.
471 */
GetRealScore()472 int32_t NetSupplier::GetRealScore()
473 {
474 // Notice: the order is important here:
475 // 1.If the user chooses to use this network, return MAX_SCORE
476 if (isAcceptUnvaliad) {
477 return static_cast<int32_t>(NetManagerStandard::NetTypeScoreValue::MAX_SCORE);
478 }
479
480 // 2. If network detection is not complete in the first time, subtract NET_VALID_SCORE.
481 if (IsInFirstTimeDetecting()) {
482 return netScore_ - NET_VALID_SCORE;
483 }
484
485 // 3. If network is not validated, subtract NET_VALID_SCORE.
486 if (!IsNetValidated()) {
487 return netScore_ - NET_VALID_SCORE;
488 }
489
490 // 4. Deduct DIFF_SCORE_BETWEEN_GOOD_POOR for poor network quality (reported by the supplier).
491 if (IsNetQualityPoor()) {
492 return netScore_ - DIFF_SCORE_BETWEEN_GOOD_POOR;
493 }
494 return netScore_;
495 }
496
SetDefault()497 void NetSupplier::SetDefault()
498 {
499 NETMGR_LOG_I("set default supplier[%{public}d].", supplierId_);
500 if (network_) {
501 network_->SetDefaultNetWork();
502 }
503 }
504
ClearDefault()505 void NetSupplier::ClearDefault()
506 {
507 NETMGR_LOG_I("clear default supplier[%{public}d].", supplierId_);
508 if (network_) {
509 network_->ClearDefaultNetWorkNetId();
510 }
511 }
512
UpdateGlobalHttpProxy(const HttpProxy & httpProxy)513 void NetSupplier::UpdateGlobalHttpProxy(const HttpProxy &httpProxy)
514 {
515 NETMGR_LOG_I("supplierId[%{public}d] update global httpProxy.", supplierId_);
516 if (network_) {
517 network_->UpdateGlobalHttpProxy(httpProxy);
518 }
519 }
520
TechToType(NetSlotTech techType)521 std::string NetSupplier::TechToType(NetSlotTech techType)
522 {
523 switch (techType) {
524 case NetSlotTech::SLOT_TYPE_GSM:
525 return "2G";
526 case NetSlotTech::SLOT_TYPE_LTE:
527 case NetSlotTech::SLOT_TYPE_LTE_CA:
528 return "4G";
529 default:
530 return "3G";
531 }
532 }
533
SetSupplierType(int32_t type)534 void NetSupplier::SetSupplierType(int32_t type)
535 {
536 NETMGR_LOG_I("supplierId[%{public}d] update type[%{public}d].", supplierId_, type);
537 type_ = TechToType(static_cast<NetSlotTech>(type));
538 }
539
GetSupplierType()540 std::string NetSupplier::GetSupplierType()
541 {
542 return type_;
543 }
544
ResumeNetworkInfo()545 bool NetSupplier::ResumeNetworkInfo()
546 {
547 if (network_ == nullptr) {
548 NETMGR_LOG_E("network_ is nullptr!");
549 return false;
550 }
551
552 return network_->ResumeNetworkInfo();
553 }
554
IsNetQualityPoor()555 bool NetSupplier::IsNetQualityPoor()
556 {
557 return netQuality_ == QUALITY_POOR_STATE;
558 }
559
SetDetectionDone()560 void NetSupplier::SetDetectionDone()
561 {
562 if (!isFirstTimeDetectionDone) {
563 isFirstTimeDetectionDone = true;
564 }
565 if (HasNetCap(NET_CAPABILITY_CHECKING_CONNECTIVITY)) {
566 netCaps_.RemoveNetCap(NET_CAPABILITY_CHECKING_CONNECTIVITY);
567 netAllCapabilities_.netCaps_.erase(NET_CAPABILITY_CHECKING_CONNECTIVITY);
568 NETMGR_LOG_I("supplier %{public}u detection done, remove NET_CAPABILITY_CHECKING_CONNECTIVITY", supplierId_);
569 }
570 }
571
IsInFirstTimeDetecting() const572 bool NetSupplier::IsInFirstTimeDetecting() const
573 {
574 return !isFirstTimeDetectionDone;
575 }
576 } // namespace NetManagerStandard
577 } // namespace OHOS
578