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, ×);
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