• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "wifi_common_util.h"
17 #include <fstream>
18 #include <sstream>
19 #include <iterator>
20 #include <regex>
21 #include <sstream>
22 
23 #ifndef OHOS_ARCH_LITE
24 #include <vector>
25 #include <openssl/bio.h>
26 #include <openssl/evp.h>
27 #include <openssl/pem.h>
28 #include <openssl/x509.h>
29 #include "app_mgr_client.h"
30 #include "bundle_mgr_interface.h"
31 #include "if_system_ability_manager.h"
32 #include "ipc_skeleton.h"
33 #include "iservice_registry.h"
34 #include "system_ability_definition.h"
35 #include "common_timer_errors.h"
36 #endif
37 #include "wifi_logger.h"
38 #include <ifaddrs.h>
39 #include <net/if.h>
40 #include <netdb.h>
41 #include <cerrno>
42 
43 namespace OHOS {
44 namespace Wifi {
45 DEFINE_WIFILOG_LABEL("WifiCommonUtil");
46 
47 constexpr int PRIFIX_IP_LEN = 3;
48 constexpr int PRIFIX_P2P_LEN = 3;
49 constexpr int PRIFIX_CHBA_LEN = 4;
50 constexpr int PRIFIX_WLAN1_LEN = 5;
51 constexpr int FREQ_2G_MIN = 2412;
52 constexpr int FREQ_2G_MAX = 2472;
53 constexpr int FREQ_5G_MIN = 5170;
54 constexpr int FREQ_5G_MAX = 5825;
55 constexpr int CHANNEL_14_FREQ = 2484;
56 constexpr int CHANNEL_14 = 14;
57 constexpr int CENTER_FREQ_DIFF = 5;
58 constexpr int CHANNEL_2G_MIN = 1;
59 constexpr int CHANNEL_5G_MIN = 34;
60 constexpr int MIN_24G_CHANNEL = 1;
61 constexpr int MAX_24G_CHANNEL = 13;
62 constexpr int MIN_5G_CHANNEL = 36;
63 constexpr int MAX_5G_CHANNEL = 165;
64 constexpr int FREQ_CHANNEL_1 = 2412;
65 constexpr int FREQ_CHANNEL_36 = 5180;
66 constexpr int MICROSECOND_TO_NANOSECOND = 1000;
67 constexpr char HIDDEN_CHAR_SHOW_AS = '*';
68 constexpr int PASSWORD_MIN_LEN = 8;
69 constexpr int PASSWORD_NO_HIDDEN_LEN = 2;
70 constexpr int STRING_MAC_LEN = 18;
71 
72 constexpr uint32_t BASE_BIN = 2;
73 constexpr uint32_t BASE_HEX = 16;
74 constexpr uint32_t MAX_INT32_LENGTH = 11; // -2147483648 ~ 2147483647
75 constexpr uint32_t MAX_INT64_LENGTH = 20; // -9223372036854775808 ~ 9223372036854775807
76 constexpr uint32_t MAX_UINT32_LENGTH = 10; // 0 ~ 4294967295
77 constexpr uint32_t MAX_INT32_LENGTH_BIN = 32;
78 constexpr uint32_t MAX_INT32_LENGTH_HEX = 8;
79 
80 const uint32_t BASE64_UNIT_ONE_PADDING = 1;
81 const uint32_t BASE64_UNIT_TWO_PADDING = 2;
82 const uint32_t BASE64_SRC_UNIT_SIZE = 3;
83 const uint32_t BASE64_DEST_UNIT_SIZE = 4;
84 
85 static std::pair<std::string, int> g_brokerProcessInfo;
86 static constexpr uint8_t STEP_2BIT = 2;
87 static constexpr uint8_t HEX_OFFSET = 4;
88 static constexpr char HEX_TABLE[] = "0123456789ABCDEF";
89 
90 static BeaconLostInfo g_beaconLostInfo = {0, 0, "", 0, 0};
91 static BeaconAbnormalInfo g_beaconAbnormalInfo = {0, 0, "", std::vector<uint8_t>(BEACON_LENGTH_RSSI)};
92 
93 constexpr int BEACON_LOST_MIN_CNT = 5; // 12s/(3s/time)
94 constexpr int BEACON_ABN_MIN_CNT = 3; // 5s/(3s/time)
95 
96 constexpr int IP_ADDRESS_FIRST_BYTE_OFFSET = 24;
97 constexpr int IP_ADDRESS_SECOND_BYTE_OFFSET = 16;
98 constexpr int IP_ADDRESS_THIRD_BYTE_OFFSET = 8;
99 constexpr int IP_ADDRESS_BYTE_LEN = 4;
100 constexpr int IP_ADDRESS_FIRST_BYTE_INDEX = 0;
101 constexpr int IP_ADDRESS_SECOND_BYTE_INDEX = 1;
102 constexpr int IP_ADDRESS_THIRD_BYTE_INDEX = 2;
103 constexpr int IP_ADDRESS_FOURTH_BYTE_INDEX = 3;
104 constexpr int32_t UID_CALLINGUID_TRANSFORM_DIVISOR = 200000;
105 
106 constexpr int DEFAULT_USER_ID = 100;
107 
DataAnonymize(const std::string str,const char delim,const char hiddenCh,const int startIdx=0)108 static std::string DataAnonymize(const std::string str, const char delim,
109     const char hiddenCh, const int startIdx = 0)
110 {
111     std::string s = str;
112     constexpr auto minDelimSize = 2;
113     constexpr auto minKeepSize = 6;
114     if (std::count(s.begin(), s.end(), delim) < minDelimSize) {
115         if (s.size() <= minKeepSize) {
116             return std::string(s.size(), hiddenCh);
117         }
118         auto idx1 = 2;
119         const auto idx2 = static_cast<int>(s.size() - 4);
120         while (idx1++ < idx2) {
121             s[idx1] = hiddenCh;
122         }
123         return s;
124     }
125 
126     std::string::size_type begin = s.find_first_of(delim);
127     std::string::size_type end = s.find_last_of(delim);
128     int idx = 0;
129     while (idx++ < startIdx && begin < end) {
130         begin = s.find_first_of(delim, begin + 1);
131     }
132     while (begin++ != end) {
133         if (s[begin] != delim) {
134             s[begin] = hiddenCh;
135         }
136     }
137     return s;
138 }
139 
MacAnonymize(const std::string str)140 std::string MacAnonymize(const std::string str)
141 {
142     return DataAnonymize(str, ':', '*', 1);
143 }
144 
IpAnonymize(const std::string str)145 std::string IpAnonymize(const std::string str)
146 {
147     return DataAnonymize(str, '.', '*');
148 }
149 
SsidAnonymize(const std::string str)150 std::string SsidAnonymize(const std::string str)
151 {
152     if (str.empty()) {
153         return str;
154     }
155 
156     std::string s = str;
157     constexpr char hiddenChar = '*';
158     constexpr size_t minHiddenSize = 3;
159     constexpr size_t headKeepSize = 3;
160     constexpr size_t tailKeepSize = 3;
161     auto func = [hiddenChar](char& c) { c = hiddenChar; };
162     if (s.size() < minHiddenSize) {
163         std::for_each(s.begin(), s.end(), func);
164         return s;
165     }
166 
167     if (s.size() < (minHiddenSize + headKeepSize + tailKeepSize)) {
168         size_t beginIndex = 1;
169         size_t hiddenSize = s.size() - minHiddenSize + 1;
170         hiddenSize = hiddenSize > minHiddenSize ? minHiddenSize : hiddenSize;
171         std::for_each(s.begin() + beginIndex, s.begin() + beginIndex + hiddenSize, func);
172         return s;
173     }
174     std::for_each(s.begin() + headKeepSize, s.begin() + s.size() - tailKeepSize, func);
175     return s;
176 }
177 
PassWordAnonymize(const std::string str)178 std::string PassWordAnonymize(const std::string str)
179 {
180     if (str.size() < PASSWORD_MIN_LEN) {
181         WIFI_LOGE("Password should not shorter than 8");
182         return "";
183     }
184     std::string s = str;
185     auto func = [](char& c) { c = HIDDEN_CHAR_SHOW_AS; };
186     std::for_each(s.begin() + PASSWORD_NO_HIDDEN_LEN, s.end() - PASSWORD_NO_HIDDEN_LEN, func);
187     return s;
188 }
189 
ConvertStrChar(char ch)190 static unsigned char ConvertStrChar(char ch)
191 {
192     constexpr int numDiffForHexAlphabet = 10;
193     if (ch >= '0' && ch <= '9') {
194         return (ch - '0');
195     }
196     if (ch >= 'A' && ch <= 'F') {
197         return (ch - 'A' + numDiffForHexAlphabet);
198     }
199     if (ch >= 'a' && ch <= 'f') {
200         return (ch - 'a' + numDiffForHexAlphabet);
201     }
202     return 0;
203 }
204 
MacStrToArray(const std::string & strMac,unsigned char mac[WIFI_MAC_LEN])205 errno_t MacStrToArray(const std::string& strMac, unsigned char mac[WIFI_MAC_LEN])
206 {
207     char tempArray[STRING_MAC_LEN] = { 0 };
208     errno_t ret = memcpy_s(tempArray, STRING_MAC_LEN, strMac.c_str(), strMac.size() + 1);
209     if (ret != EOK) {
210         return ret;
211     }
212 
213     int idx = 0;
214     constexpr int bitWidth = 4;
215     char *ptr = nullptr;
216     char *p = strtok_s(tempArray, ":", &ptr);
217     while ((p != nullptr) && (idx < WIFI_MAC_LEN)) {
218         mac[idx++] = (ConvertStrChar(*p) << bitWidth) | ConvertStrChar(*(p + 1));
219         p = strtok_s(nullptr, ":", &ptr);
220     }
221     return EOK;
222 }
223 
ConvertArrayChar(unsigned char ch)224 static char ConvertArrayChar(unsigned char ch)
225 {
226     constexpr int maxDecNum = 9;
227     constexpr int numDiffForHexAlphabet = 10;
228     if (ch <= maxDecNum) {
229         return '0' + ch;
230     }
231     if (ch <= 0xf) {
232         return ch + 'a' - numDiffForHexAlphabet;
233     }
234     return '0';
235 }
236 
MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])237 std::string MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])
238 {
239     constexpr int bitWidth = 4;
240     constexpr int noColonBit = 5;
241     std::stringstream ss;
242     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
243         ss << ConvertArrayChar(mac[i] >> bitWidth) << ConvertArrayChar(mac[i] & 0xf);
244         if (i != noColonBit) {
245             ss << ":";
246         }
247     }
248     return ss.str();
249 }
250 
IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])251 bool IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])
252 {
253     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
254         if (mac[i] != 0) {
255             return false;
256         }
257     }
258     return true;
259 }
260 
Ip2Number(const std::string & strIp)261 unsigned int Ip2Number(const std::string& strIp)
262 {
263     std::string::size_type start = 0;
264     std::string::size_type end = 0;
265     std::vector<std::string> subStrList;
266     std::string ip(strIp + '.');
267     while ((end = ip.find_first_of('.', start)) != (std::string::size_type)std::string::npos) {
268         subStrList.push_back(ip.substr(start, end - start));
269         start = end + 1;
270     }
271 
272     unsigned int number = 0;
273     if (subStrList.size() != IP_ADDRESS_BYTE_LEN) {
274         WIFI_LOGE("ip address format check error");
275         return number;
276     }
277 
278     number = static_cast<unsigned long>(
279         (CheckDataLegal(subStrList[IP_ADDRESS_FIRST_BYTE_INDEX]) << IP_ADDRESS_FIRST_BYTE_OFFSET) |
280         (CheckDataLegal(subStrList[IP_ADDRESS_SECOND_BYTE_INDEX]) << IP_ADDRESS_SECOND_BYTE_OFFSET) |
281         (CheckDataLegal(subStrList[IP_ADDRESS_THIRD_BYTE_INDEX]) << IP_ADDRESS_THIRD_BYTE_OFFSET) |
282         CheckDataLegal(subStrList[IP_ADDRESS_FOURTH_BYTE_INDEX]));
283     return number;
284 }
285 
Number2Ip(unsigned int intIp)286 std::string Number2Ip(unsigned int intIp)
287 {
288     std::string ip;
289     ip.append(std::to_string((intIp & 0xff000000) >> IP_ADDRESS_FIRST_BYTE_OFFSET));
290     ip.push_back('.');
291     ip.append(std::to_string((intIp & 0x00ff0000) >> IP_ADDRESS_SECOND_BYTE_OFFSET));
292     ip.push_back('.');
293     ip.append(std::to_string((intIp & 0x0000ff00) >> IP_ADDRESS_THIRD_BYTE_OFFSET));
294     ip.push_back('.');
295     ip.append(std::to_string(intIp & 0x000000ff));
296     return ip;
297 }
298 
StrSplit(const std::string & str,const std::string & delim)299 std::vector<std::string> StrSplit(const std::string& str, const std::string& delim) {
300     std::regex re(delim);
301     std::sregex_token_iterator
302         first{ str.begin(), str.end(), re, -1 },
303         last;
304     return { first, last };
305 }
306 
GetCurrentTimeSeconds()307 int64_t GetCurrentTimeSeconds()
308 {
309     auto now = std::chrono::system_clock::now();
310     auto nowMs = std::chrono::time_point_cast<std::chrono::seconds>(now);
311     auto value = nowMs.time_since_epoch();
312     return value.count();
313 }
314 
GetCurrentTimeMilliSeconds()315 int64_t GetCurrentTimeMilliSeconds()
316 {
317     auto now = std::chrono::system_clock::now();
318     auto nowMs = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
319     auto value = nowMs.time_since_epoch();
320     return value.count();
321 }
322 
GetElapsedMicrosecondsSinceBoot()323 int64_t GetElapsedMicrosecondsSinceBoot()
324 {
325     struct timespec times = {0, 0};
326     clock_gettime(CLOCK_BOOTTIME, &times);
327     return static_cast<int64_t>(times.tv_sec) * SECOND_TO_MICROSECOND + times.tv_nsec / MICROSECOND_TO_NANOSECOND;
328 }
329 
330 #ifndef OHOS_ARCH_LITE
GetBundleManager()331 sptr<AppExecFwk::IBundleMgr> GetBundleManager()
332 {
333     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
334     if (systemManager == nullptr) {
335         WIFI_LOGE("Get system ability manager failed!");
336         return nullptr;
337     }
338     return iface_cast<AppExecFwk::IBundleMgr>(systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID));
339 }
340 
GetBundleName()341 std::string GetBundleName()
342 {
343     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
344     if (bundleInstance == nullptr) {
345         WIFI_LOGE("bundle instance is null!");
346         return "";
347     }
348 
349     AppExecFwk::BundleInfo bundleInfo;
350     auto ret = bundleInstance->GetBundleInfoForSelf(0, bundleInfo);
351     if (ret != OHOS::ERR_OK) {
352         return "";
353     }
354 
355     WIFI_LOGI("Get bundle name uid[%{public}d]: %{public}s", bundleInfo.uid, bundleInfo.name.c_str());
356     return bundleInfo.name;
357 }
358 
GetBundleAppIdByBundleName(const int callingUid,const std::string & bundleName)359 std::string GetBundleAppIdByBundleName(const int callingUid, const std::string &bundleName)
360 {
361     int userId = static_cast<int32_t>(GetCallingUid() / UID_CALLINGUID_TRANSFORM_DIVISOR);
362     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
363     if (bundleInstance == nullptr) {
364         WIFI_LOGE("bundle instance is null!");
365         return "";
366     }
367 
368     AppExecFwk::BundleInfo bundleInfo;
369     AppExecFwk::GetBundleInfoFlag bundleInfoFlag = AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO;
370     auto ret = bundleInstance->GetBundleInfoV9(bundleName, static_cast<int32_t>(bundleInfoFlag), bundleInfo, userId);
371     if (ret != OHOS::ERR_OK) {
372         return "";
373     }
374     return bundleInfo.signatureInfo.appIdentifier;
375 }
376 
IsBundleInstalled(const std::string & bundleName)377 bool IsBundleInstalled(const std::string &bundleName)
378 {
379     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
380     if (bundleInstance == nullptr) {
381         WIFI_LOGE("bundle instance is null!");
382         return false;
383     }
384 
385     AppExecFwk::BundleInfo bundleInfo;
386     bool isInstalled = bundleInstance->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT,
387         bundleInfo, DEFAULT_USER_ID);
388     WIFI_LOGI("Bundle %{public}s is Installed: %{public}d", bundleName.c_str(), isInstalled);
389     return isInstalled;
390 }
391 
GetBundleNameByUid(const int uid,std::string & bundleName)392 ErrCode GetBundleNameByUid(const int uid, std::string &bundleName)
393 {
394     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
395     if (bundleInstance == nullptr) {
396         WIFI_LOGE("%{public}s bundle instance is null!", __FUNCTION__);
397         return WIFI_OPT_FAILED;
398     }
399     if (!bundleInstance->GetBundleNameForUid(uid, bundleName)) {
400         WIFI_LOGD("%{public}s get bundleName failed", __FUNCTION__);
401         return WIFI_OPT_FAILED;
402     }
403     return WIFI_OPT_SUCCESS;
404 }
405 
GetAllBundleName(std::vector<std::string> & bundleNameList)406 ErrCode GetAllBundleName(std::vector<std::string> &bundleNameList)
407 {
408     return WIFI_OPT_SUCCESS;
409 }
410 
GetCallingPid()411 int GetCallingPid()
412 {
413     return IPCSkeleton::GetCallingPid();
414 }
415 
GetCallingUid()416 int GetCallingUid()
417 {
418     return IPCSkeleton::GetCallingUid();
419 }
420 
GetCallingTokenId()421 int GetCallingTokenId()
422 {
423     return IPCSkeleton::GetCallingTokenID();
424 }
425 
GetBrokerProcessNameByPid(const int uid,const int pid)426 std::string GetBrokerProcessNameByPid(const int uid, const int pid)
427 {
428     std::string processName = "";
429     if (g_brokerProcessInfo.second == pid) {
430         processName = g_brokerProcessInfo.first;
431     }
432     return processName;
433 }
434 
SetWifiBrokerProcess(int pid,std::string processName)435 void SetWifiBrokerProcess(int pid, std::string processName)
436 {
437     WIFI_LOGD("enter SetWifiBrokerProcess");
438     g_brokerProcessInfo = make_pair(processName, pid);
439 }
440 
TimeStats(const std::string desc)441 TimeStats::TimeStats(const std::string desc): m_desc(desc)
442 {
443     m_startTime = std::chrono::steady_clock::now();
444     WIFI_LOGI("[Time stats][start] %{public}s.", m_desc.c_str());
445 }
446 
~TimeStats()447 TimeStats::~TimeStats()
448 {
449     auto us = std::chrono::duration_cast<std::chrono::microseconds>
450         (std::chrono::steady_clock::now() - m_startTime).count();
451     constexpr int TIME_BASE = 1000;
452     WIFI_LOGI("[Time stats][end] %{public}s, time cost:%{public}lldus, %{public}lldms, %{public}llds",
453         m_desc.c_str(), us, us / TIME_BASE, us / TIME_BASE / TIME_BASE);
454 }
455 #endif
456 
FrequencyToChannel(int freq)457 int FrequencyToChannel(int freq)
458 {
459     WIFI_LOGD("FrequencyToChannel: %{public}d", freq);
460     int channel = INVALID_FREQ_OR_CHANNEL;
461     if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
462         channel = (freq - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
463     } else if (freq == CHANNEL_14_FREQ) {
464         channel = CHANNEL_14;
465     } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
466         channel = (freq - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
467     }
468     return channel;
469 }
470 
ChannelToFrequency(int channel)471 int ChannelToFrequency(int channel)
472 {
473     WIFI_LOGI("ChannelToFrequency: %{public}d", channel);
474     if (channel >= MIN_24G_CHANNEL && channel <= MAX_24G_CHANNEL) {
475         return ((channel - MIN_24G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_1);
476     }
477     if (MIN_5G_CHANNEL <= channel && channel <= MAX_5G_CHANNEL) {
478         return ((channel - MIN_5G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_36);
479     }
480     return INVALID_FREQ_OR_CHANNEL;
481 }
482 
IsOtherVapConnect()483 bool IsOtherVapConnect()
484 {
485     WIFI_LOGD("Enter IsOtherVapConnect");
486     int n;
487     int ret;
488     struct ifaddrs *ifaddr = nullptr;
489     struct ifaddrs *ifa = nullptr;
490     bool p2pOrHmlConnected = false;
491     bool hotspotEnable = false;
492     if (getifaddrs(&ifaddr) == -1) {
493         WIFI_LOGE("getifaddrs failed, error is %{public}d", errno);
494         return false;
495     }
496     for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++) {
497         if (ifa->ifa_addr == nullptr) {
498             continue;
499         }
500         /* For an AF_INET interface address, display the address */
501         int family = ifa->ifa_addr->sa_family;
502         char ipAddress[NI_MAXHOST] = {0}; /* IP address storage */
503         if (family == AF_INET) {
504             ret = getnameinfo(ifa->ifa_addr,
505                 sizeof(struct sockaddr_in),
506                 ipAddress,
507                 NI_MAXHOST,
508                 nullptr,
509                 0,
510                 NI_NUMERICHOST);
511             if (ret != 0) {
512                 WIFI_LOGE("getnameinfo() failed: %{public}s\n", gai_strerror(ret));
513                 return false;
514             }
515         }
516         if (strncmp("192", ipAddress, PRIFIX_IP_LEN) != 0 && strncmp("172", ipAddress, PRIFIX_IP_LEN) != 0) {
517             continue;
518         }
519         if ((strncmp("p2p", ifa->ifa_name, PRIFIX_P2P_LEN) == 0 ||
520              strncmp("chba", ifa->ifa_name, PRIFIX_CHBA_LEN) == 0)) {
521             p2pOrHmlConnected = true;
522         }
523         if (strncmp("wlan1", ifa->ifa_name, PRIFIX_WLAN1_LEN) == 0) {
524             hotspotEnable = true;
525         }
526     }
527     freeifaddrs(ifaddr);
528     return p2pOrHmlConnected && hotspotEnable;
529 }
530 
IsBeaconLost(std::string bssid,WifiSignalPollInfo checkInfo)531 bool IsBeaconLost(std::string bssid, WifiSignalPollInfo checkInfo)
532 {
533     const int64_t checkTime = checkInfo.timeStamp;
534     const int checkRssi = checkInfo.signal;
535     const unsigned int checkRxBytes = checkInfo.rxBytes;
536 
537     // 检查 BSSID、RSSI 和 RxBytes 是否与初始值一致
538     if (g_beaconLostInfo.bssid != bssid || g_beaconLostInfo.rssi != checkRssi
539         || g_beaconLostInfo.rxBytes != checkRxBytes) {
540         g_beaconLostInfo.bssid = bssid;
541         g_beaconLostInfo.rssi = checkRssi;
542         g_beaconLostInfo.rxBytes = checkRxBytes;
543         g_beaconLostInfo.time = 0;
544         g_beaconLostInfo.cnt = 0;
545         return false;
546     }
547     if (checkInfo.ext.size() < BEACON_LENGTH_RSSI) {
548         g_beaconLostInfo.time = 0;
549         g_beaconLostInfo.cnt = 0;
550         return false;
551     }
552      // 检查 RSSI 是否无效
553     const auto* extData = checkInfo.ext.data();
554     bool isInvalid = std::all_of(extData, extData + BEACON_LENGTH_RSSI, [](uint8_t num) {
555             int8_t val = static_cast<int8_t>(num);
556             return val == BEACON_LOST_RSSI0 || val == BEACON_LOST_RSSI1 || val == 0;
557         }) && std::any_of(extData, extData + BEACON_LENGTH_RSSI,
558         [](uint8_t num) { return static_cast<int8_t>(num) == BEACON_LOST_RSSI0; });
559     if (!isInvalid) {
560         g_beaconLostInfo.time = 0;
561         g_beaconLostInfo.cnt = 0;
562         return false;
563     }
564     g_beaconLostInfo.cnt += 1;
565     if (g_beaconLostInfo.time == 0) {
566         g_beaconLostInfo.time = checkTime;
567         return false;
568     }
569     int64_t accumulateTime = checkTime - g_beaconLostInfo.time;
570     if (accumulateTime <= 0) {
571         g_beaconLostInfo.time = checkTime;
572         g_beaconLostInfo.cnt = 1;
573         return false;
574     }
575     if (accumulateTime >= SIGNAL_RECORD_12S && g_beaconLostInfo.cnt >= BEACON_LOST_MIN_CNT) {
576         g_beaconLostInfo.time = checkTime;
577         g_beaconLostInfo.cnt = 1;
578         return true;
579     }
580     return false;
581 }
582 
IsBeaconAbnormal(std::string bssid,WifiSignalPollInfo checkInfo)583 bool IsBeaconAbnormal(std::string bssid, WifiSignalPollInfo checkInfo)
584 {
585     const int64_t checkTime = checkInfo.timeStamp;
586     // 检查 BSSID是否与初始值一致
587     if (g_beaconAbnormalInfo.bssid != bssid) {
588         g_beaconAbnormalInfo.bssid = bssid;
589         g_beaconAbnormalInfo.time = 0;
590         g_beaconAbnormalInfo.cnt = 0;
591         return false;
592     }
593     if (checkInfo.ext.size() < BEACON_LENGTH_RSSI) {
594         g_beaconAbnormalInfo.time = 0;
595         g_beaconAbnormalInfo.cnt = 0;
596         return false;
597     }
598     // 检查未平滑rssi数组是否相等
599     bool areVectorsEqual = true;
600     for (int i = 0; i < BEACON_LENGTH_RSSI; i++) {
601         if (g_beaconAbnormalInfo.rssiArr[i] != checkInfo.ext[i]) {
602             g_beaconAbnormalInfo.rssiArr[i] = checkInfo.ext[i];
603             areVectorsEqual = false;
604         }
605     }
606     if (!areVectorsEqual) {
607         g_beaconAbnormalInfo.time = checkTime;
608         g_beaconAbnormalInfo.cnt = 1;
609         return false;
610     }
611     g_beaconAbnormalInfo.cnt += 1;
612     if (g_beaconAbnormalInfo.time == 0) {
613         g_beaconAbnormalInfo.time = checkTime;
614         return false;
615     }
616     int64_t accumulateTime = checkTime - g_beaconAbnormalInfo.time;
617     if (accumulateTime <= 0) {
618         g_beaconAbnormalInfo.time = checkTime;
619         g_beaconAbnormalInfo.cnt = 1;
620         return false;
621     }
622     if (accumulateTime >= SIGNAL_RECORD_5S && g_beaconAbnormalInfo.cnt >= BEACON_ABN_MIN_CNT) {
623         g_beaconAbnormalInfo.time = checkTime;
624         g_beaconAbnormalInfo.cnt = 1;
625         return true;
626     }
627     return false;
628 }
629 
Hex2num(char c)630 static int Hex2num(char c)
631 {
632     if (c >= '0' && c <= '9') {
633         return c - '0';
634     }
635     if (c >= 'a' && c <= 'f') {
636         return c - 'a' + 10; // convert to decimal
637     }
638     if (c >= 'A' && c <= 'F') {
639         return c - 'A' + 10; // convert to decimal
640     }
641     return -1;
642 }
643 
Hex2byte(const char * hex)644 int Hex2byte(const char *hex)
645 {
646     int a = Hex2num(*hex++);
647     if (a < 0) {
648         return -1;
649     }
650     int b = Hex2num(*hex++);
651     if (b < 0) {
652         return -1;
653     }
654     return (a << 4) | b; // convert to binary
655 }
656 
HexString2Byte(const char * hex,uint8_t * buf,size_t len)657 int HexString2Byte(const char *hex, uint8_t *buf, size_t len)
658 {
659     size_t i;
660     int a;
661     const char *ipos = hex;
662     uint8_t *opos = buf;
663 
664     for (i = 0; i < len; i++) {
665         a = Hex2byte(ipos);
666         if (a < 0) {
667             return -1;
668         }
669         *opos++ = a;
670         ipos += 2; // convert to binary
671     }
672     return 0;
673 }
674 
Byte2HexString(const uint8_t * byte,uint8_t bytesLen,char * hexstr,uint8_t hexstrLen)675 void Byte2HexString(const uint8_t* byte, uint8_t bytesLen, char* hexstr, uint8_t hexstrLen)
676 {
677     if ((byte == nullptr) || (hexstr == nullptr)) {
678         WIFI_LOGE("%{public}s: invalid parameter", __func__);
679         return;
680     }
681 
682     if (hexstrLen < bytesLen * 2) { // verify length
683         WIFI_LOGE("%{public}s: invalid byteLen:%{public}d or hexStrLen:%{public}d",
684             __func__, bytesLen, hexstrLen);
685         return;
686     }
687 
688     WIFI_LOGI("%{public}s byteLen:%{public}d, hexStrLen:%{public}d", __func__, bytesLen, hexstrLen);
689     uint8_t hexstrIndex = 0;
690     for (uint8_t i = 0; i < bytesLen; i++) {
691         if (snprintf_s(hexstr + hexstrIndex, hexstrLen - hexstrIndex, hexstrLen - hexstrIndex - 1,
692             "%02x", byte[i]) <= 0) {
693             WIFI_LOGI("%{public}s: failed to snprintf_s", __func__);
694         }
695         hexstrIndex += 2; // offset
696         if (hexstrIndex >= hexstrLen) {
697             break;
698         }
699     }
700 }
701 
DecodeBase64(const std::string & input,std::vector<uint8_t> & output)702 bool DecodeBase64(const std::string &input, std::vector<uint8_t> &output)
703 {
704 #ifndef OHOS_ARCH_LITE
705     WIFI_LOGD("%{public}s input:%{private}s, length:%{public}zu", __func__, input.c_str(), input.length());
706     if (input.length() % BASE64_DEST_UNIT_SIZE != 0) {
707         WIFI_LOGE("%{public}s: wrong data length for base64 encode string", __func__);
708         return false;
709     }
710     uint32_t decodedLen = input.length() * BASE64_SRC_UNIT_SIZE / BASE64_DEST_UNIT_SIZE;
711     if (input.at(input.length() - BASE64_UNIT_ONE_PADDING) == '=') {
712         decodedLen--;
713         if (input.at(input.length() - BASE64_UNIT_TWO_PADDING) == '=') {
714             decodedLen--;
715         }
716     }
717     output.resize(decodedLen);
718 
719     BIO *b64 = BIO_new(BIO_f_base64());
720     if (b64 == nullptr) {
721         WIFI_LOGE("%{public}s: failed to create b64", __func__);
722         return false;
723     }
724     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
725     BIO *bio = BIO_new_mem_buf(input.c_str(), input.length());
726     if (bio == nullptr) {
727         WIFI_LOGE("%{public}s: failed to create bio", __func__);
728         BIO_free(b64);
729         return false;
730     }
731     bio = BIO_push(b64, bio);
732     if (BIO_read(bio, &output[0], input.length()) != static_cast<int32_t>(decodedLen)) {
733         WIFI_LOGE("%{public}s: wrong data length for decoded buffer", __func__);
734         BIO_free_all(bio);
735         return false;
736     }
737     BIO_free_all(bio);
738 #endif
739     return true;
740 }
741 
EncodeBase64(const std::vector<uint8_t> & input)742 std::string EncodeBase64(const std::vector<uint8_t> &input)
743 {
744 #ifndef OHOS_ARCH_LITE
745     WIFI_LOGD("%{public}s: size:%{public}zu", __func__, input.size());
746     if (input.empty()) {
747         WIFI_LOGE("%{public}s: wrong data length for string to encode.", __func__);
748         return "";
749     }
750     BIO *b64 = BIO_new(BIO_f_base64());
751     if (b64 == nullptr) {
752         WIFI_LOGE("%{public}s: failed to create b64", __func__);
753         return "";
754     }
755     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
756     BIO *bio = BIO_new(BIO_s_mem());
757     if (bio == nullptr) {
758         WIFI_LOGE("%{public}s: failed to create bio", __func__);
759         BIO_free(b64);
760         return "";
761     }
762     bio = BIO_push(b64, bio);
763     BIO_write(bio, &input[0], input.size());
764     BIO_flush(bio);
765 
766     BUF_MEM *bptr = nullptr;
767     BIO_get_mem_ptr(bio, &bptr);
768     std::string output = "";
769     if (bptr != nullptr) {
770         std::vector<char> outputBuffer {};
771         WIFI_LOGI("%{public}s: length is %{public}zu", __func__, bptr->length);
772         outputBuffer.insert(outputBuffer.end(), bptr->data, bptr->data + bptr->length);
773         outputBuffer[bptr->length] = 0;
774         output = static_cast<char*>(&outputBuffer[0]);
775     }
776     BIO_free_all(bio);
777     return output;
778 #else
779     return "";
780 #endif
781 }
782 
GetSplitInfo(const std::string & input,const std::string & delimiter)783 std::vector<std::string> GetSplitInfo(const std::string &input, const std::string &delimiter)
784 {
785     size_t start = 0;
786     size_t pos = 0;
787     std::vector<std::string> results;
788     if (input.empty() || delimiter.empty()) {
789         WIFI_LOGE("%{public}s: invalid input or delimiter", __func__);
790         return results;
791     }
792 
793     if (input.length() < delimiter.length()) {
794         WIFI_LOGE("%{public}s: invalid input length", __func__);
795         return results;
796     }
797 
798     WIFI_LOGD("%{public}s input:%{private}s, delimiter:%{public}s", __func__, input.c_str(), delimiter.c_str());
799     while ((pos = input.find(delimiter, start)) != std::string::npos) {
800         if (pos > start) {
801             results.push_back(input.substr(start, pos - start));
802         }
803         start = pos + delimiter.length();
804     }
805     if (start < input.length()) {
806         results.push_back(input.substr(start));
807     }
808     WIFI_LOGD("%{public}s size:%{public}zu", __func__, results.size());
809     return results;
810 }
811 
HexToString(const std::string & str)812 std::string HexToString(const std::string &str)
813 {
814     std::string result;
815     if (str.length() <= 0) {
816         return result;
817     }
818     for (size_t i = 0; i < str.length() - 1; i += STEP_2BIT) {
819         std::string byte = str.substr(i, STEP_2BIT);
820         char chr = 0;
821         int strTemp = CheckDataLegalHex(byte);
822         if (strTemp > 0) {
823             chr = static_cast<char>(strTemp);
824         }
825         result.push_back(chr);
826     }
827     return result;
828 }
829 
StringToHex(const std::string & data)830 std::string StringToHex(const std::string &data)
831 {
832     std::stringstream ss;
833     for (std::string::size_type i = 0; i < data.size(); ++i) {
834         unsigned char temp = static_cast<unsigned char>(data[i]) >> HEX_OFFSET;
835         ss << HEX_TABLE[temp] << HEX_TABLE[static_cast<unsigned char>(data[i]) & 0xf];
836     }
837     return ss.str();
838 }
839 
CheckDataLegalBin(const std::string & data)840 int CheckDataLegalBin(const std::string &data)
841 {
842     if (data.empty() || data.size() > MAX_INT32_LENGTH_BIN) {
843         WIFI_LOGE("CheckDataLegalBin: invalid data:%{private}s", data.c_str());
844         return 0;
845     }
846 
847     std::regex pattern("[0-1]+");
848     if (!std::regex_match(data, pattern)) {
849         return 0;
850     }
851     errno = 0;
852     char *endptr = nullptr;
853     long int num = std::strtol(data.c_str(), &endptr, BASE_BIN);
854     if (errno == ERANGE) {
855         WIFI_LOGE("CheckDataLegalBin errno == ERANGE, data:%{private}s", data.c_str());
856         return 0;
857     }
858 
859     return static_cast<int>(num);
860 }
861 
CheckDataLegalHex(const std::string & data)862 int CheckDataLegalHex(const std::string &data)
863 {
864     if (data.empty() || data.size() > MAX_INT32_LENGTH_HEX) {
865         WIFI_LOGE("CheckDataLegalHex: invalid data:%{private}s", data.c_str());
866         return 0;
867     }
868 
869     std::regex pattern("[0-9a-fA-F]+");
870     if (!std::regex_match(data, pattern)) {
871         return 0;
872     }
873     errno = 0;
874     char *endptr = nullptr;
875     long int num = std::strtol(data.c_str(), &endptr, BASE_HEX);
876     if (errno == ERANGE) {
877         WIFI_LOGE("CheckDataLegalHex errno == ERANGE, data:%{private}s", data.c_str());
878         return 0;
879     }
880 
881     return static_cast<int>(num);
882 }
883 
CheckDataLegal(std::string & data,int base)884 int CheckDataLegal(std::string &data, int base)
885 {
886     if (data.empty() || data.size() > MAX_INT32_LENGTH) {
887         WIFI_LOGE("CheckDataLegal: invalid data:%{private}s", data.c_str());
888         return 0;
889     }
890 
891     std::regex pattern("-?\\d+");
892     if (!std::regex_match(data, pattern)) {
893         return 0;
894     }
895     errno = 0;
896     char *endptr = nullptr;
897     long int num = std::strtol(data.c_str(), &endptr, base);
898     if (errno == ERANGE) {
899         WIFI_LOGE("CheckDataLegal errno == ERANGE, data:%{private}s", data.c_str());
900         return 0;
901     }
902 
903     return static_cast<int>(num);
904 }
905 
CheckDataToUint(std::string & data,int base)906 unsigned int CheckDataToUint(std::string &data, int base)
907 {
908     if (data.empty() || data.size() > MAX_UINT32_LENGTH) {
909         WIFI_LOGE("CheckDataToUint: invalid data:%{private}s", data.c_str());
910         return 0;
911     }
912     std::regex pattern("\\d+");
913     if (!std::regex_match(data, pattern)) {
914         WIFI_LOGE("CheckDataToUint regex unsigned int value fail, data:%{private}s", data.c_str());
915         return 0;
916     }
917 
918     errno = 0;
919     char *endptr = nullptr;
920     unsigned long int num = std::strtoul(data.c_str(), &endptr, base);
921     if (errno == ERANGE) {
922         WIFI_LOGE("CheckDataToUint errno == ERANGE, data:%{private}s", data.c_str());
923         return 0;
924     }
925 
926     return static_cast<unsigned int>(num);
927 }
928 
CheckDataTolonglong(std::string & data,int base)929 long long CheckDataTolonglong(std::string &data, int base)
930 {
931     if (data.empty() || data.size() > MAX_INT64_LENGTH) {
932         WIFI_LOGE("CheckDataTolonglong: invalid data:%{private}s", data.c_str());
933         return 0;
934     }
935 
936     std::regex pattern("-?\\d+");
937     if (!std::regex_match(data, pattern)) {
938         return 0;
939     }
940     errno = 0;
941     char *endptr = nullptr;
942     long long int num = std::strtoll(data.c_str(), &endptr, base);
943     if (errno == ERANGE) {
944         WIFI_LOGE("CheckDataTolonglong errno == ERANGE, data:%{private}s", data.c_str());
945         return 0;
946     }
947     return num;
948 }
949 
StringToUlong(const std::string & word)950 unsigned long StringToUlong(const std::string &word)
951 {
952     unsigned long result;
953     std::istringstream(word) >> result;
954     return result;
955 }
956 
StringToFloat(const std::string & word)957 float StringToFloat(const std::string &word)
958 {
959     float result;
960     std::istringstream(word) >> result;
961     return result;
962 }
963 
StringToDouble(const std::string & word)964 double StringToDouble(const std::string &word)
965 {
966     double result;
967     std::istringstream(word) >> result;
968     return result;
969 }
970 
GenerateStandardErrCode(uint8_t subSystem,uint16_t errCode)971 uint32_t GenerateStandardErrCode(uint8_t subSystem, uint16_t errCode)
972 {
973     uint8_t standardSubSystem = subSystem & 0x1F;
974     return (WIFI_SYSTEM_ID << SYSTEM_OFFSET | standardSubSystem << SUB_SYSTEM_OFFSET | errCode);
975 }
976 
InternalHiLinkNetworkToBool(int isHiLinkNetwork)977 bool InternalHiLinkNetworkToBool(int isHiLinkNetwork)
978 {
979     return (isHiLinkNetwork > 0 && isHiLinkNetwork <= INTERNAL_HILINK_MAX_VALUE) ? true : false;
980 }
981 
Ipv4IntAnonymize(uint32_t ipInt)982 std::string Ipv4IntAnonymize(uint32_t ipInt)
983 {
984     // convert uint32_t to string
985     std::string address;
986     if (ipInt == 0) {
987         return address;
988     }
989     std::ostringstream stream;
990     stream << ((ipInt >> BITS_24) & 0xFF) << "." << ((ipInt >> BITS_16) & 0xFF) << "."
991     << ((ipInt >> BITS_8) & 0xFF) << "." << (ipInt & 0xFF);
992     address = stream.str();
993     return IpAnonymize(address);
994 }
995 
Ipv6Anonymize(std::string str)996 std::string Ipv6Anonymize(std::string str)
997 {
998     return DataAnonymize(str, ':', '*', 1);
999 }
1000 }  // namespace Wifi
1001 }  // namespace OHOS
1002