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 <sstream>
17 #include "network_status_history_manager.h"
18 #include "wifi_logger.h"
19
20 namespace OHOS {
21 namespace Wifi {
22 DEFINE_WIFILOG_LABEL("NetworkStatusHistoryManager");
23 constexpr int THRESHOLD_CHECKED_NUM = 2;
24 constexpr int SECOND_FROM_LAST = 1;
25 constexpr int THIRD_FROM_LAST = 2;
26
Insert(uint32_t & networkStatusHistory,NetworkStatus networkStatus)27 void NetworkStatusHistoryManager::Insert(uint32_t &networkStatusHistory, NetworkStatus networkStatus)
28 {
29 networkStatusHistory =
30 (networkStatusHistory << ITEM_BIT_NUM | static_cast<int>(networkStatus)) & NETWORK_STATUS_HISTORY_MAX_MASK;
31 }
32
Update(uint32_t & networkStatusHistory,NetworkStatus networkStatus)33 void NetworkStatusHistoryManager::Update(uint32_t &networkStatusHistory, NetworkStatus networkStatus)
34 {
35 networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
36 Insert(networkStatusHistory, networkStatus);
37 }
38
GetLastNetworkStatus(uint32_t networkHistory)39 NetworkStatus NetworkStatusHistoryManager::GetLastNetworkStatus(uint32_t networkHistory)
40 {
41 return static_cast<NetworkStatus>(networkHistory & NETWORK_STATUS_MASK);
42 }
43
CountNetworkStatus(uint32_t networkStatusHistory,int counts[NETWORK_STATUS_NUM])44 void NetworkStatusHistoryManager::CountNetworkStatus(uint32_t networkStatusHistory,
45 int counts[NETWORK_STATUS_NUM])
46 {
47 while (networkStatusHistory != 0) {
48 NetworkStatus networkStatus = GetLastNetworkStatus(networkStatusHistory);
49 counts[static_cast<int>(networkStatus)]++;
50 networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
51 }
52 }
53
IsInternetAccessByHistory(uint32_t networkStatusHistory)54 bool NetworkStatusHistoryManager::IsInternetAccessByHistory(uint32_t networkStatusHistory)
55 {
56 int counts[NETWORK_STATUS_NUM] = {0};
57 CountNetworkStatus(networkStatusHistory, counts);
58 int checkedNum = counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] +
59 counts[static_cast<int>(NetworkStatus::PORTAL)] +
60 counts[static_cast<int>(NetworkStatus::NO_INTERNET)];
61 if (checkedNum == 0) {
62 return false;
63 }
64 if (GetLastNetworkStatus(networkStatusHistory) == NetworkStatus::HAS_INTERNET) {
65 return true;
66 }
67 if (checkedNum == THRESHOLD_CHECKED_NUM) {
68 return GetLastNetworkStatus(networkStatusHistory >> SECOND_FROM_LAST * ITEM_BIT_NUM) ==
69 NetworkStatus::HAS_INTERNET;
70 }
71 return counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] >= checkedNum * RECOVERY_PERCENTAGE;
72 }
73
IsAllowRecoveryByHistory(uint32_t networkStatusHistory)74 bool NetworkStatusHistoryManager::IsAllowRecoveryByHistory(uint32_t networkStatusHistory)
75 {
76 int counts[NETWORK_STATUS_NUM] = {0};
77 CountNetworkStatus(networkStatusHistory, counts);
78 int checkedNum = counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] +
79 counts[static_cast<int>(NetworkStatus::PORTAL)] +
80 counts[static_cast<int>(NetworkStatus::NO_INTERNET)];
81 if (checkedNum < THRESHOLD_CHECKED_NUM) {
82 return false;
83 }
84 if (checkedNum == THRESHOLD_CHECKED_NUM) {
85 /* get the second from last network status by shifting right */
86 return GetLastNetworkStatus(networkStatusHistory >> SECOND_FROM_LAST * ITEM_BIT_NUM) ==
87 NetworkStatus::HAS_INTERNET;
88 }
89
90 /* get the last networkStatus and get the second from last network status by shifting right */
91 if (GetLastNetworkStatus(networkStatusHistory) != NetworkStatus::HAS_INTERNET &&
92 GetLastNetworkStatus(networkStatusHistory >> SECOND_FROM_LAST * ITEM_BIT_NUM) != NetworkStatus::HAS_INTERNET) {
93 return false;
94 }
95
96 /* get the second from last and third from last network status by shifting right*/
97 if (GetLastNetworkStatus(networkStatusHistory >> SECOND_FROM_LAST * ITEM_BIT_NUM) == NetworkStatus::HAS_INTERNET &&
98 GetLastNetworkStatus(networkStatusHistory >> THIRD_FROM_LAST * ITEM_BIT_NUM) == NetworkStatus::HAS_INTERNET) {
99 return true;
100 }
101 return counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] >= checkedNum * RECOVERY_PERCENTAGE;
102 }
103
IsPortalByHistory(uint32_t networkStatusHistory)104 bool NetworkStatusHistoryManager::IsPortalByHistory(uint32_t networkStatusHistory)
105 {
106 int counts[NETWORK_STATUS_NUM] = {0};
107 CountNetworkStatus(networkStatusHistory, counts);
108 return counts[static_cast<int>(NetworkStatus::PORTAL)] > 0;
109 }
110
HasInternetEverByHistory(uint32_t networkStatusHistory)111 bool NetworkStatusHistoryManager::HasInternetEverByHistory(uint32_t networkStatusHistory)
112 {
113 int counts[NETWORK_STATUS_NUM] = {0};
114 CountNetworkStatus(networkStatusHistory, counts);
115 return counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] > 0;
116 }
117
IsEmptyNetworkStatusHistory(uint32_t networkStatusHistory)118 bool NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(uint32_t networkStatusHistory)
119 {
120 return !networkStatusHistory;
121 }
122
ToString(uint32_t networkStatusHistory)123 std::string NetworkStatusHistoryManager::ToString(uint32_t networkStatusHistory)
124 {
125 std::stringstream networkStatusString;
126 while (networkStatusHistory != 0) {
127 NetworkStatus networkStatus = GetLastNetworkStatus(networkStatusHistory);
128 networkStatusString << static_cast<int>(networkStatus) << "/";
129 networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
130 }
131 return networkStatusString.str();
132 }
133
GetCurrentNetworkStatusHistory2Array(uint32_t networkStatusHistory)134 std::vector<int> NetworkStatusHistoryManager::GetCurrentNetworkStatusHistory2Array(uint32_t networkStatusHistory)
135 {
136 std::vector<int> vNetworkStatusHistory;
137 while (networkStatusHistory != 0) {
138 NetworkStatus networkStatus = GetLastNetworkStatus(networkStatusHistory);
139 if (networkStatus == NetworkStatus::HAS_INTERNET) {
140 vNetworkStatusHistory.emplace_back(1);
141 } else {
142 vNetworkStatusHistory.emplace_back(0);
143 }
144 networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
145 }
146 return vNetworkStatusHistory;
147 }
148
ModifyAllHistoryRecord(unsigned int & networkStatusHistory,NetworkStatus oldStatus,NetworkStatus newStatus)149 void NetworkStatusHistoryManager::ModifyAllHistoryRecord(unsigned int &networkStatusHistory,
150 NetworkStatus oldStatus, NetworkStatus newStatus)
151 {
152 WIFI_LOGI("%{public}s, old networkStatusHistory=%{public}d, old status=%{public}d, new status=%{public}d",
153 __func__, networkStatusHistory, static_cast<int>(oldStatus), static_cast<int>(newStatus));
154 unsigned int oldNetworkStatusHistory = networkStatusHistory;
155 unsigned int newNetworkStatusHistory = 0;
156 int count = 0;
157 while (oldNetworkStatusHistory != 0) {
158 NetworkStatus networkStatus = GetLastNetworkStatus(oldNetworkStatusHistory);
159 if (networkStatus == oldStatus) {
160 networkStatus = newStatus;
161 }
162 newNetworkStatusHistory |= static_cast<unsigned int>(networkStatus) << (count * ITEM_BIT_NUM);
163 oldNetworkStatusHistory = oldNetworkStatusHistory >> ITEM_BIT_NUM;
164 count++;
165 }
166 networkStatusHistory = newNetworkStatusHistory;
167 WIFI_LOGI("%{public}s, new networkStatusHistory=%{public}d", __func__, newNetworkStatusHistory);
168 }
169 }
170 }