• 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 <sstream>
18 #include <iterator>
19 #include <regex>
20 #ifndef OHOS_ARCH_LITE
21 #include "app_mgr_client.h"
22 #include "bundle_mgr_interface.h"
23 #include "if_system_ability_manager.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27 #include "common_timer_errors.h"
28 #endif
29 #include "wifi_logger.h"
30 #include <ifaddrs.h>
31 #include <net/if.h>
32 #include <netdb.h>
33 
34 namespace OHOS {
35 namespace Wifi {
36 DEFINE_WIFILOG_LABEL("WifiCommonUtil");
37 
38 constexpr int PRIFIX_IP_LEN = 3;
39 constexpr int PRIFIX_P2P_LEN = 3;
40 constexpr int PRIFIX_CHBA_LEN = 4;
41 constexpr int PRIFIX_WLAN1_LEN = 5;
42 constexpr int FREQ_2G_MIN = 2412;
43 constexpr int FREQ_2G_MAX = 2472;
44 constexpr int FREQ_5G_MIN = 5170;
45 constexpr int FREQ_5G_MAX = 5825;
46 constexpr int CHANNEL_14_FREQ = 2484;
47 constexpr int CHANNEL_14 = 14;
48 constexpr int CENTER_FREQ_DIFF = 5;
49 constexpr int CHANNEL_2G_MIN = 1;
50 constexpr int CHANNEL_5G_MIN = 34;
51 constexpr int MIN_24G_CHANNEL = 1;
52 constexpr int MAX_24G_CHANNEL = 13;
53 constexpr int MIN_5G_CHANNEL = 36;
54 constexpr int MAX_5G_CHANNEL = 165;
55 constexpr int FREQ_CHANNEL_1 = 2412;
56 constexpr int FREQ_CHANNEL_36 = 5180;
57 constexpr int SECOND_TO_MICROSECOND = 1000 * 1000;
58 constexpr int MICROSECOND_TO_NANOSECOND = 1000;
59 constexpr int32_t UID_CALLINGUID_TRANSFORM_DIVISOR = 200000;
60 static std::pair<std::string, int> g_brokerProcessInfo;
61 
DataAnonymize(const std::string str,const char delim,const char hiddenCh,const int startIdx=0)62 static std::string DataAnonymize(const std::string str, const char delim,
63     const char hiddenCh, const int startIdx = 0)
64 {
65     std::string s = str;
66     constexpr auto minDelimSize = 2;
67     constexpr auto minKeepSize = 6;
68     if (std::count(s.begin(), s.end(), delim) < minDelimSize) {
69         if (s.size() <= minKeepSize) {
70             return std::string(s.size(), hiddenCh);
71         }
72         auto idx1 = 2;
73         const auto idx2 = static_cast<int>(s.size() - 4);
74         while (idx1++ < idx2) {
75             s[idx1] = hiddenCh;
76         }
77         return s;
78     }
79 
80     std::string::size_type begin = s.find_first_of(delim);
81     std::string::size_type end = s.find_last_of(delim);
82     int idx = 0;
83     while (idx++ < startIdx && begin < end) {
84         begin = s.find_first_of(delim, begin + 1);
85     }
86     while (begin++ != end) {
87         if (s[begin] != delim) {
88             s[begin] = hiddenCh;
89         }
90     }
91     return s;
92 }
93 
MacAnonymize(const std::string str)94 std::string MacAnonymize(const std::string str)
95 {
96     return DataAnonymize(str, ':', '*', 1);
97 }
98 
IpAnonymize(const std::string str)99 std::string IpAnonymize(const std::string str)
100 {
101     return DataAnonymize(str, '.', '*');
102 }
103 
SsidAnonymize(const std::string str)104 std::string SsidAnonymize(const std::string str)
105 {
106     if (str.empty()) {
107         return str;
108     }
109 
110     std::string s = str;
111     constexpr char hiddenChar = '*';
112     constexpr size_t minHiddenSize = 3;
113     constexpr size_t headKeepSize = 3;
114     constexpr size_t tailKeepSize = 3;
115     auto func = [hiddenChar](char& c) { c = hiddenChar; };
116     if (s.size() < minHiddenSize) {
117         std::for_each(s.begin(), s.end(), func);
118         return s;
119     }
120 
121     if (s.size() < (minHiddenSize + headKeepSize + tailKeepSize)) {
122         size_t beginIndex = 1;
123         size_t hiddenSize = s.size() - minHiddenSize + 1;
124         hiddenSize = hiddenSize > minHiddenSize ? minHiddenSize : hiddenSize;
125         std::for_each(s.begin() + beginIndex, s.begin() + beginIndex + hiddenSize, func);
126         return s;
127     }
128     std::for_each(s.begin() + headKeepSize, s.begin() + s.size() - tailKeepSize, func);
129     return s;
130 }
131 
ConvertStrChar(char ch)132 static unsigned char ConvertStrChar(char ch)
133 {
134     constexpr int numDiffForHexAlphabet = 10;
135     if (ch >= '0' && ch <= '9') {
136         return (ch - '0');
137     }
138     if (ch >= 'A' && ch <= 'F') {
139         return (ch - 'A' + numDiffForHexAlphabet);
140     }
141     if (ch >= 'a' && ch <= 'f') {
142         return (ch - 'a' + numDiffForHexAlphabet);
143     }
144     return 0;
145 }
146 
MacStrToArray(const std::string & strMac,unsigned char mac[WIFI_MAC_LEN])147 errno_t MacStrToArray(const std::string& strMac, unsigned char mac[WIFI_MAC_LEN])
148 {
149     constexpr int strMacLen = 18;
150     char tempArray[strMacLen] = { 0 };
151     errno_t ret = memcpy_s(tempArray, strMacLen, strMac.c_str(), strMac.size() + 1);
152     if (ret != EOK) {
153         return ret;
154     }
155 
156     int idx = 0;
157     constexpr int bitWidth = 4;
158     char *ptr = nullptr;
159     char *p = strtok_s(tempArray, ":", &ptr);
160     while ((p != nullptr) && (idx < WIFI_MAC_LEN)) {
161         mac[idx++] = (ConvertStrChar(*p) << bitWidth) | ConvertStrChar(*(p + 1));
162         p = strtok_s(nullptr, ":", &ptr);
163     }
164     return EOK;
165 }
166 
ConvertArrayChar(unsigned char ch)167 static char ConvertArrayChar(unsigned char ch)
168 {
169     constexpr int maxDecNum = 9;
170     constexpr int numDiffForHexAlphabet = 10;
171     if (ch <= maxDecNum) {
172         return '0' + ch;
173     }
174     if (ch <= 0xf) {
175         return ch + 'a' - numDiffForHexAlphabet;
176     }
177     return '0';
178 }
179 
MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])180 std::string MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])
181 {
182     constexpr int bitWidth = 4;
183     constexpr int noColonBit = 5;
184     std::stringstream ss;
185     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
186         ss << ConvertArrayChar(mac[i] >> bitWidth) << ConvertArrayChar(mac[i] & 0xf);
187         if (i != noColonBit) {
188             ss << ":";
189         }
190     }
191     return ss.str();
192 }
193 
IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])194 bool IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])
195 {
196     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
197         if (mac[i] != 0) {
198             return false;
199         }
200     }
201     return true;
202 }
203 
Ip2Number(const std::string & strIp)204 unsigned int Ip2Number(const std::string& strIp)
205 {
206     std::string::size_type front = 0;
207     std::string::size_type back = 0;
208     unsigned int number = 0;
209     int size = 32;
210     constexpr int sectionSize = 8;
211 
212     std::string ip(strIp + '.');
213     while ((back = ip.find_first_of('.', back)) != (std::string::size_type)std::string::npos) {
214         number |= std::stol(ip.substr(front, back - front).c_str()) << (size -= sectionSize);
215         front = ++back;
216     }
217     return number;
218 }
219 
Number2Ip(unsigned int intIp)220 std::string Number2Ip(unsigned int intIp)
221 {
222     constexpr int fourthPartMoveLen = 24;
223     constexpr int thirdPartMoveLen = 16;
224     constexpr int secondPartMoveLen = 8;
225 
226     std::string ip;
227     ip.append(std::to_string((intIp & 0xff000000) >> fourthPartMoveLen));
228     ip.push_back('.');
229     ip.append(std::to_string((intIp & 0x00ff0000) >> thirdPartMoveLen));
230     ip.push_back('.');
231     ip.append(std::to_string((intIp & 0x0000ff00) >> secondPartMoveLen));
232     ip.push_back('.');
233     ip.append(std::to_string(intIp & 0x000000ff));
234     return ip;
235 }
236 
StrSplit(const std::string & str,const std::string & delim)237 std::vector<std::string> StrSplit(const std::string& str, const std::string& delim) {
238     std::regex re(delim);
239     std::sregex_token_iterator
240         first{ str.begin(), str.end(), re, -1 },
241         last;
242     return { first, last };
243 }
244 
GetElapsedMicrosecondsSinceBoot()245 int64_t GetElapsedMicrosecondsSinceBoot()
246 {
247     struct timespec times = {0, 0};
248     clock_gettime(CLOCK_MONOTONIC, &times);
249     return static_cast<int64_t>(times.tv_sec) * SECOND_TO_MICROSECOND + times.tv_nsec / MICROSECOND_TO_NANOSECOND;
250 }
251 
252 #ifndef OHOS_ARCH_LITE
GetBundleManager()253 sptr<AppExecFwk::IBundleMgr> GetBundleManager()
254 {
255     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
256     if (systemManager == nullptr) {
257         WIFI_LOGE("Get system ability manager failed!");
258         return nullptr;
259     }
260     return iface_cast<AppExecFwk::IBundleMgr>(systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID));
261 }
262 
GetBundleName()263 std::string GetBundleName()
264 {
265     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
266     if (bundleInstance == nullptr) {
267         WIFI_LOGE("bundle instance is null!");
268         return "";
269     }
270 
271     AppExecFwk::BundleInfo bundleInfo;
272     auto ret = bundleInstance->GetBundleInfoForSelf(0, bundleInfo);
273     if (ret != OHOS::ERR_OK) {
274         WIFI_LOGE("GetBundleInfoForSelf failed! ret[%{public}d]", ret);
275         return "";
276     }
277 
278     WIFI_LOGI("Get bundle name uid[%{public}d]: %{public}s", bundleInfo.uid, bundleInfo.name.c_str());
279     return bundleInfo.name;
280 }
281 
GetCallingPid()282 int GetCallingPid()
283 {
284     return IPCSkeleton::GetCallingPid();
285 }
286 
GetCallingUid()287 int GetCallingUid()
288 {
289     return IPCSkeleton::GetCallingUid();
290 }
291 
GetCallingTokenId()292 int GetCallingTokenId()
293 {
294     return IPCSkeleton::GetCallingTokenID();
295 }
296 
IsForegroundApp(const int uid)297 bool IsForegroundApp(const int uid)
298 {
299     using namespace OHOS::AppExecFwk;
300     using namespace OHOS::AppExecFwk::Constants;
301     int32_t userId = static_cast<int32_t>(uid / UID_CALLINGUID_TRANSFORM_DIVISOR);
302 
303     auto appMgrClient = std::make_unique<AppMgrClient>();
304     appMgrClient->ConnectAppMgrService();
305     AppMgrResultCode ret;
306     std::vector<RunningProcessInfo> infos;
307     ret = appMgrClient->GetProcessRunningInfosByUserId(infos, userId);
308     if (ret != AppMgrResultCode::RESULT_OK) {
309         WIFI_LOGE("GetProcessRunningInfosByUserId fail, ret = [%{public}d]", ret);
310         return false;
311     }
312 
313     auto iter = std::find_if(infos.begin(), infos.end(), [&uid](const RunningProcessInfo &rhs) {
314         return ((rhs.uid_ == uid) && (rhs.state_ == AppProcessState::APP_STATE_FOREGROUND ||
315                 rhs.state_ == AppProcessState::APP_STATE_FOCUS));
316     });
317     if (iter != infos.end()) {
318         return true;
319     }
320     return false;
321 }
322 
GetRunningProcessNameByPid(const int uid,const int pid)323 std::string GetRunningProcessNameByPid(const int uid, const int pid)
324 {
325     using namespace OHOS::AppExecFwk;
326     using namespace OHOS::AppExecFwk::Constants;
327 
328     int32_t userId = static_cast<int32_t>(uid / UID_CALLINGUID_TRANSFORM_DIVISOR);
329     auto appMgrClient = std::make_unique<AppMgrClient>();
330     appMgrClient->ConnectAppMgrService();
331     AppMgrResultCode ret;
332     std::vector<RunningProcessInfo> infos;
333     ret = appMgrClient->GetProcessRunningInfosByUserId(infos, userId);
334     if (ret != AppMgrResultCode::RESULT_OK) {
335         WIFI_LOGE("GetProcessRunningInfosByUserId fail, ret = [%{public}d]", ret);
336         return "";
337     }
338     std::string processName = "";
339     auto iter = infos.begin();
340     while (iter != infos.end()) {
341         if (iter->pid_ == pid) {
342             processName = iter->processName_;
343             break;
344         }
345         iter++;
346     }
347     if (processName.empty() && g_brokerProcessInfo.second == pid) {
348         processName = g_brokerProcessInfo.first;
349     }
350     return processName;
351 }
352 
SetWifiBrokerProcess(int pid,std::string processName)353 void SetWifiBrokerProcess(int pid, std::string processName)
354 {
355     WIFI_LOGD("enter SetWifiBrokerProcess");
356     g_brokerProcessInfo = make_pair(processName, pid);
357 }
358 
TimeStats(const std::string desc)359 TimeStats::TimeStats(const std::string desc): m_desc(desc)
360 {
361     m_startTime = std::chrono::steady_clock::now();
362     WIFI_LOGI("[Time stats][start] %{public}s.", m_desc.c_str());
363 }
364 
~TimeStats()365 TimeStats::~TimeStats()
366 {
367     auto us = std::chrono::duration_cast<std::chrono::microseconds>
368         (std::chrono::steady_clock::now() - m_startTime).count();
369     constexpr int TIME_BASE = 1000;
370     WIFI_LOGI("[Time stats][end] %{public}s, time cost:%{public}lldus, %{public}lldms, %{public}llds",
371         m_desc.c_str(), us, us / TIME_BASE, us / TIME_BASE / TIME_BASE);
372 }
373 
GetInstance()374 WifiTimer *WifiTimer::GetInstance()
375 {
376     static WifiTimer instance;
377     return &instance;
378 }
379 
WifiTimer()380 WifiTimer::WifiTimer() : timer_(std::make_unique<Utils::Timer>("WifiManagerTimer"))
381 {
382     timer_->Setup();
383 }
384 
~WifiTimer()385 WifiTimer::~WifiTimer()
386 {
387     if (timer_) {
388         timer_->Shutdown(true);
389     }
390 }
391 
Register(const TimerCallback & callback,uint32_t & outTimerId,uint32_t interval,bool once)392 ErrCode WifiTimer::Register(const TimerCallback &callback, uint32_t &outTimerId, uint32_t interval, bool once)
393 {
394     if (timer_ == nullptr) {
395         WIFI_LOGE("timer_ is nullptr");
396         return WIFI_OPT_FAILED;
397     }
398 
399     uint32_t ret = timer_->Register(callback, interval, once);
400     if (ret == Utils::TIMER_ERR_DEAL_FAILED) {
401         WIFI_LOGE("Register timer failed");
402         return WIFI_OPT_FAILED;
403     }
404 
405     outTimerId = ret;
406     return WIFI_OPT_SUCCESS;
407 }
408 
UnRegister(uint32_t timerId)409 void WifiTimer::UnRegister(uint32_t timerId)
410 {
411     if (timerId == 0) {
412         WIFI_LOGE("timerId is 0, no register timer");
413         return;
414     }
415 
416     if (timer_ == nullptr) {
417         WIFI_LOGE("timer_ is nullptr");
418         return;
419     }
420 
421     timer_->Unregister(timerId);
422     return;
423 }
424 #endif
425 
FrequencyToChannel(int freq)426 int FrequencyToChannel(int freq)
427 {
428     WIFI_LOGD("FrequencyToChannel: %{public}d", freq);
429     int channel = INVALID_FREQ_OR_CHANNEL;
430     if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
431         channel = (freq - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
432     } else if (freq == CHANNEL_14_FREQ) {
433         channel = CHANNEL_14;
434     } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
435         channel = (freq - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
436     }
437     return channel;
438 }
439 
ChannelToFrequency(int channel)440 int ChannelToFrequency(int channel)
441 {
442     WIFI_LOGI("ChannelToFrequency: %{public}d", channel);
443     if (channel >= MIN_24G_CHANNEL && channel <= MAX_24G_CHANNEL) {
444         return ((channel - MIN_24G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_1);
445     }
446     if (MIN_5G_CHANNEL <= channel && channel <= MAX_5G_CHANNEL) {
447         return ((channel - MIN_5G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_36);
448     }
449     return INVALID_FREQ_OR_CHANNEL;
450 }
451 
IsOtherVapConnect()452 bool IsOtherVapConnect()
453 {
454     WIFI_LOGD("Enter IsOtherVapConnect");
455     int n;
456     int ret;
457     struct ifaddrs *ifaddr = nullptr;
458     struct ifaddrs *ifa = nullptr;
459     bool p2pOrHmlConnected = false;
460     bool hotspotEnable = false;
461     if (getifaddrs(&ifaddr) == -1) {
462         WIFI_LOGE("getifaddrs failed, error is %{public}d", errno);
463         return false;
464     }
465     for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++) {
466         if (ifa->ifa_addr == nullptr) {
467             continue;
468         }
469         /* For an AF_INET interface address, display the address */
470         int family = ifa->ifa_addr->sa_family;
471         char ipAddress[NI_MAXHOST] = {0}; /* IP address storage */
472         if (family == AF_INET) {
473             ret = getnameinfo(ifa->ifa_addr,
474                 sizeof(struct sockaddr_in),
475                 ipAddress,
476                 NI_MAXHOST,
477                 nullptr,
478                 0,
479                 NI_NUMERICHOST);
480             if (ret != 0) {
481                 WIFI_LOGE("getnameinfo() failed: %{public}s\n", gai_strerror(ret));
482                 return false;
483             }
484         }
485         if (strncmp("192", ipAddress, PRIFIX_IP_LEN) != 0 && strncmp("172", ipAddress, PRIFIX_IP_LEN) != 0) {
486             continue;
487         }
488         if ((strncmp("p2p", ifa->ifa_name, PRIFIX_P2P_LEN) == 0 ||
489              strncmp("chba", ifa->ifa_name, PRIFIX_CHBA_LEN) == 0)) {
490             p2pOrHmlConnected = true;
491         }
492         if (strncmp("wlan1", ifa->ifa_name, PRIFIX_WLAN1_LEN) == 0) {
493             hotspotEnable = true;
494         }
495     }
496     freeifaddrs(ifaddr);
497     return p2pOrHmlConnected && hotspotEnable;
498 }
499 
500 }  // namespace Wifi
501 }  // namespace OHOS
502