1 /*
2 * Copyright (c) 2021-2022 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 "net_policy_traffic.h"
17
18 #include "broadcast_manager.h"
19 #include "common_event_data.h"
20 #include "common_event_manager.h"
21 #include "common_event_publish_info.h"
22 #include "common_event_support.h"
23 #include "system_ability_definition.h"
24
25 #include "net_manager_center.h"
26 #include "net_mgr_log_wrapper.h"
27 #include "net_policy_constants.h"
28 #include "net_policy_file.h"
29 #include "net_policy_inner_define.h"
30 #include "net_quota_policy.h"
31 #include "net_specifier.h"
32 #include "net_stats_info.h"
33 #include "netmanager_base_common_utils.h"
34 #include "netmanager_base_permission.h"
35
36 namespace OHOS {
37 namespace NetManagerStandard {
38 namespace {
39 constexpr const char *BROADCAST_QUOTA_WARNING = "Net Policy Quota Warning";
40 constexpr const char *BROADCAST_QUOTA_LIMIT_REMIND = "Net Policy Quota Limit Remind";
41 constexpr const char *BROADCAST_QUOTA_LIMIT = "Net Policy Quota Limit";
42 } // namespace
43
Init()44 void NetPolicyTraffic::Init()
45 {
46 netsysCallback_ = new (std::nothrow)
47 NetsysControllerCallbackImpl((std::static_pointer_cast<NetPolicyTraffic>(shared_from_this())));
48 if (netsysCallback_ != nullptr) {
49 GetNetsysInst()->RegisterNetsysCallback(netsysCallback_);
50 }
51
52 ReadQuotaPolicies();
53 }
54
IsValidQuotaPolicy(const NetQuotaPolicy & quotaPolicy)55 bool NetPolicyTraffic::IsValidQuotaPolicy(const NetQuotaPolicy "aPolicy)
56 {
57 int32_t netType = quotaPolicy.netType;
58 if (!IsValidNetType(netType)) {
59 NETMGR_LOG_E("NetPolicyType is invalid policy[%{public}d]", netType);
60 return false;
61 }
62
63 if (!IsValidPeriodDuration(quotaPolicy.periodDuration)) {
64 NETMGR_LOG_E("periodDuration [%{public}s] must Mx", quotaPolicy.periodDuration.c_str());
65 return false;
66 }
67 return true;
68 }
69
IsValidNetType(int32_t netType)70 bool NetPolicyTraffic::IsValidNetType(int32_t netType)
71 {
72 switch (netType) {
73 case NetBearType::BEARER_CELLULAR:
74 case NetBearType::BEARER_WIFI:
75 case NetBearType::BEARER_BLUETOOTH:
76 case NetBearType::BEARER_ETHERNET:
77 case NetBearType::BEARER_VPN:
78 case NetBearType::BEARER_WIFI_AWARE: {
79 return true;
80 }
81 default: {
82 NETMGR_LOG_E("Invalid netType [%{public}d]", netType);
83 return false;
84 }
85 }
86 }
87
IsValidNetRemindType(uint32_t remindType)88 bool NetPolicyTraffic::IsValidNetRemindType(uint32_t remindType)
89 {
90 switch (remindType) {
91 case RemindType::REMIND_TYPE_WARNING:
92 case RemindType::REMIND_TYPE_LIMIT: {
93 return true;
94 }
95 default: {
96 NETMGR_LOG_E("Invalid remindType [%{public}d]", remindType);
97 return false;
98 }
99 }
100 }
101
UpdateQuotaPolicies(const std::vector<NetQuotaPolicy> & quotaPolicies)102 int32_t NetPolicyTraffic::UpdateQuotaPolicies(const std::vector<NetQuotaPolicy> "aPolicies)
103 {
104 if (quotaPolicies.empty()) {
105 NETMGR_LOG_E("SetNetQuotaPolicies size is empty");
106 return POLICY_ERR_INVALID_QUOTA_POLICY;
107 }
108 // formalize the quota policy
109 NetmanagerHiTrace::NetmanagerStartSyncTrace("FormalizeQuotaPolicies quotaPolicies start");
110 FormalizeQuotaPolicies(quotaPolicies);
111 NetmanagerHiTrace::NetmanagerFinishSyncTrace("FormalizeQuotaPolicies quotaPolicies end");
112 return UpdateQuotaPoliciesInner();
113 }
114
UpdateQuotaPoliciesInner()115 int32_t NetPolicyTraffic::UpdateQuotaPoliciesInner()
116 {
117 // calculate the quota remain and get the metered ifaces
118 NetmanagerHiTrace::NetmanagerStartSyncTrace("UpdateMeteredIfacesQuota start");
119 auto meteredIfaces = UpdateMeteredIfacesQuota();
120 NetmanagerHiTrace::NetmanagerFinishSyncTrace("UpdateMeteredIfacesQuota end");
121
122 // update the metered ifaces and notify the changes.
123 NetmanagerHiTrace::NetmanagerStartSyncTrace("UpdateMeteredIfaces meteredIfaces start");
124 UpdateMeteredIfaces(meteredIfaces);
125 NetmanagerHiTrace::NetmanagerFinishSyncTrace("UpdateMeteredIfaces meteredIfaces end");
126
127 // notify quota limit or warning.
128 NetmanagerHiTrace::NetmanagerStartSyncTrace("UpdateQuotaNotify start");
129 UpdateQuotaNotify();
130 NetmanagerHiTrace::NetmanagerFinishSyncTrace("UpdateQuotaNotify end");
131 // write quota policies to file.
132 if (!WriteQuotaPolicies()) {
133 NETMGR_LOG_E("UpdateQuotaPolicies WriteFile failed");
134 return NETMANAGER_ERR_WRITE_DATA_FAIL;
135 }
136 // notify the the quota policy change.
137 GetCbInst()->NotifyNetQuotaPolicyChange(quotaPolicies_);
138 return NETMANAGER_SUCCESS;
139 }
140
FormalizeQuotaPolicies(const std::vector<NetQuotaPolicy> & quotaPolicies)141 void NetPolicyTraffic::FormalizeQuotaPolicies(const std::vector<NetQuotaPolicy> "aPolicies)
142 {
143 quotaPolicies_.clear();
144 for (auto quotaPolicy : quotaPolicies) {
145 if (!IsValidQuotaPolicy(quotaPolicy)) {
146 NETMGR_LOG_E("UpdateQuotaPolicies invalid quota policy netType[%{public}d], periodDuration[%{public}s]",
147 quotaPolicy.netType, quotaPolicy.periodDuration.c_str());
148 continue;
149 }
150 if (quotaPolicy.limitBytes == DATA_USAGE_UNKNOWN) {
151 quotaPolicy.limitAction = LIMIT_ACTION_AUTO_BILL;
152 } else if (quotaPolicy.warningBytes == DATA_USAGE_UNKNOWN) {
153 quotaPolicy.warningBytes = quotaPolicy.limitBytes * NINETY_PERCENTAGE / HUNDRED_PERCENTAGE;
154 }
155 if (quotaPolicy.limitAction == LIMIT_ACTION_AUTO_BILL) {
156 quotaPolicy.limitBytes = DATA_USAGE_UNLIMITED;
157 }
158 if (quotaPolicy.warningBytes > quotaPolicy.limitBytes) {
159 quotaPolicy.warningBytes = DATA_USAGE_UNLIMITED;
160 }
161 if (quotaPolicy.limitBytes == DATA_USAGE_UNLIMITED) {
162 quotaPolicy.limitAction = LIMIT_ACTION_AUTO_BILL;
163 }
164 quotaPolicies_.push_back(quotaPolicy);
165 }
166 }
167
UpdateMeteredIfacesQuota()168 const std::vector<std::string> NetPolicyTraffic::UpdateMeteredIfacesQuota()
169 {
170 std::vector<std::string> newMeteredIfaces;
171 for (auto "aPolicy : quotaPolicies_) {
172 std::string iface = GetMatchIfaces(quotaPolicy);
173 // set quota for metered iface.
174 if (iface == UNKNOW_IFACE || !quotaPolicy.metered) {
175 continue;
176 }
177 newMeteredIfaces.push_back(iface);
178 int64_t quotaRemain = GetQuotaRemain(quotaPolicy);
179 if (quotaRemain >= 0) {
180 GetNetsysInst()->BandwidthSetIfaceQuota(iface, quotaRemain);
181 }
182 }
183 // remove the iface quota that not metered.
184 for (uint32_t i = 0; i < meteredIfaces_.size(); ++i) {
185 if (!std::count(newMeteredIfaces.begin(), newMeteredIfaces.end(), meteredIfaces_[i])) {
186 GetNetsysInst()->BandwidthRemoveIfaceQuota(meteredIfaces_[i]);
187 }
188 }
189 return newMeteredIfaces;
190 }
191
UpdateMeteredIfaces(std::vector<std::string> & newMeteredIfaces)192 void NetPolicyTraffic::UpdateMeteredIfaces(std::vector<std::string> &newMeteredIfaces)
193 {
194 NETMGR_LOG_D("UpdateMeteredIfaces size[%{public}zu]", newMeteredIfaces.size());
195 meteredIfaces_.clear();
196 meteredIfaces_.reserve(newMeteredIfaces.size());
197 for (auto &iface : newMeteredIfaces) {
198 meteredIfaces_.push_back(iface);
199 }
200 // notify the callback of metered ifaces changed.
201 GetCbInst()->NotifyNetMeteredIfacesChange(meteredIfaces_);
202 }
203
UpdateQuotaNotify()204 void NetPolicyTraffic::UpdateQuotaNotify()
205 {
206 NetmanagerHiTrace::NetmanagerStartSyncTrace("Traverse cellular network start");
207 for (auto "aPolicy : quotaPolicies_) {
208 NetmanagerHiTrace::NetmanagerStartSyncTrace("Get the start time of the metering cycle start");
209 int64_t start = quotaPolicy.GetPeriodStart();
210 NetmanagerHiTrace::NetmanagerFinishSyncTrace("Get the start time of the metering cycle end");
211
212 NetmanagerHiTrace::NetmanagerStartSyncTrace("Get the usage of traffic start");
213 int64_t totalQuota = GetTotalQuota(quotaPolicy);
214 NetmanagerHiTrace::NetmanagerFinishSyncTrace("Get the usage of traffic end");
215 // check if the quota is over the limit
216 if (quotaPolicy.IsOverLimit(totalQuota)) {
217 if (quotaPolicy.lastLimitRemind > start) {
218 // notify the quota reach limit and has reminded before.
219 NetmanagerHiTrace::NetmanagerStartSyncTrace("Notify quota limit reminded start");
220 NotifyQuotaLimitReminded(totalQuota);
221 NetmanagerHiTrace::NetmanagerFinishSyncTrace("Notify quota limit reminded end");
222 continue;
223 }
224 NetmanagerHiTrace::NetmanagerStartSyncTrace("Update net enable status start");
225 UpdateNetEnableStatus(quotaPolicy);
226 NetmanagerHiTrace::NetmanagerFinishSyncTrace("Update net enable status end");
227 // notify the quota reach limit
228 NotifyQuotaLimit(totalQuota);
229 continue;
230 }
231 // check if the quota is over the warning
232 if (quotaPolicy.IsOverWarning(totalQuota) && quotaPolicy.lastWarningRemind < start) {
233 NetmanagerHiTrace::NetmanagerStartSyncTrace("Notify quota warning remind start");
234 NotifyQuotaWarning(totalQuota);
235 NetmanagerHiTrace::NetmanagerFinishSyncTrace("Notify quota warning remind end");
236 }
237 }
238 NetmanagerHiTrace::NetmanagerFinishSyncTrace("Traverse cellular network end");
239 }
240
GetQuotaRemain(NetQuotaPolicy & quotaPolicy)241 int64_t NetPolicyTraffic::GetQuotaRemain(NetQuotaPolicy "aPolicy)
242 {
243 int64_t start = quotaPolicy.GetPeriodStart();
244 int64_t totalQuota = GetTotalQuota(quotaPolicy);
245 NETMGR_LOG_D("GetQuotaRemain totalQuota[%{public}s] limit[%{public}s] start[%{public}s]",
246 std::to_string(totalQuota).c_str(), std::to_string(quotaPolicy.limitBytes).c_str(), ctime(&start));
247 // calculate the quota for each policy.
248 bool hasLimit = quotaPolicy.limitBytes != DATA_USAGE_UNKNOWN;
249 int64_t quota = LONG_MAX;
250 if (hasLimit || quotaPolicy.metered) {
251 if (hasLimit && quotaPolicy.periodDuration != QUOTA_POLICY_NO_PERIOD) {
252 if (quotaPolicy.lastLimitRemind >= start) {
253 return LONG_MAX;
254 }
255 quota = quotaPolicy.limitBytes - totalQuota;
256 }
257 }
258 return quota < 0 ? 0 : quota;
259 }
260
UpdateNetEnableStatus(const NetQuotaPolicy & quotaPolicy)261 void NetPolicyTraffic::UpdateNetEnableStatus(const NetQuotaPolicy "aPolicy)
262 {
263 NETMGR_LOG_D("UpdateNetEnableStatus metered[%{public}d] limitAction[%{public}d]", quotaPolicy.metered,
264 quotaPolicy.limitAction);
265 if (quotaPolicy.metered || quotaPolicy.limitAction == LIMIT_ACTION_DISABLE) {
266 SetNetworkEnableStatus(quotaPolicy, false);
267 }
268 }
269
GetNetQuotaPolicies(std::vector<NetQuotaPolicy> & quotaPolicies)270 int32_t NetPolicyTraffic::GetNetQuotaPolicies(std::vector<NetQuotaPolicy> "aPolicies)
271 {
272 quotaPolicies.clear();
273 quotaPolicies = quotaPolicies_;
274 NETMGR_LOG_D("GetNetQuotaPolicies quotaPolicies end size[%{public}zu]", quotaPolicies.size());
275 return NETMANAGER_SUCCESS;
276 }
277
UpdateRemindPolicy(int32_t netType,const std::string & iccid,uint32_t remindType)278 int32_t NetPolicyTraffic::UpdateRemindPolicy(int32_t netType, const std::string &iccid, uint32_t remindType)
279 {
280 if (!IsValidNetType(netType)) {
281 NETMGR_LOG_E("NetPolicyType is invalid policy[%{public}d]", netType);
282 return NETMANAGER_ERR_PARAMETER_ERROR;
283 }
284
285 if (!IsValidNetRemindType(remindType)) {
286 return NETMANAGER_ERR_PARAMETER_ERROR;
287 }
288
289 for (uint32_t i = 0; i < quotaPolicies_.size(); ++i) {
290 NetQuotaPolicy "aPolicy = quotaPolicies_[i];
291 int32_t netTypeTemp = quotaPolicy.netType;
292 std::string iccidTemp = quotaPolicy.iccid;
293 if (netTypeTemp == netType && iccidTemp == iccid) {
294 switch (remindType) {
295 case REMIND_TYPE_WARNING:
296 quotaPolicy.lastWarningRemind = time(nullptr);
297 break;
298 case REMIND_TYPE_LIMIT:
299 quotaPolicy.lastLimitRemind = time(nullptr);
300 break;
301 default:
302 return NETMANAGER_ERR_PARAMETER_ERROR;
303 }
304 }
305 }
306 UpdateQuotaPoliciesInner();
307
308 return NETMANAGER_SUCCESS;
309 }
310
GetMeteredIfaces()311 const std::vector<std::string> &NetPolicyTraffic::GetMeteredIfaces()
312 {
313 return meteredIfaces_;
314 }
315
ResetPolicies(const std::string & iccid)316 int32_t NetPolicyTraffic::ResetPolicies(const std::string &iccid)
317 {
318 for (auto "aPolicy : quotaPolicies_) {
319 if (quotaPolicy.iccid == iccid) {
320 quotaPolicy.Reset();
321 }
322 }
323 return UpdateQuotaPoliciesInner();
324 }
325
ReachedLimit(const std::string & iface)326 void NetPolicyTraffic::ReachedLimit(const std::string &iface)
327 {
328 NETMGR_LOG_D("ReachedLimit iface:%{public}s.", iface.c_str());
329 auto &ifaces = GetMeteredIfaces();
330 if (std::find(ifaces.begin(), ifaces.end(), iface) != ifaces.end()) {
331 UpdateQuotaPoliciesInner();
332 }
333 }
334
GetTotalQuota(NetQuotaPolicy & quotaPolicy)335 int64_t NetPolicyTraffic::GetTotalQuota(NetQuotaPolicy "aPolicy)
336 {
337 std::string iface = GetMatchIfaces(quotaPolicy);
338 NetStatsInfo info;
339 int64_t start = quotaPolicy.GetPeriodStart();
340 int64_t end = static_cast<int64_t>(time(nullptr));
341 int64_t quota = GetNetCenterInst().GetIfaceStatsDetail(iface, start, end, info);
342
343 return quota < 0 ? 0 : quota;
344 }
345
ReadQuotaPolicies()346 int32_t NetPolicyTraffic::ReadQuotaPolicies()
347 {
348 GetFileInst()->ReadQuotaPolicies(quotaPolicies_);
349 UpdateQuotaPoliciesInner();
350 return 0;
351 }
352
WriteQuotaPolicies()353 bool NetPolicyTraffic::WriteQuotaPolicies()
354 {
355 return GetFileInst()->WriteFile(quotaPolicies_);
356 }
357
GetMatchIfaces(const NetQuotaPolicy & quotaPolicy)358 const std::string NetPolicyTraffic::GetMatchIfaces(const NetQuotaPolicy "aPolicy)
359 {
360 std::string ident = "";
361 if (quotaPolicy.netType == BEARER_CELLULAR) {
362 ident = IDENT_PREFIX_CELLULAR + quotaPolicy.iccid;
363 } else if (quotaPolicy.netType == BEARER_WIFI) {
364 ident = quotaPolicy.ident;
365 } else if (quotaPolicy.netType == BEARER_ETHERNET) {
366 ident = quotaPolicy.ident;
367 }
368 std::string iface;
369 GetNetCenterInst().GetIfaceNameByType(static_cast<NetBearType>(quotaPolicy.netType), ident, iface);
370 NETMGR_LOG_D("GetMatchIfaces netType: %{public}d ident: %{public}s iface: %{public}s.", quotaPolicy.netType,
371 ident.c_str(), iface.c_str());
372 return iface;
373 }
374
SetNetworkEnableStatus(const NetQuotaPolicy & quotaPolicy,bool enable)375 void NetPolicyTraffic::SetNetworkEnableStatus(const NetQuotaPolicy "aPolicy, bool enable)
376 {
377 NETMGR_LOG_D("SetNetworkEnableStatus enable: %{public}d ", enable);
378 }
379
NotifyQuotaWarning(int64_t totalQuota)380 void NetPolicyTraffic::NotifyQuotaWarning(int64_t totalQuota)
381 {
382 PublishQuotaEvent(COMMON_EVENT_NET_QUOTA_WARNING, BROADCAST_QUOTA_WARNING, totalQuota);
383 }
384
NotifyQuotaLimitReminded(int64_t totalQuota)385 void NetPolicyTraffic::NotifyQuotaLimitReminded(int64_t totalQuota)
386 {
387 PublishQuotaEvent(COMMON_EVENT_NET_QUOTA_LIMIT_REMINDED, BROADCAST_QUOTA_LIMIT_REMIND, totalQuota);
388 }
389
NotifyQuotaLimit(int64_t totalQuota)390 void NetPolicyTraffic::NotifyQuotaLimit(int64_t totalQuota)
391 {
392 PublishQuotaEvent(COMMON_EVENT_NET_QUOTA_LIMIT, BROADCAST_QUOTA_LIMIT, totalQuota);
393 }
394
PublishQuotaEvent(const std::string & action,const std::string & describe,int64_t quota)395 void NetPolicyTraffic::PublishQuotaEvent(const std::string &action, const std::string &describe, int64_t quota)
396 {
397 BroadcastInfo info;
398 info.action = action;
399 info.data = describe;
400 info.permission = Permission::CONNECTIVITY_INTERNAL;
401 std::map<std::string, int64_t> param = {{"totalQuota", quota}};
402 DelayedSingleton<BroadcastManager>::GetInstance()->SendBroadcast(info, param);
403 }
404
IsValidPeriodDuration(const std::string & periodDuration)405 bool NetPolicyTraffic::IsValidPeriodDuration(const std::string &periodDuration)
406 {
407 if (periodDuration.empty() || periodDuration.size() < PERIOD_DURATION_SIZE) {
408 NETMGR_LOG_E("periodDuration is illegal");
409 return false;
410 }
411
412 std::string cycle = periodDuration.substr(0, 1);
413 NETMGR_LOG_D("PeriodDuration [%{public}s].", periodDuration.c_str());
414 int32_t start = CommonUtils::StrToInt(periodDuration.substr(1, periodDuration.size()));
415
416 if (cycle == PERIOD_DAY) {
417 if (start >= PERIOD_START && start <= DAY_MAX) {
418 return true;
419 }
420 }
421
422 if (cycle == PERIOD_MONTH) {
423 if (start >= PERIOD_START && start <= MONTH_MAX) {
424 return true;
425 }
426 }
427
428 if (cycle == PERIOD_YEAR) {
429 if (start >= PERIOD_START && start <= YEAR_MAX) {
430 return true;
431 }
432 }
433 NETMGR_LOG_E("Invalid periodDuration start [%{public}d],Invalid periodDuration cycle [%{public}s]", start,
434 cycle.c_str());
435 return false;
436 }
437
IsQuotaPolicyExist(int32_t netType,const std::string & iccid)438 bool NetPolicyTraffic::IsQuotaPolicyExist(int32_t netType, const std::string &iccid)
439 {
440 std::vector<NetQuotaPolicy> quotaPolicies;
441 if (GetFileInst()->ReadQuotaPolicies(quotaPolicies) != NETMANAGER_SUCCESS) {
442 NETMGR_LOG_E("GetNetQuotaPolicies failed");
443 return false;
444 }
445
446 if (quotaPolicies.empty()) {
447 NETMGR_LOG_E("quotaPolicies is empty");
448 return false;
449 }
450
451 for (uint32_t i = 0; i < quotaPolicies.size(); i++) {
452 if (netType == quotaPolicies[i].netType && iccid == quotaPolicies[i].iccid) {
453 return true;
454 }
455 }
456
457 return false;
458 }
459
HandleEvent(int32_t eventId,const std::shared_ptr<PolicyEvent> & policyEvent)460 void NetPolicyTraffic::HandleEvent(int32_t eventId, const std::shared_ptr<PolicyEvent> &policyEvent)
461 {
462 NETMGR_LOG_D("NetPolicyTraffic HandleEvent");
463 }
464
GetDumpMessage(std::string & message)465 void NetPolicyTraffic::GetDumpMessage(std::string &message)
466 {
467 static const std::string TAB = " ";
468 message.append(TAB + "MeteredIfaces: {");
469 std::for_each(meteredIfaces_.begin(), meteredIfaces_.end(),
470 [&message](const std::string &item) { message.append(item + ", "); });
471 message.append("}\n");
472 message.append(TAB + "QuotaPolicies:\n");
473 std::for_each(quotaPolicies_.begin(), quotaPolicies_.end(), [&message](const auto &item) {
474 message.append(TAB + TAB + "NetType: " + std::to_string(item.netType) + "\n" + TAB + TAB +
475 "IccId: " + item.iccid + "\n" + TAB + TAB + "Ident: " + item.ident + "\n");
476 message.append(TAB + TAB + "PeriodStartTime: " + std::to_string(item.periodStartTime) + "\n");
477 message.append(TAB + TAB + "PeriodDuration: " + item.periodDuration + "\n");
478 message.append(TAB + TAB + "Title: " + item.title + "\n" + TAB + TAB + "Summary: " + item.summary + "\n");
479 message.append(TAB + TAB + "WarningBytes: " + std::to_string(item.warningBytes) + "\n");
480 message.append(TAB + TAB + "LimitBytes: " + std::to_string(item.limitBytes) + "\n");
481 message.append(TAB + TAB + "LastWarningRemind: " + std::to_string(item.lastWarningRemind) + "\n");
482 message.append(TAB + TAB + "LastLimitRemind: " + std::to_string(item.lastLimitRemind) + "\n");
483 message.append(TAB + TAB + "Metered: " + std::to_string(item.metered) + "\n" + TAB + TAB +
484 "Source: " + std::to_string(item.source) + "\n");
485 message.append(TAB + TAB + "LimitAction: " + std::to_string(item.limitAction) + "\n" + TAB + TAB +
486 "UsedBytes: " + std::to_string(item.usedBytes) + "\n");
487 message.append(TAB + TAB + "UsedTimeDuration: " + std::to_string(item.usedTimeDuration) + "\n");
488 message.append(TAB + TAB + "Possessor: " + item.possessor + "\n\n");
489 });
490 }
491 } // namespace NetManagerStandard
492 } // namespace OHOS
493