• 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 
22 #ifndef OHOS_ARCH_LITE
23 #include <vector>
24 #include <openssl/bio.h>
25 #include <openssl/evp.h>
26 #include <openssl/pem.h>
27 #include <openssl/x509.h>
28 #include "bundle_mgr_interface.h"
29 #include "if_system_ability_manager.h"
30 #include "ipc_skeleton.h"
31 #include "iservice_registry.h"
32 #include "system_ability_definition.h"
33 #include "common_timer_errors.h"
34 #endif
35 #include "wifi_logger.h"
36 #include <ifaddrs.h>
37 #include <net/if.h>
38 #include <netdb.h>
39 #include <cerrno>
40 
41 namespace OHOS {
42 namespace Wifi {
43 DEFINE_WIFILOG_LABEL("WifiCommonUtil");
44 
45 constexpr int PRIFIX_IP_LEN = 3;
46 constexpr int PRIFIX_P2P_LEN = 3;
47 constexpr int PRIFIX_CHBA_LEN = 4;
48 constexpr int PRIFIX_WLAN1_LEN = 5;
49 constexpr int FREQ_2G_MIN = 2412;
50 constexpr int FREQ_2G_MAX = 2472;
51 constexpr int FREQ_5G_MIN = 5170;
52 constexpr int FREQ_5G_MAX = 5825;
53 constexpr int CHANNEL_14_FREQ = 2484;
54 constexpr int CHANNEL_14 = 14;
55 constexpr int CENTER_FREQ_DIFF = 5;
56 constexpr int CHANNEL_2G_MIN = 1;
57 constexpr int CHANNEL_5G_MIN = 34;
58 constexpr int MIN_24G_CHANNEL = 1;
59 constexpr int MAX_24G_CHANNEL = 13;
60 constexpr int MIN_5G_CHANNEL = 36;
61 constexpr int MAX_5G_CHANNEL = 165;
62 constexpr int FREQ_CHANNEL_1 = 2412;
63 constexpr int FREQ_CHANNEL_36 = 5180;
64 constexpr int SECOND_TO_MICROSECOND = 1000 * 1000;
65 constexpr int MICROSECOND_TO_NANOSECOND = 1000;
66 constexpr char HIDDEN_CHAR_SHOW_AS = '*';
67 constexpr int PASSWORD_MIN_LEN = 8;
68 constexpr int PASSWORD_NO_HIDDEN_LEN = 2;
69 
70 constexpr uint32_t BASE_BIN = 2;
71 constexpr uint32_t BASE_HEX = 16;
72 constexpr uint32_t MAX_INT32_LENGTH = 11; // -2147483648 ~ 2147483647
73 constexpr uint32_t MAX_INT64_LENGTH = 20; // -9223372036854775808 ~ 9223372036854775807
74 constexpr uint32_t MAX_UINT32_LENGTH = 10; // 0 ~ 4294967295
75 constexpr uint32_t MAX_INT32_LENGTH_BIN = 32;
76 constexpr uint32_t MAX_INT32_LENGTH_HEX = 8;
77 
78 const uint32_t BASE64_UNIT_ONE_PADDING = 1;
79 const uint32_t BASE64_UNIT_TWO_PADDING = 2;
80 const uint32_t BASE64_SRC_UNIT_SIZE = 3;
81 const uint32_t BASE64_DEST_UNIT_SIZE = 4;
82 
83 static std::pair<std::string, int> g_brokerProcessInfo;
84 static constexpr uint8_t STEP_2BIT = 2;
85 static constexpr uint8_t HEX_OFFSET = 4;
86 static constexpr char HEX_TABLE[] = "0123456789ABCDEF";
87 
88 constexpr int IP_ADDRESS_FIRST_BYTE_OFFSET = 24;
89 constexpr int IP_ADDRESS_SECOND_BYTE_OFFSET = 16;
90 constexpr int IP_ADDRESS_THIRD_BYTE_OFFSET = 8;
91 constexpr int IP_ADDRESS_BYTE_LEN = 4;
92 constexpr int IP_ADDRESS_FIRST_BYTE_INDEX = 0;
93 constexpr int IP_ADDRESS_SECOND_BYTE_INDEX = 1;
94 constexpr int IP_ADDRESS_THIRD_BYTE_INDEX = 2;
95 constexpr int IP_ADDRESS_FOURTH_BYTE_INDEX = 3;
96 
DataAnonymize(const std::string str,const char delim,const char hiddenCh,const int startIdx=0)97 static std::string DataAnonymize(const std::string str, const char delim,
98     const char hiddenCh, const int startIdx = 0)
99 {
100     std::string s = str;
101     constexpr auto minDelimSize = 2;
102     constexpr auto minKeepSize = 6;
103     if (std::count(s.begin(), s.end(), delim) < minDelimSize) {
104         if (s.size() <= minKeepSize) {
105             return std::string(s.size(), hiddenCh);
106         }
107         auto idx1 = 2;
108         const auto idx2 = static_cast<int>(s.size() - 4);
109         while (idx1++ < idx2) {
110             s[idx1] = hiddenCh;
111         }
112         return s;
113     }
114 
115     std::string::size_type begin = s.find_first_of(delim);
116     std::string::size_type end = s.find_last_of(delim);
117     int idx = 0;
118     while (idx++ < startIdx && begin < end) {
119         begin = s.find_first_of(delim, begin + 1);
120     }
121     while (begin++ != end) {
122         if (s[begin] != delim) {
123             s[begin] = hiddenCh;
124         }
125     }
126     return s;
127 }
128 
MacAnonymize(const std::string str)129 std::string MacAnonymize(const std::string str)
130 {
131     return DataAnonymize(str, ':', '*', 1);
132 }
133 
IpAnonymize(const std::string str)134 std::string IpAnonymize(const std::string str)
135 {
136     return DataAnonymize(str, '.', '*');
137 }
138 
SsidAnonymize(const std::string str)139 std::string SsidAnonymize(const std::string str)
140 {
141     if (str.empty()) {
142         return str;
143     }
144 
145     std::string s = str;
146     constexpr char hiddenChar = '*';
147     constexpr size_t minHiddenSize = 3;
148     constexpr size_t headKeepSize = 3;
149     constexpr size_t tailKeepSize = 3;
150     auto func = [hiddenChar](char& c) { c = hiddenChar; };
151     if (s.size() < minHiddenSize) {
152         std::for_each(s.begin(), s.end(), func);
153         return s;
154     }
155 
156     if (s.size() < (minHiddenSize + headKeepSize + tailKeepSize)) {
157         size_t beginIndex = 1;
158         size_t hiddenSize = s.size() - minHiddenSize + 1;
159         hiddenSize = hiddenSize > minHiddenSize ? minHiddenSize : hiddenSize;
160         std::for_each(s.begin() + beginIndex, s.begin() + beginIndex + hiddenSize, func);
161         return s;
162     }
163     std::for_each(s.begin() + headKeepSize, s.begin() + s.size() - tailKeepSize, func);
164     return s;
165 }
166 
PassWordAnonymize(const std::string str)167 std::string PassWordAnonymize(const std::string str)
168 {
169     if (str.size() < PASSWORD_MIN_LEN) {
170         WIFI_LOGE("Password should not shorter than 8");
171         return "";
172     }
173     std::string s = str;
174     auto func = [](char& c) { c = HIDDEN_CHAR_SHOW_AS; };
175     std::for_each(s.begin() + PASSWORD_NO_HIDDEN_LEN, s.end() - PASSWORD_NO_HIDDEN_LEN, func);
176     return s;
177 }
178 
ConvertStrChar(char ch)179 static unsigned char ConvertStrChar(char ch)
180 {
181     constexpr int numDiffForHexAlphabet = 10;
182     if (ch >= '0' && ch <= '9') {
183         return (ch - '0');
184     }
185     if (ch >= 'A' && ch <= 'F') {
186         return (ch - 'A' + numDiffForHexAlphabet);
187     }
188     if (ch >= 'a' && ch <= 'f') {
189         return (ch - 'a' + numDiffForHexAlphabet);
190     }
191     return 0;
192 }
193 
MacStrToArray(const std::string & strMac,unsigned char mac[WIFI_MAC_LEN])194 errno_t MacStrToArray(const std::string& strMac, unsigned char mac[WIFI_MAC_LEN])
195 {
196     constexpr int strMacLen = 18;
197     char tempArray[strMacLen] = { 0 };
198     errno_t ret = memcpy_s(tempArray, strMacLen, strMac.c_str(), strMac.size() + 1);
199     if (ret != EOK) {
200         return ret;
201     }
202 
203     int idx = 0;
204     constexpr int bitWidth = 4;
205     char *ptr = nullptr;
206     char *p = strtok_s(tempArray, ":", &ptr);
207     while ((p != nullptr) && (idx < WIFI_MAC_LEN)) {
208         mac[idx++] = (ConvertStrChar(*p) << bitWidth) | ConvertStrChar(*(p + 1));
209         p = strtok_s(nullptr, ":", &ptr);
210     }
211     return EOK;
212 }
213 
ConvertArrayChar(unsigned char ch)214 static char ConvertArrayChar(unsigned char ch)
215 {
216     constexpr int maxDecNum = 9;
217     constexpr int numDiffForHexAlphabet = 10;
218     if (ch <= maxDecNum) {
219         return '0' + ch;
220     }
221     if (ch <= 0xf) {
222         return ch + 'a' - numDiffForHexAlphabet;
223     }
224     return '0';
225 }
226 
MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])227 std::string MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])
228 {
229     constexpr int bitWidth = 4;
230     constexpr int noColonBit = 5;
231     std::stringstream ss;
232     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
233         ss << ConvertArrayChar(mac[i] >> bitWidth) << ConvertArrayChar(mac[i] & 0xf);
234         if (i != noColonBit) {
235             ss << ":";
236         }
237     }
238     return ss.str();
239 }
240 
IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])241 bool IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])
242 {
243     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
244         if (mac[i] != 0) {
245             return false;
246         }
247     }
248     return true;
249 }
250 
Ip2Number(const std::string & strIp)251 unsigned int Ip2Number(const std::string& strIp)
252 {
253     std::string::size_type start = 0;
254     std::string::size_type end = 0;
255     std::vector<std::string> subStrList;
256     std::string ip(strIp + '.');
257     while ((end = ip.find_first_of('.', start)) != (std::string::size_type)std::string::npos) {
258         subStrList.push_back(ip.substr(start, end - start));
259         start = end + 1;
260     }
261 
262     unsigned int number = 0;
263     if (subStrList.size() != IP_ADDRESS_BYTE_LEN) {
264         WIFI_LOGE("ip address format check error");
265         return number;
266     }
267 
268     number = static_cast<unsigned long>(
269         (CheckDataLegal(subStrList[IP_ADDRESS_FIRST_BYTE_INDEX]) << IP_ADDRESS_FIRST_BYTE_OFFSET) |
270         (CheckDataLegal(subStrList[IP_ADDRESS_SECOND_BYTE_INDEX]) << IP_ADDRESS_SECOND_BYTE_OFFSET) |
271         (CheckDataLegal(subStrList[IP_ADDRESS_THIRD_BYTE_INDEX]) << IP_ADDRESS_THIRD_BYTE_OFFSET) |
272         CheckDataLegal(subStrList[IP_ADDRESS_FOURTH_BYTE_INDEX]));
273     return number;
274 }
275 
Number2Ip(unsigned int intIp)276 std::string Number2Ip(unsigned int intIp)
277 {
278     std::string ip;
279     ip.append(std::to_string((intIp & 0xff000000) >> IP_ADDRESS_FIRST_BYTE_OFFSET));
280     ip.push_back('.');
281     ip.append(std::to_string((intIp & 0x00ff0000) >> IP_ADDRESS_SECOND_BYTE_OFFSET));
282     ip.push_back('.');
283     ip.append(std::to_string((intIp & 0x0000ff00) >> IP_ADDRESS_THIRD_BYTE_OFFSET));
284     ip.push_back('.');
285     ip.append(std::to_string(intIp & 0x000000ff));
286     return ip;
287 }
288 
StrSplit(const std::string & str,const std::string & delim)289 std::vector<std::string> StrSplit(const std::string& str, const std::string& delim) {
290     std::regex re(delim);
291     std::sregex_token_iterator
292         first{ str.begin(), str.end(), re, -1 },
293         last;
294     return { first, last };
295 }
296 
GetCurrentTimeSeconds()297 int64_t GetCurrentTimeSeconds()
298 {
299     auto now = std::chrono::system_clock::now();
300     auto nowMs = std::chrono::time_point_cast<std::chrono::seconds>(now);
301     auto value = nowMs.time_since_epoch();
302     return value.count();
303 }
304 
GetElapsedMicrosecondsSinceBoot()305 int64_t GetElapsedMicrosecondsSinceBoot()
306 {
307     struct timespec times = {0, 0};
308     clock_gettime(CLOCK_BOOTTIME, &times);
309     return static_cast<int64_t>(times.tv_sec) * SECOND_TO_MICROSECOND + times.tv_nsec / MICROSECOND_TO_NANOSECOND;
310 }
311 
312 #ifndef OHOS_ARCH_LITE
GetBundleManager()313 sptr<AppExecFwk::IBundleMgr> GetBundleManager()
314 {
315     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
316     if (systemManager == nullptr) {
317         WIFI_LOGE("Get system ability manager failed!");
318         return nullptr;
319     }
320     return iface_cast<AppExecFwk::IBundleMgr>(systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID));
321 }
322 
GetBundleName()323 std::string GetBundleName()
324 {
325     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
326     if (bundleInstance == nullptr) {
327         WIFI_LOGE("bundle instance is null!");
328         return "";
329     }
330 
331     AppExecFwk::BundleInfo bundleInfo;
332     auto ret = bundleInstance->GetBundleInfoForSelf(0, bundleInfo);
333     if (ret != OHOS::ERR_OK) {
334         return "";
335     }
336 
337     WIFI_LOGI("Get bundle name uid[%{public}d]: %{public}s", bundleInfo.uid, bundleInfo.name.c_str());
338     return bundleInfo.name;
339 }
340 
GetBundleAppIdByBundleName(const int userId,const std::string & bundleName)341 std::string GetBundleAppIdByBundleName(const int userId, const std::string &bundleName)
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     AppExecFwk::GetBundleInfoFlag bundleInfoFlag = AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO;
351     auto ret = bundleInstance->GetBundleInfoV9(bundleName, static_cast<int32_t>(bundleInfoFlag), bundleInfo, userId);
352     if (ret != OHOS::ERR_OK) {
353         return "";
354     }
355     return bundleInfo.signatureInfo.appIdentifier;
356 }
357 
GetBundleNameByUid(const int uid,std::string & bundleName)358 ErrCode GetBundleNameByUid(const int uid, std::string &bundleName)
359 {
360     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
361     if (bundleInstance == nullptr) {
362         WIFI_LOGE("%{public}s bundle instance is null!", __FUNCTION__);
363         return WIFI_OPT_FAILED;
364     }
365     if (!bundleInstance->GetBundleNameForUid(uid, bundleName)) {
366         WIFI_LOGD("%{public}s get bundleName failed", __FUNCTION__);
367         return WIFI_OPT_FAILED;
368     }
369     return WIFI_OPT_SUCCESS;
370 }
371 
GetAllBundleName(std::vector<std::string> & bundleNameList)372 ErrCode GetAllBundleName(std::vector<std::string> &bundleNameList)
373 {
374     return WIFI_OPT_SUCCESS;
375 }
376 
GetCallingPid()377 int GetCallingPid()
378 {
379     return IPCSkeleton::GetCallingPid();
380 }
381 
GetCallingUid()382 int GetCallingUid()
383 {
384     return IPCSkeleton::GetCallingUid();
385 }
386 
GetCallingTokenId()387 int GetCallingTokenId()
388 {
389     return IPCSkeleton::GetCallingTokenID();
390 }
391 
GetBrokerProcessNameByPid(const int uid,const int pid)392 std::string GetBrokerProcessNameByPid(const int uid, const int pid)
393 {
394     std::string processName = "";
395     if (g_brokerProcessInfo.second == pid) {
396         processName = g_brokerProcessInfo.first;
397     }
398     return processName;
399 }
400 
SetWifiBrokerProcess(int pid,std::string processName)401 void SetWifiBrokerProcess(int pid, std::string processName)
402 {
403     WIFI_LOGD("enter SetWifiBrokerProcess");
404     g_brokerProcessInfo = make_pair(processName, pid);
405 }
406 
TimeStats(const std::string desc)407 TimeStats::TimeStats(const std::string desc): m_desc(desc)
408 {
409     m_startTime = std::chrono::steady_clock::now();
410     WIFI_LOGI("[Time stats][start] %{public}s.", m_desc.c_str());
411 }
412 
~TimeStats()413 TimeStats::~TimeStats()
414 {
415     auto us = std::chrono::duration_cast<std::chrono::microseconds>
416         (std::chrono::steady_clock::now() - m_startTime).count();
417     constexpr int TIME_BASE = 1000;
418     WIFI_LOGI("[Time stats][end] %{public}s, time cost:%{public}lldus, %{public}lldms, %{public}llds",
419         m_desc.c_str(), us, us / TIME_BASE, us / TIME_BASE / TIME_BASE);
420 }
421 #endif
422 
FrequencyToChannel(int freq)423 int FrequencyToChannel(int freq)
424 {
425     WIFI_LOGD("FrequencyToChannel: %{public}d", freq);
426     int channel = INVALID_FREQ_OR_CHANNEL;
427     if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
428         channel = (freq - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
429     } else if (freq == CHANNEL_14_FREQ) {
430         channel = CHANNEL_14;
431     } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
432         channel = (freq - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
433     }
434     return channel;
435 }
436 
ChannelToFrequency(int channel)437 int ChannelToFrequency(int channel)
438 {
439     WIFI_LOGI("ChannelToFrequency: %{public}d", channel);
440     if (channel >= MIN_24G_CHANNEL && channel <= MAX_24G_CHANNEL) {
441         return ((channel - MIN_24G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_1);
442     }
443     if (MIN_5G_CHANNEL <= channel && channel <= MAX_5G_CHANNEL) {
444         return ((channel - MIN_5G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_36);
445     }
446     return INVALID_FREQ_OR_CHANNEL;
447 }
448 
IsOtherVapConnect()449 bool IsOtherVapConnect()
450 {
451     WIFI_LOGD("Enter IsOtherVapConnect");
452     int n;
453     int ret;
454     struct ifaddrs *ifaddr = nullptr;
455     struct ifaddrs *ifa = nullptr;
456     bool p2pOrHmlConnected = false;
457     bool hotspotEnable = false;
458     if (getifaddrs(&ifaddr) == -1) {
459         WIFI_LOGE("getifaddrs failed, error is %{public}d", errno);
460         return false;
461     }
462     for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++) {
463         if (ifa->ifa_addr == nullptr) {
464             continue;
465         }
466         /* For an AF_INET interface address, display the address */
467         int family = ifa->ifa_addr->sa_family;
468         char ipAddress[NI_MAXHOST] = {0}; /* IP address storage */
469         if (family == AF_INET) {
470             ret = getnameinfo(ifa->ifa_addr,
471                 sizeof(struct sockaddr_in),
472                 ipAddress,
473                 NI_MAXHOST,
474                 nullptr,
475                 0,
476                 NI_NUMERICHOST);
477             if (ret != 0) {
478                 WIFI_LOGE("getnameinfo() failed: %{public}s\n", gai_strerror(ret));
479                 return false;
480             }
481         }
482         if (strncmp("192", ipAddress, PRIFIX_IP_LEN) != 0 && strncmp("172", ipAddress, PRIFIX_IP_LEN) != 0) {
483             continue;
484         }
485         if ((strncmp("p2p", ifa->ifa_name, PRIFIX_P2P_LEN) == 0 ||
486              strncmp("chba", ifa->ifa_name, PRIFIX_CHBA_LEN) == 0)) {
487             p2pOrHmlConnected = true;
488         }
489         if (strncmp("wlan1", ifa->ifa_name, PRIFIX_WLAN1_LEN) == 0) {
490             hotspotEnable = true;
491         }
492     }
493     freeifaddrs(ifaddr);
494     return p2pOrHmlConnected && hotspotEnable;
495 }
496 
Hex2num(char c)497 static int Hex2num(char c)
498 {
499     if (c >= '0' && c <= '9') {
500         return c - '0';
501     }
502     if (c >= 'a' && c <= 'f') {
503         return c - 'a' + 10; // convert to decimal
504     }
505     if (c >= 'A' && c <= 'F') {
506         return c - 'A' + 10; // convert to decimal
507     }
508     return -1;
509 }
510 
Hex2byte(const char * hex)511 int Hex2byte(const char *hex)
512 {
513     int a = Hex2num(*hex++);
514     if (a < 0) {
515         return -1;
516     }
517     int b = Hex2num(*hex++);
518     if (b < 0) {
519         return -1;
520     }
521     return (a << 4) | b; // convert to binary
522 }
523 
HexString2Byte(const char * hex,uint8_t * buf,size_t len)524 int HexString2Byte(const char *hex, uint8_t *buf, size_t len)
525 {
526     size_t i;
527     int a;
528     const char *ipos = hex;
529     uint8_t *opos = buf;
530 
531     for (i = 0; i < len; i++) {
532         a = Hex2byte(ipos);
533         if (a < 0) {
534             return -1;
535         }
536         *opos++ = a;
537         ipos += 2; // convert to binary
538     }
539     return 0;
540 }
541 
Byte2HexString(const uint8_t * byte,uint8_t bytesLen,char * hexstr,uint8_t hexstrLen)542 void Byte2HexString(const uint8_t* byte, uint8_t bytesLen, char* hexstr, uint8_t hexstrLen)
543 {
544     if ((byte == nullptr) || (hexstr == nullptr)) {
545         WIFI_LOGE("%{public}s: invalid parameter", __func__);
546         return;
547     }
548 
549     if (hexstrLen < bytesLen * 2) { // verify length
550         WIFI_LOGE("%{public}s: invalid byteLen:%{public}d or hexStrLen:%{public}d",
551             __func__, bytesLen, hexstrLen);
552         return;
553     }
554 
555     WIFI_LOGI("%{public}s byteLen:%{public}d, hexStrLen:%{public}d", __func__, bytesLen, hexstrLen);
556     uint8_t hexstrIndex = 0;
557     for (uint8_t i = 0; i < bytesLen; i++) {
558         if (snprintf_s(hexstr + hexstrIndex, hexstrLen - hexstrIndex, hexstrLen - hexstrIndex - 1,
559             "%02x", byte[i]) <= 0) {
560             WIFI_LOGI("%{public}s: failed to snprintf_s", __func__);
561         }
562         hexstrIndex += 2; // offset
563         if (hexstrIndex >= hexstrLen) {
564             break;
565         }
566     }
567 }
568 
DecodeBase64(const std::string & input,std::vector<uint8_t> & output)569 bool DecodeBase64(const std::string &input, std::vector<uint8_t> &output)
570 {
571 #ifndef OHOS_ARCH_LITE
572     WIFI_LOGD("%{public}s input:%{private}s, length:%{public}zu", __func__, input.c_str(), input.length());
573     if (input.length() % BASE64_DEST_UNIT_SIZE != 0) {
574         WIFI_LOGE("%{public}s: wrong data length for base64 encode string", __func__);
575         return false;
576     }
577     uint32_t decodedLen = input.length() * BASE64_SRC_UNIT_SIZE / BASE64_DEST_UNIT_SIZE;
578     if (input.at(input.length() - BASE64_UNIT_ONE_PADDING) == '=') {
579         decodedLen--;
580         if (input.at(input.length() - BASE64_UNIT_TWO_PADDING) == '=') {
581             decodedLen--;
582         }
583     }
584     output.resize(decodedLen);
585 
586     BIO *b64 = BIO_new(BIO_f_base64());
587     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
588     BIO *bio = BIO_new_mem_buf(input.c_str(), input.length());
589     bio = BIO_push(b64, bio);
590     if (BIO_read(bio, &output[0], input.length()) != static_cast<int32_t>(decodedLen)) {
591         WIFI_LOGE("%{public}s: wrong data length for decoded buffer", __func__);
592         return false;
593     }
594     BIO_free_all(bio);
595 #endif
596     return true;
597 }
598 
EncodeBase64(const std::vector<uint8_t> & input)599 std::string EncodeBase64(const std::vector<uint8_t> &input)
600 {
601 #ifndef OHOS_ARCH_LITE
602     WIFI_LOGD("%{public}s: size:%{public}zu", __func__, input.size());
603     if (input.empty()) {
604         WIFI_LOGE("%{public}s: wrong data length for string to encode.", __func__);
605         return "";
606     }
607     BIO *b64 = BIO_new(BIO_f_base64());
608     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
609     BIO *bio = BIO_new(BIO_s_mem());
610     bio = BIO_push(b64, bio);
611     BIO_write(bio, &input[0], input.size());
612     BIO_flush(bio);
613 
614     BUF_MEM *bptr = nullptr;
615     BIO_get_mem_ptr(bio, &bptr);
616     std::string output = "";
617     if (bptr != nullptr) {
618         std::vector<char> outputBuffer {};
619         WIFI_LOGI("%{public}s: length is %{public}zu", __func__, bptr->length);
620         outputBuffer.insert(outputBuffer.end(), bptr->data, bptr->data + bptr->length);
621         outputBuffer[bptr->length] = 0;
622         output = static_cast<char*>(&outputBuffer[0]);
623     }
624     BIO_free_all(bio);
625     return output;
626 #else
627     return "";
628 #endif
629 }
630 
GetSplitInfo(const std::string & input,const std::string & delimiter)631 std::vector<std::string> GetSplitInfo(const std::string &input, const std::string &delimiter)
632 {
633     size_t pos = 0;
634     std::string token;
635     std::vector<std::string> results;
636 
637     std::string splitStr = input;
638     WIFI_LOGD("%{public}s input:%{private}s, delimiter:%{public}s", __func__, input.c_str(), delimiter.c_str());
639     while ((pos = splitStr.find(delimiter)) != std::string::npos) {
640         token = splitStr.substr(0, pos);
641         if (token.length() > 0) {
642             results.push_back(token);
643             splitStr.erase(0, pos + delimiter.length());
644             WIFI_LOGD("%{public}s token:%{private}s, splitStr:%{public}s", __func__, token.c_str(), splitStr.c_str());
645         }
646     }
647     results.push_back(splitStr);
648     WIFI_LOGD("%{public}s size:%{public}zu", __func__, results.size());
649     return results;
650 }
651 
HexToString(const std::string & str)652 std::string HexToString(const std::string &str)
653 {
654     std::string result;
655     if (str.length() <= 0) {
656         return result;
657     }
658     for (size_t i = 0; i < str.length() - 1; i += STEP_2BIT) {
659         std::string byte = str.substr(i, STEP_2BIT);
660         char chr = 0;
661         int strTemp = CheckDataLegalHex(byte);
662         if (strTemp > 0) {
663             chr = static_cast<char>(strTemp);
664         }
665         result.push_back(chr);
666     }
667     return result;
668 }
669 
StringToHex(const std::string & data)670 std::string StringToHex(const std::string &data)
671 {
672     std::stringstream ss;
673     for (std::string::size_type i = 0; i < data.size(); ++i) {
674         unsigned char temp = static_cast<unsigned char>(data[i]) >> HEX_OFFSET;
675         ss << HEX_TABLE[temp] << HEX_TABLE[static_cast<unsigned char>(data[i]) & 0xf];
676     }
677     return ss.str();
678 }
679 
CheckDataLegalBin(const std::string & data)680 int CheckDataLegalBin(const std::string &data)
681 {
682     if (data.empty() || data.size() > MAX_INT32_LENGTH_BIN) {
683         WIFI_LOGE("CheckDataLegalBin: invalid data:%{private}s", data.c_str());
684         return 0;
685     }
686 
687     std::regex pattern("[0-1]+");
688     if (!std::regex_match(data, pattern)) {
689         return 0;
690     }
691     errno = 0;
692     char *endptr = nullptr;
693     long int num = std::strtol(data.c_str(), &endptr, BASE_BIN);
694     if (errno == ERANGE) {
695         WIFI_LOGE("CheckDataLegalBin errno == ERANGE, data:%{private}s", data.c_str());
696         return 0;
697     }
698 
699     return static_cast<int>(num);
700 }
701 
CheckDataLegalHex(const std::string & data)702 int CheckDataLegalHex(const std::string &data)
703 {
704     if (data.empty() || data.size() > MAX_INT32_LENGTH_HEX) {
705         WIFI_LOGE("CheckDataLegalHex: invalid data:%{private}s", data.c_str());
706         return 0;
707     }
708 
709     std::regex pattern("[0-9|a-f|A-F]+");
710     if (!std::regex_match(data, pattern)) {
711         return 0;
712     }
713     errno = 0;
714     char *endptr = nullptr;
715     long int num = std::strtol(data.c_str(), &endptr, BASE_HEX);
716     if (errno == ERANGE) {
717         WIFI_LOGE("CheckDataLegalHex errno == ERANGE, data:%{private}s", data.c_str());
718         return 0;
719     }
720 
721     return static_cast<int>(num);
722 }
723 
CheckDataLegal(std::string & data,int base)724 int CheckDataLegal(std::string &data, int base)
725 {
726     if (data.empty() || data.size() > MAX_INT32_LENGTH) {
727         WIFI_LOGE("CheckDataLegal: invalid data:%{private}s", data.c_str());
728         return 0;
729     }
730 
731     std::regex pattern("-?\\d+");
732     if (!std::regex_match(data, pattern)) {
733         return 0;
734     }
735     errno = 0;
736     char *endptr = nullptr;
737     long int num = std::strtol(data.c_str(), &endptr, base);
738     if (errno == ERANGE) {
739         WIFI_LOGE("CheckDataLegal errno == ERANGE, data:%{private}s", data.c_str());
740         return 0;
741     }
742 
743     return static_cast<int>(num);
744 }
745 
CheckDataToUint(std::string & data,int base)746 unsigned int CheckDataToUint(std::string &data, int base)
747 {
748     if (data.empty() || data.size() > MAX_UINT32_LENGTH) {
749         WIFI_LOGE("CheckDataToUint: invalid data:%{private}s", data.c_str());
750         return 0;
751     }
752     std::regex pattern("\\d+");
753     if (!std::regex_match(data, pattern)) {
754         WIFI_LOGE("CheckDataToUint regex unsigned int value fail, data:%{private}s", data.c_str());
755         return 0;
756     }
757 
758     errno = 0;
759     char *endptr = nullptr;
760     unsigned long int num = std::strtoul(data.c_str(), &endptr, base);
761     if (errno == ERANGE) {
762         WIFI_LOGE("CheckDataToUint errno == ERANGE, data:%{private}s", data.c_str());
763         return 0;
764     }
765 
766     return static_cast<unsigned int>(num);
767 }
768 
CheckDataTolonglong(std::string & data,int base)769 long long CheckDataTolonglong(std::string &data, int base)
770 {
771     if (data.empty() || data.size() > MAX_INT64_LENGTH) {
772         WIFI_LOGE("CheckDataTolonglong: invalid data:%{private}s", data.c_str());
773         return 0;
774     }
775 
776     std::regex pattern("-?\\d+");
777     if (!std::regex_match(data, pattern)) {
778         return 0;
779     }
780     errno = 0;
781     char *endptr = nullptr;
782     long long int num = std::strtoll(data.c_str(), &endptr, base);
783     if (errno == ERANGE) {
784         WIFI_LOGE("CheckDataTolonglong errno == ERANGE, data:%{private}s", data.c_str());
785         return 0;
786     }
787     return num;
788 }
789 
GenerateStandardErrCode(uint8_t subSystem,uint16_t errCode)790 uint32_t GenerateStandardErrCode(uint8_t subSystem, uint16_t errCode)
791 {
792     uint8_t standardSubSystem = subSystem & 0x1F;
793     return (WIFI_SYSTEM_ID << SYSTEM_OFFSET | standardSubSystem << SUB_SYSTEM_OFFSET | errCode);
794 }
795 }  // namespace Wifi
796 }  // namespace OHOS
797