• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 "self_cure_utils.h"
17 #include "net_conn_client.h"
18 #include "net_handle.h"
19 #include "netsys_controller.h"
20 #include "self_cure_common.h"
21 #include "self_cure_msg.h"
22 #include "wifi_logger.h"
23 #include "self_cure_state_machine.h"
24 #include "wifi_config_center.h"
25 #include "wifi_country_code_manager.h"
26 #include "wifi_sta_hal_interface.h"
27 
28 namespace OHOS {
29 namespace Wifi {
30 using namespace NetManagerStandard;
31 DEFINE_WIFILOG_LABEL("SelfCureUtils");
SelfCureUtils()32 SelfCureUtils::SelfCureUtils()
33 {
34     WIFI_LOGI("SelfCureUtils()");
35 }
36 
~SelfCureUtils()37 SelfCureUtils::~SelfCureUtils()
38 {
39     WIFI_LOGI("~SelfCureUtils()");
40 }
41 
GetInstance()42 SelfCureUtils& SelfCureUtils::GetInstance()
43 {
44     static SelfCureUtils instance;
45     return instance;
46 }
47 
RegisterDnsResultCallback()48 void SelfCureUtils::RegisterDnsResultCallback()
49 {
50     dnsResultCallback_ = std::make_unique<SelfCureDnsResultCallback>().release();
51     int32_t regDnsResult = NetsysController::GetInstance().RegisterDnsResultCallback(dnsResultCallback_, 0);
52     WIFI_LOGI("RegisterDnsResultCallback result = %{public}d", regDnsResult);
53 }
54 
UnRegisterDnsResultCallback()55 void SelfCureUtils::UnRegisterDnsResultCallback()
56 {
57     WIFI_LOGI("UnRegisterDnsResultCallback");
58     if (dnsResultCallback_ != nullptr) {
59         NetsysController::GetInstance().UnregisterDnsResultCallback(dnsResultCallback_);
60     }
61 }
62 
GetCurrentDnsFailedCounter()63 int32_t SelfCureUtils::GetCurrentDnsFailedCounter()
64 {
65     if (dnsResultCallback_ == nullptr) {
66         WIFI_LOGE("dnsResultCallback_ is null");
67         return -1;
68     }
69     return dnsResultCallback_->dnsFailedCounter_;
70 }
71 
ClearDnsFailedCounter()72 void SelfCureUtils::ClearDnsFailedCounter()
73 {
74     if (dnsResultCallback_ == nullptr) {
75         WIFI_LOGE("dnsResultCallback_ is null");
76         return;
77     }
78     dnsResultCallback_->dnsFailedCounter_ = 0;
79 }
80 
OnDnsResultReport(uint32_t size,const std::list<NetsysNative::NetDnsResultReport> netDnsResultReport)81 int32_t SelfCureUtils::SelfCureDnsResultCallback::OnDnsResultReport(uint32_t size,
82     const std::list<NetsysNative::NetDnsResultReport> netDnsResultReport)
83 {
84     int32_t wifiNetId = GetWifiNetId();
85     int32_t defaultNetId = GetDefaultNetId();
86     for (auto &it : netDnsResultReport) {
87         int32_t netId = static_cast<int32_t>(it.netid_);
88         int32_t targetNetId = netId > 0 ? netId : (defaultNetId > 0 ? defaultNetId : 0);
89         if (wifiNetId > 0 && wifiNetId == targetNetId) {
90             if (it.queryresult_ != 0) {
91                 dnsFailedCounter_++;
92             }
93         }
94     }
95     WIFI_LOGD("OnDnsResultReport, wifiNetId: %{public}d, defaultNetId: %{public}d, dnsFailedCounter_: %{public}d",
96         wifiNetId, defaultNetId, dnsFailedCounter_);
97     return 0;
98 }
99 
GetWifiNetId()100 int32_t SelfCureUtils::SelfCureDnsResultCallback::GetWifiNetId()
101 {
102     std::list<sptr<NetHandle>> netList;
103     int32_t ret = NetConnClient::GetInstance().GetAllNets(netList);
104     if (ret != 0) {
105         return 0;
106     }
107 
108     for (auto iter : netList) {
109         NetAllCapabilities netAllCap;
110         NetConnClient::GetInstance().GetNetCapabilities(*iter, netAllCap);
111         if (netAllCap.bearerTypes_.count(BEARER_WIFI) > 0) {
112             return iter->GetNetId();
113         }
114     }
115     return 0;
116 }
117 
GetDefaultNetId()118 int32_t SelfCureUtils::SelfCureDnsResultCallback::GetDefaultNetId()
119 {
120     NetHandle defaultNet;
121     NetConnClient::GetInstance().GetDefaultNet(defaultNet);
122     return defaultNet.GetNetId();
123 }
124 
GetSelfCureType(int32_t currentCureLevel)125 int32_t SelfCureUtils::GetSelfCureType(int32_t currentCureLevel)
126 {
127     SelfCureType ret = SelfCureType::SCE_TYPE_INVALID;
128     switch (currentCureLevel) {
129         case WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC:
130             ret = SelfCureType::SCE_TYPE_REASSOC;
131             break;
132         case WIFI_CURE_RESET_LEVEL_WIFI6:
133             ret = SelfCureType::SCE_TYPE_WIFI6;
134             break;
135         case WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP:
136             ret = SelfCureType::SCE_TYPE_STATIC_IP;
137             break;
138         case WIFI_CURE_RESET_LEVEL_MULTI_GATEWAY:
139             ret = SelfCureType::SCE_TYPE_MULTI_GW;
140             break;
141         case WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC:
142             ret = SelfCureType::SCE_TYPE_RANDMAC;
143             break;
144         case WIFI_CURE_RESET_LEVEL_HIGH_RESET:
145             ret = SelfCureType::SCE_TYPE_RESET;
146             break;
147         case WIFI_CURE_RESET_LEVEL_HIGH_RESET_WIFI_ON:
148             ret = SelfCureType::SCE_TYPE_RESET_WIFI_ON;
149             break;
150         default:
151             break;
152     }
153     return static_cast<int32_t>(ret);
154 }
155 
GetNextIpAddr(const std::string & gateway,const std::string & currentAddr,const std::vector<std::string> & testedAddr)156 std::string SelfCureUtils::GetNextIpAddr(const std::string& gateway, const std::string& currentAddr,
157                                          const std::vector<std::string>& testedAddr)
158 {
159     std::vector<uint32_t> ipAddr;
160     if (gateway.empty() || currentAddr.empty() || testedAddr.size() ==0) {
161         WIFI_LOGI("gateway is empty or currentAddr is empty or testedAddr.size() == 0");
162         return "";
163     }
164     uint32_t newIp = 0;
165     uint32_t getCnt = 1;
166     ipAddr = TransIpAddressToVec(currentAddr);
167     uint32_t iMAX = 250;
168     uint32_t iMIN = 101;
169     while (getCnt++ < GET_NEXT_IP_MAC_CNT) {
170         std::vector<uint32_t> gwAddr;
171         bool reduplicate = false;
172         time_t now = time(nullptr);
173         if (now >= 0) {
174             srand(now);
175         }
176         uint32_t randomNum = 0;
177         int32_t fd = open("/dev/random", O_RDONLY); /* Obtain the random number by reading /dev/random */
178         if (fd > 0) {
179             read(fd, &randomNum, sizeof(uint32_t));
180         }
181         close(fd);
182         uint32_t rand = (randomNum > 0 ? randomNum : -randomNum) % 100;
183         newIp = rand + iMIN;
184         gwAddr = TransIpAddressToVec(gateway);
185         if (newIp == (gwAddr[VEC_POS_3] & 0xFF) || newIp == (ipAddr[VEC_POS_3] & 0xFF)) {
186             continue;
187         }
188         for (size_t i = 0; i < testedAddr.size(); i++) {
189             std::vector<uint32_t> tmp = TransIpAddressToVec(testedAddr[i]);
190             if (newIp == (tmp[VEC_POS_3] & 0xFF)) {
191                 reduplicate = true;
192                 break;
193             }
194         }
195         if (newIp > 0 && !reduplicate) {
196             break;
197         }
198     }
199     if (newIp > 1 && newIp <= iMAX && getCnt < GET_NEXT_IP_MAC_CNT) {
200         ipAddr[VEC_POS_3] = newIp;
201         return TransVecToIpAddress(ipAddr);
202     }
203     return "";
204 }
205 
UpdateSelfCureHistoryInfo(WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel,bool success)206 void SelfCureUtils::UpdateSelfCureHistoryInfo(WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel,
207                                               bool success)
208 {
209     WIFI_LOGI("enter %{public}s", __FUNCTION__);
210     auto now = std::chrono::system_clock::now();
211     int64_t currentMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
212     if (requestCureLevel == WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP) {
213         if (success) {
214             historyInfo.staticIpSelfCureFailedCnt = 0;
215             historyInfo.lastStaticIpSelfCureFailedTs = 0;
216         } else {
217             historyInfo.staticIpSelfCureFailedCnt += 1;
218             historyInfo.lastStaticIpSelfCureFailedTs = currentMs;
219         }
220     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC) {
221         if (success) {
222             historyInfo.reassocSelfCureFailedCnt = 0;
223             historyInfo.lastReassocSelfCureFailedTs = 0;
224         } else {
225             historyInfo.reassocSelfCureFailedCnt += 1;
226             historyInfo.lastReassocSelfCureFailedTs = currentMs;
227         }
228     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC) {
229         if (success) {
230             historyInfo.randMacSelfCureFailedCnt = 0;
231             historyInfo.lastRandMacSelfCureFailedCntTs = 0;
232         } else {
233             historyInfo.randMacSelfCureFailedCnt += 1;
234             historyInfo.lastRandMacSelfCureFailedCntTs = currentMs;
235         }
236     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_HIGH_RESET) {
237         if (success) {
238             historyInfo.resetSelfCureFailedCnt = 0;
239             historyInfo.lastResetSelfCureFailedTs = 0;
240         } else {
241             historyInfo.resetSelfCureFailedCnt += 1;
242             historyInfo.lastResetSelfCureFailedTs = currentMs;
243         }
244     }
245 }
246 
UpdateSelfCureConnectHistoryInfo(WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel,bool success)247 void SelfCureUtils::UpdateSelfCureConnectHistoryInfo(WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel,
248                                                      bool success)
249 {
250     auto now = std::chrono::system_clock::now();
251     int64_t currentMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
252     if (requestCureLevel == WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC) {
253         if (success) {
254             historyInfo.reassocSelfCureConnectFailedCnt = 0;
255             historyInfo.lastReassocSelfCureConnectFailedTs = 0;
256         } else {
257             historyInfo.reassocSelfCureConnectFailedCnt += 1;
258             historyInfo.lastReassocSelfCureConnectFailedTs = currentMs;
259         }
260     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC) {
261         if (success) {
262             historyInfo.randMacSelfCureConnectFailedCnt = 0;
263             historyInfo.lastRandMacSelfCureConnectFailedCntTs = 0;
264         } else {
265             historyInfo.randMacSelfCureConnectFailedCnt += 1;
266             historyInfo.lastRandMacSelfCureConnectFailedCntTs = currentMs;
267         }
268     } else if (requestCureLevel == WIFI_CURE_RESET_LEVEL_HIGH_RESET) {
269         if (success) {
270             historyInfo.resetSelfCureConnectFailedCnt = 0;
271             historyInfo.lastResetSelfCureConnectFailedTs = 0;
272         } else {
273             historyInfo.resetSelfCureConnectFailedCnt += 1;
274             historyInfo.lastResetSelfCureConnectFailedTs = currentMs;
275         }
276     }
277 }
278 
AllowSelfCure(const WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel)279 bool AllowSelfCure(const WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel)
280 {
281     auto now = std::chrono::system_clock::now();
282     int64_t currentMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
283     if (requestCureLevel == WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC) {
284         if ((historyInfo.reassocSelfCureConnectFailedCnt == 0) ||
285             ((historyInfo.reassocSelfCureConnectFailedCnt >= 1) &&
286              ((currentMs - historyInfo.lastReassocSelfCureConnectFailedTs) > DELAYED_DAYS_LOW))) {
287             return true;
288         }
289     } else {
290         if (requestCureLevel == WIFI_CURE_RESET_LEVEL_HIGH_RESET) {
291             if ((historyInfo.resetSelfCureConnectFailedCnt == 0) ||
292                 ((historyInfo.resetSelfCureConnectFailedCnt >= 1) &&
293                  ((currentMs - historyInfo.lastResetSelfCureConnectFailedTs) > DELAYED_DAYS_LOW))) {
294                 return true;
295             }
296         }
297     }
298     return false;
299 }
300 
DealStaticIp(const WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel,int64_t currentMs)301 static bool DealStaticIp(const WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel, int64_t currentMs)
302 {
303     if (historyInfo.staticIpSelfCureFailedCnt <= SELF_CURE_FAILED_FOUR_CNT ||
304         (historyInfo.staticIpSelfCureFailedCnt == SELF_CURE_FAILED_FIVE_CNT &&
305          (currentMs - historyInfo.lastStaticIpSelfCureFailedTs > DELAYED_DAYS_LOW)) ||
306         (historyInfo.staticIpSelfCureFailedCnt == SELF_CURE_FAILED_SIX_CNT &&
307          (currentMs - historyInfo.lastStaticIpSelfCureFailedTs > DELAYED_DAYS_MID)) ||
308         (historyInfo.staticIpSelfCureFailedCnt >= SELF_CURE_FAILED_SEVEN_CNT &&
309          (currentMs - historyInfo.lastStaticIpSelfCureFailedTs > DELAYED_DAYS_HIGH))) {
310         return true;
311     }
312     return false;
313 }
314 
DealMiddleReassoc(WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel,int64_t currentMs)315 static bool DealMiddleReassoc(WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel, int64_t currentMs)
316 {
317     if ((historyInfo.reassocSelfCureFailedCnt == 0 ||
318         (historyInfo.reassocSelfCureFailedCnt == SELF_CURE_FAILED_ONE_CNT &&
319          (currentMs - historyInfo.lastReassocSelfCureFailedTs > DELAYED_DAYS_LOW)) ||
320         (historyInfo.reassocSelfCureFailedCnt == SELF_CURE_FAILED_TWO_CNT &&
321          (currentMs - historyInfo.lastReassocSelfCureFailedTs > DELAYED_DAYS_MID)) ||
322         (historyInfo.reassocSelfCureFailedCnt >= SELF_CURE_FAILED_THREE_CNT &&
323          (currentMs - historyInfo.lastReassocSelfCureFailedTs > DELAYED_DAYS_HIGH))) &&
324         AllowSelfCure(historyInfo, requestCureLevel)) {
325         return true;
326     }
327     return false;
328 }
329 
DealRandMacReassoc(const WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel,int64_t currentMs)330 static bool DealRandMacReassoc(const WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel, int64_t currentMs)
331 {
332     if (historyInfo.randMacSelfCureFailedCnt < SELF_CURE_RAND_MAC_MAX_COUNT) {
333         return true;
334     }
335     return false;
336 }
337 
DealHighReset(WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel,int64_t currentMs)338 static bool DealHighReset(WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel, int64_t currentMs)
339 {
340     if ((historyInfo.resetSelfCureFailedCnt <= SELF_CURE_FAILED_ONE_CNT ||
341         (historyInfo.resetSelfCureFailedCnt == SELF_CURE_FAILED_TWO_CNT &&
342          (currentMs - historyInfo.lastResetSelfCureFailedTs > DELAYED_DAYS_LOW)) ||
343         (historyInfo.resetSelfCureFailedCnt == SELF_CURE_FAILED_THREE_CNT &&
344          (currentMs - historyInfo.lastResetSelfCureFailedTs > DELAYED_DAYS_MID)) ||
345         (historyInfo.resetSelfCureFailedCnt >= SELF_CURE_FAILED_FOUR_CNT &&
346          (currentMs - historyInfo.lastResetSelfCureFailedTs > DELAYED_DAYS_HIGH))) &&
347         AllowSelfCure(historyInfo, requestCureLevel)) {
348         return true;
349     }
350     return false;
351 }
352 
SelfCureAcceptable(WifiSelfCureHistoryInfo & historyInfo,int requestCureLevel)353 bool SelfCureUtils::SelfCureAcceptable(WifiSelfCureHistoryInfo &historyInfo, int requestCureLevel)
354 {
355     auto now = std::chrono::system_clock::now();
356     int64_t currentMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
357     if (currentMs <= 0) {
358         WIFI_LOGE("Get current time error");
359     }
360     bool ifAcceptable = false;
361     switch (requestCureLevel) {
362         case WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP:
363             ifAcceptable = DealStaticIp(historyInfo, WIFI_CURE_RESET_LEVEL_LOW_3_STATIC_IP, currentMs);
364             break;
365         case WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC:
366             ifAcceptable = DealMiddleReassoc(historyInfo, WIFI_CURE_RESET_LEVEL_MIDDLE_REASSOC, currentMs);
367             break;
368         case WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC:
369             ifAcceptable = DealRandMacReassoc(historyInfo, WIFI_CURE_RESET_LEVEL_RAND_MAC_REASSOC, currentMs);
370             break;
371         case WIFI_CURE_RESET_LEVEL_HIGH_RESET:
372             ifAcceptable = DealHighReset(historyInfo, WIFI_CURE_RESET_LEVEL_HIGH_RESET, currentMs);
373             break;
374         default:
375             break;
376     }
377     return ifAcceptable;
378 }
379 
TransStrToVec(std::string str,char c)380 std::vector<std::string> SelfCureUtils::TransStrToVec(std::string str, char c)
381 {
382     size_t pos = 0;
383     std::vector<std::string> vec;
384     while ((pos = str.find(c)) != std::string::npos) {
385         vec.push_back(str.substr(0, pos));
386         str.erase(0, pos + 1);
387     }
388     vec.push_back(str);
389     return vec;
390 }
391 
TransVecToIpAddress(const std::vector<uint32_t> & vec)392 std::string SelfCureUtils::TransVecToIpAddress(const std::vector<uint32_t>& vec)
393 {
394     std::string address = "";
395     if (vec.size() != IP_ADDR_SIZE) {
396         return address;
397     }
398     std::ostringstream stream;
399     stream << vec[VEC_POS_0] << "." << vec[VEC_POS_1] << "." << vec[VEC_POS_2] << "." << vec[VEC_POS_3];
400     address = stream.str();
401     return address;
402 }
403 
TransIpAddressToVec(std::string addr)404 std::vector<uint32_t> SelfCureUtils::TransIpAddressToVec(std::string addr)
405 {
406     if (addr.empty()) {
407         WIFI_LOGE("addr is empty");
408         return {0, 0, 0, 0};
409     }
410     size_t pos = 0;
411     std::vector<uint32_t> currAddr;
412     while ((pos = addr.find('.')) != std::string::npos) {
413         std::string addTmp = addr.substr(0, pos);
414         currAddr.push_back(CheckDataLegal(addTmp));
415         addr.erase(0, pos + 1);
416     }
417     currAddr.push_back(CheckDataLegal(addr));
418     if (currAddr.size() != IP_ADDR_SIZE) {
419         WIFI_LOGE("TransIpAddressToVec failed");
420         return {0, 0, 0, 0};
421     }
422     return currAddr;
423 }
424 
String2InternetSelfCureHistoryInfo(const std::string selfCureHistory,WifiSelfCureHistoryInfo & info)425 int SelfCureUtils::String2InternetSelfCureHistoryInfo(const std::string selfCureHistory,
426                                                       WifiSelfCureHistoryInfo &info)
427 {
428     WifiSelfCureHistoryInfo selfCureHistoryInfo;
429     if (selfCureHistory.empty()) {
430         WIFI_LOGE("InternetSelfCureHistoryInfo is empty!");
431         info = selfCureHistoryInfo;
432         return -1;
433     }
434     std::vector<std::string> histories = TransStrToVec(selfCureHistory, '|');
435     if (histories.size() != SELFCURE_HISTORY_LENGTH) {
436         WIFI_LOGE("self cure history length = %{public}lu", (unsigned long) histories.size());
437         info = selfCureHistoryInfo;
438         return -1;
439     }
440     if (SetSelfCureFailInfo(selfCureHistoryInfo, histories, SELFCURE_FAIL_LENGTH) != 0) {
441         WIFI_LOGE("set self cure history information failed!");
442     }
443     if (SetSelfCureConnectFailInfo(selfCureHistoryInfo, histories, SELFCURE_FAIL_LENGTH) != 0) {
444         WIFI_LOGE("set self cure connect history information failed!");
445     }
446     info = selfCureHistoryInfo;
447     return 0;
448 }
449 
SetSelfCureFailInfo(WifiSelfCureHistoryInfo & info,std::vector<std::string> & histories,int cnt)450 int SelfCureUtils::SetSelfCureFailInfo(WifiSelfCureHistoryInfo &info,
451                                        std::vector<std::string>& histories, int cnt)
452 {
453     if (histories.empty() || histories.size() != SELFCURE_HISTORY_LENGTH || cnt != SELFCURE_FAIL_LENGTH) {
454         WIFI_LOGE("SetSelfCureFailInfo return");
455         return -1;
456     }
457     // 0 to 12 is history subscript, which record the selfcure failed info, covert array to calss member
458     for (int i = 0; i < cnt; i++) {
459         if (i == SelfCureHistoryOrder::POS_STATIC_IP_FAILED_CNT) {
460             info.staticIpSelfCureFailedCnt = CheckDataLegal(histories[i]);
461         } else if (i == SelfCureHistoryOrder::POS_STATIC_IP_FAILED_TS) {
462             info.lastStaticIpSelfCureFailedTs = CheckDataTolonglong(histories[i]);
463         } else if (i == SelfCureHistoryOrder::POS_REASSOC_FAILED_CNT) {
464             info.reassocSelfCureFailedCnt = CheckDataLegal(histories[i]);
465         } else if (i == SelfCureHistoryOrder::POS_REASSOC_FAILED_TS) {
466             info.lastReassocSelfCureFailedTs = CheckDataTolonglong(histories[i]);
467         } else if (i == SelfCureHistoryOrder::POS_RANDMAC_FAILED_CNT) {
468             info.randMacSelfCureFailedCnt = CheckDataLegal(histories[i]);
469         } else if (i == SelfCureHistoryOrder::POS_RANDMAC_FAILED_TS) {
470             info.lastRandMacSelfCureFailedCntTs = CheckDataTolonglong(histories[i]);
471         } else if (i == SelfCureHistoryOrder::POS_RESET_FAILED_CNT) {
472             info.resetSelfCureFailedCnt = CheckDataLegal(histories[i]);
473         } else if (i == SelfCureHistoryOrder::POS_RESET_FAILED_TS) {
474             info.lastResetSelfCureFailedTs = CheckDataTolonglong(histories[i]);
475         } else {
476             WIFI_LOGE("SetSelfCureFailInfo, exception happen.");
477         }
478     }
479     return 0;
480 }
481 
SetSelfCureConnectFailInfo(WifiSelfCureHistoryInfo & info,std::vector<std::string> & histories,int cnt)482 int SelfCureUtils::SetSelfCureConnectFailInfo(WifiSelfCureHistoryInfo &info,
483                                               std::vector<std::string>& histories, int cnt)
484 {
485     if (histories.empty() || histories.size() != SELFCURE_HISTORY_LENGTH || cnt != SELFCURE_FAIL_LENGTH) {
486         WIFI_LOGE("SetSelfCureFailInfo return");
487         return -1;
488     }
489     // 12 to 17 is history subscript, which record the selfcure connect failed info, covert array to calss member
490     for (int i = cnt; i < SELFCURE_HISTORY_LENGTH; i++) {
491         if (i == POS_REASSOC_CONNECT_FAILED_CNT) {
492             info.reassocSelfCureConnectFailedCnt = CheckDataLegal(histories[i]);
493         } else if (i == POS_REASSOC_CONNECT_FAILED_TS) {
494             info.lastReassocSelfCureConnectFailedTs = CheckDataTolonglong(histories[i]);
495         } else if (i == POS_RANDMAC_CONNECT_FAILED_CNT) {
496             info.randMacSelfCureConnectFailedCnt = CheckDataLegal(histories[i]);
497         } else if (i == POS_RANDMAC_CONNECT_FAILED_TS) {
498             info.lastRandMacSelfCureConnectFailedCntTs = CheckDataTolonglong(histories[i]);
499         } else if (i == POS_RESET_CONNECT_FAILED_CNT) {
500             info.resetSelfCureConnectFailedCnt = CheckDataLegal(histories[i]);
501         } else if (i == POS_RESET_CONNECT_FAILED_TS) {
502             info.lastResetSelfCureConnectFailedTs = CheckDataTolonglong(histories[i]);
503         } else {
504             WIFI_LOGE("SetSelfCureConnectFailInfo, exception happen.");
505         }
506     }
507     return 0;
508 }
509 
IsIpConflictDetect()510 bool SelfCureUtils::IsIpConflictDetect()
511 {
512     WIFI_LOGI("IsIpConflictDetect enter");
513     ArpChecker arpChecker;
514     std::string macAddress;
515     WifiConfigCenter::GetInstance().GetMacAddress(macAddress);
516     IpInfo ipInfo;
517     WifiConfigCenter::GetInstance().GetIpInfo(ipInfo);
518     std::string targetIp = IpTools::ConvertIpv4Address(ipInfo.ipAddress);
519     std::string ifName = WifiConfigCenter::GetInstance().GetStaIfaceName();
520     std::string senderIp = "0.0.0.0";
521     if (targetIp.empty() || ifName.empty()) {
522         WIFI_LOGE("targetIp or ifName is empty");
523         return false;
524     }
525     arpChecker.Start(ifName, macAddress, senderIp, targetIp);
526     for (int i = 0; i < DEFAULT_SLOW_NUM_ARP_PINGS; i++) {
527         if (arpChecker.DoArpCheck(MAX_ARP_DNS_CHECK_TIME, true)) {
528             WIFI_LOGW("IsIpConflictDetect, ip conflicted!");
529             return true;
530         }
531     }
532     return false;
533 }
534 
GetSelfCureHistory()535 std::string SelfCureUtils::GetSelfCureHistory()
536 {
537     WifiLinkedInfo wifiLinkedInfo;
538     if (WifiConfigCenter::GetInstance().GetLinkedInfo(wifiLinkedInfo) != 0) {
539         WIFI_LOGE("GetSelfCureHistory Get current link info failed!");
540         return "";
541     }
542     WifiDeviceConfig config;
543     if (WifiSettings::GetInstance().GetDeviceConfig(wifiLinkedInfo.networkId, config) != 0) {
544         WIFI_LOGE("GetSelfCureHistory Get device config failed!, netId: %{public}d", wifiLinkedInfo.networkId);
545         return "";
546     }
547     return config.internetSelfCureHistory;
548 }
549 
ReportNoInternetChrEvent()550 void SelfCureUtils::ReportNoInternetChrEvent()
551 {
552     WIFI_LOGI("ReportNoInternetChrEvent enter");
553     std::string selfcureHistory = GetSelfCureHistory();
554     int resetState = (WifiConfigCenter::GetInstance().GetWifiSelfcureResetEntered() ? 1 : 0);
555     NetworkFailReason networkFailReason = NetworkFailReason::DNS_STATE_UNREACHABLE;
556     if (IsIpConflictDetect()) {
557         networkFailReason = NetworkFailReason::IP_STATE_CONFLICT;
558     }
559     WriteWifiAccessIntFailedHiSysEvent(1, networkFailReason, resetState, selfcureHistory);
560 }
561 } // namespace Wifi
562 } // namespace OHOS