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 #endif
28 #include "wifi_logger.h"
29
30 namespace OHOS {
31 namespace Wifi {
32 DEFINE_WIFILOG_LABEL("WifiCommonUtil");
33
34 constexpr int FREQ_2G_MIN = 2412;
35 constexpr int FREQ_2G_MAX = 2472;
36 constexpr int FREQ_5G_MIN = 5170;
37 constexpr int FREQ_5G_MAX = 5825;
38 constexpr int CHANNEL_14_FREQ = 2484;
39 constexpr int CHANNEL_14 = 14;
40 constexpr int CENTER_FREQ_DIFF = 5;
41 constexpr int CHANNEL_2G_MIN = 1;
42 constexpr int CHANNEL_5G_MIN = 34;
43 constexpr int MIN_24G_CHANNEL = 1;
44 constexpr int MAX_24G_CHANNEL = 13;
45 constexpr int MIN_5G_CHANNEL = 36;
46 constexpr int MAX_5G_CHANNEL = 165;
47 constexpr int FREQ_CHANNEL_1 = 2412;
48 constexpr int FREQ_CHANNEL_36 = 5180;
49
DataAnonymize(const std::string str,const char delim,const char hiddenCh,const int startIdx=0)50 static std::string DataAnonymize(const std::string str, const char delim,
51 const char hiddenCh, const int startIdx = 0)
52 {
53 std::string s = str;
54 constexpr auto minDelimSize = 2;
55 constexpr auto minKeepSize = 6;
56 if (std::count(s.begin(), s.end(), delim) < minDelimSize) {
57 if (s.size() <= minKeepSize) {
58 return std::string(s.size(), hiddenCh);
59 }
60 auto idx1 = 2;
61 const auto idx2 = static_cast<int>(s.size() - 4);
62 while (idx1++ < idx2) {
63 s[idx1] = hiddenCh;
64 }
65 return s;
66 }
67
68 std::string::size_type begin = s.find_first_of(delim);
69 std::string::size_type end = s.find_last_of(delim);
70 int idx = 0;
71 while (idx++ < startIdx && begin < end) {
72 begin = s.find_first_of(delim, begin + 1);
73 }
74 while (begin++ != end) {
75 if (s[begin] != delim) {
76 s[begin] = hiddenCh;
77 }
78 }
79 return s;
80 }
81
MacAnonymize(const std::string str)82 std::string MacAnonymize(const std::string str)
83 {
84 return DataAnonymize(str, ':', '*', 1);
85 }
86
IpAnonymize(const std::string str)87 std::string IpAnonymize(const std::string str)
88 {
89 return DataAnonymize(str, '.', '*');
90 }
91
SsidAnonymize(const std::string str)92 std::string SsidAnonymize(const std::string str)
93 {
94 if (str.empty()) {
95 return str;
96 }
97
98 std::string s = str;
99 constexpr char hiddenChar = '*';
100 constexpr size_t minHiddenSize = 3;
101 constexpr size_t headKeepSize = 3;
102 constexpr size_t tailKeepSize = 3;
103 auto func = [hiddenChar](char& c) { c = hiddenChar; };
104 if (s.size() < minHiddenSize) {
105 std::for_each(s.begin(), s.end(), func);
106 return s;
107 }
108
109 if (s.size() < (minHiddenSize + headKeepSize + tailKeepSize)) {
110 size_t beginIndex = 1;
111 size_t hiddenSize = s.size() - minHiddenSize + 1;
112 hiddenSize = hiddenSize > minHiddenSize ? minHiddenSize : hiddenSize;
113 std::for_each(s.begin() + beginIndex, s.begin() + beginIndex + hiddenSize, func);
114 return s;
115 }
116 std::for_each(s.begin() + headKeepSize, s.begin() + s.size() - tailKeepSize, func);
117 return s;
118 }
119
ConvertStrChar(char ch)120 static unsigned char ConvertStrChar(char ch)
121 {
122 constexpr int numDiffForHexAlphabet = 10;
123 if (ch >= '0' && ch <= '9') {
124 return (ch - '0');
125 }
126 if (ch >= 'A' && ch <= 'F') {
127 return (ch - 'A' + numDiffForHexAlphabet);
128 }
129 if (ch >= 'a' && ch <= 'f') {
130 return (ch - 'a' + numDiffForHexAlphabet);
131 }
132 return 0;
133 }
134
MacStrToArray(const std::string & strMac,unsigned char mac[WIFI_MAC_LEN])135 errno_t MacStrToArray(const std::string& strMac, unsigned char mac[WIFI_MAC_LEN])
136 {
137 constexpr int strMacLen = 18;
138 char tempArray[strMacLen] = { 0 };
139 errno_t ret = memcpy_s(tempArray, strMacLen, strMac.c_str(), strMac.size() + 1);
140 if (ret != EOK) {
141 return ret;
142 }
143
144 int idx = 0;
145 constexpr int bitWidth = 4;
146 char *ptr = nullptr;
147 char *p = strtok_s(tempArray, ":", &ptr);
148 while (p != nullptr) {
149 mac[idx++] = (ConvertStrChar(*p) << bitWidth) | ConvertStrChar(*(p + 1));
150 p = strtok_s(nullptr, ":", &ptr);
151 }
152 return EOK;
153 }
154
ConvertArrayChar(unsigned char ch)155 static char ConvertArrayChar(unsigned char ch)
156 {
157 constexpr int maxDecNum = 9;
158 constexpr int numDiffForHexAlphabet = 10;
159 if (ch <= maxDecNum) {
160 return '0' + ch;
161 }
162 if (ch <= 0xf) {
163 return ch + 'a' - numDiffForHexAlphabet;
164 }
165 return '0';
166 }
167
MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])168 std::string MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])
169 {
170 constexpr int bitWidth = 4;
171 constexpr int noColonBit = 5;
172 std::stringstream ss;
173 for (int i = 0; i != WIFI_MAC_LEN; ++i) {
174 ss << ConvertArrayChar(mac[i] >> bitWidth) << ConvertArrayChar(mac[i] & 0xf);
175 if (i != noColonBit) {
176 ss << ":";
177 }
178 }
179 return ss.str();
180 }
181
IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])182 bool IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])
183 {
184 for (int i = 0; i != WIFI_MAC_LEN; ++i) {
185 if (mac[i] != 0) {
186 return false;
187 }
188 }
189 return true;
190 }
191
Ip2Number(const std::string & strIp)192 unsigned int Ip2Number(const std::string& strIp)
193 {
194 std::string::size_type front = 0;
195 std::string::size_type back = 0;
196 unsigned int number = 0;
197 int size = 32;
198 constexpr int sectionSize = 8;
199
200 std::string ip(strIp + '.');
201 while ((back = ip.find_first_of('.', back)) != (std::string::size_type)std::string::npos) {
202 number |= std::stol(ip.substr(front, back - front).c_str()) << (size -= sectionSize);
203 front = ++back;
204 }
205 return number;
206 }
207
Number2Ip(unsigned int intIp)208 std::string Number2Ip(unsigned int intIp)
209 {
210 constexpr int fourthPartMoveLen = 24;
211 constexpr int thirdPartMoveLen = 16;
212 constexpr int secondPartMoveLen = 8;
213
214 std::string ip;
215 ip.append(std::to_string((intIp & 0xff000000) >> fourthPartMoveLen));
216 ip.push_back('.');
217 ip.append(std::to_string((intIp & 0x00ff0000) >> thirdPartMoveLen));
218 ip.push_back('.');
219 ip.append(std::to_string((intIp & 0x0000ff00) >> secondPartMoveLen));
220 ip.push_back('.');
221 ip.append(std::to_string(intIp & 0x000000ff));
222 return ip;
223 }
224
StrSplit(const std::string & str,const std::string & delim)225 std::vector<std::string> StrSplit(const std::string& str, const std::string& delim) {
226 std::regex re(delim);
227 std::sregex_token_iterator
228 first{ str.begin(), str.end(), re, -1 },
229 last;
230 return { first, last };
231 }
232
233 #ifndef OHOS_ARCH_LITE
GetBundleManager()234 sptr<AppExecFwk::IBundleMgr> GetBundleManager()
235 {
236 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
237 if (systemManager == nullptr) {
238 WIFI_LOGE("Get system ability manager failed!");
239 return nullptr;
240 }
241 return iface_cast<AppExecFwk::IBundleMgr>(systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID));
242 }
243
GetBundleName()244 std::string GetBundleName()
245 {
246 sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
247 if (bundleInstance == nullptr) {
248 WIFI_LOGE("bundle instance is null!");
249 return "";
250 }
251
252 std::string bundleName;
253 int uid = IPCSkeleton::GetCallingUid();
254 if (!bundleInstance->GetBundleNameForUid(uid, bundleName)) {
255 WIFI_LOGE("Get bundle name failed!");
256 }
257 WIFI_LOGI("Get bundle name uid[%{public}d]: %{public}s", uid, bundleName.c_str());
258 return bundleName;
259 }
260
IsSystemApp()261 bool IsSystemApp()
262 {
263 sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
264 if (bundleInstance == nullptr) {
265 return false;
266 }
267
268 int uid = IPCSkeleton::GetCallingUid();
269 bool isSysApp = bundleInstance->CheckIsSystemAppByUid(uid);
270 WIFI_LOGI("Is system App uid[%{public}d]: %{public}d", uid, isSysApp);
271 return isSysApp;
272 }
273
GetCallingPid()274 int GetCallingPid()
275 {
276 return IPCSkeleton::GetCallingPid();
277 }
278
GetCallingUid()279 int GetCallingUid()
280 {
281 return IPCSkeleton::GetCallingUid();
282 }
283
IsForegroundApp(const int uid)284 bool IsForegroundApp(const int uid)
285 {
286 using namespace OHOS::AppExecFwk;
287 using namespace OHOS::AppExecFwk::Constants;
288 constexpr int32_t UID_CALLINGUID_TRANSFORM_DIVISOR = 200000;
289 int32_t userId = static_cast<int32_t>(uid / UID_CALLINGUID_TRANSFORM_DIVISOR);
290
291 auto appMgrClient = std::make_unique<AppMgrClient>();
292 if (appMgrClient == nullptr) {
293 return false;
294 }
295 appMgrClient->ConnectAppMgrService();
296 AppMgrResultCode ret;
297 std::vector<RunningProcessInfo> infos;
298 ret = appMgrClient->GetProcessRunningInfosByUserId(infos, userId);
299 if (ret != AppMgrResultCode::RESULT_OK) {
300 WIFI_LOGE("GetProcessRunningInfosByUserId fail, ret = [%{public}d]", ret);
301 return false;
302 }
303
304 auto iter = std::find_if(infos.begin(), infos.end(), [&uid](const RunningProcessInfo &rhs) {
305 return ((rhs.uid_ == uid) && (rhs.state_ == AppProcessState::APP_STATE_FOREGROUND ||
306 rhs.state_ == AppProcessState::APP_STATE_FOCUS));
307 });
308 if (iter != infos.end()) {
309 return true;
310 }
311 return false;
312 }
313
TimeStats(const std::string desc)314 TimeStats::TimeStats(const std::string desc): m_desc(desc)
315 {
316 m_startTime = std::chrono::steady_clock::now();
317 WIFI_LOGI("[Time stats][start] %{public}s.", m_desc.c_str());
318 }
319
~TimeStats()320 TimeStats::~TimeStats()
321 {
322 auto us = std::chrono::duration_cast<std::chrono::microseconds>
323 (std::chrono::steady_clock::now() - m_startTime).count();
324 constexpr int TIME_BASE = 1000;
325 WIFI_LOGI("[Time stats][end] %{public}s, time cost:%{public}lldus, %{public}lldms, %{public}llds",
326 m_desc.c_str(), us, us / TIME_BASE, us / TIME_BASE / TIME_BASE);
327 }
328 #endif
329
FrequencyToChannel(int freq)330 int FrequencyToChannel(int freq)
331 {
332 WIFI_LOGI("FrequencyToChannel: %{public}d", freq);
333 int channel = INVALID_FREQ_OR_CHANNEL;
334 if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
335 channel = (freq - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
336 } else if (freq == CHANNEL_14_FREQ) {
337 channel = CHANNEL_14;
338 } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
339 channel = (freq - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
340 }
341 return channel;
342 }
343
ChannelToFrequency(int channel)344 int ChannelToFrequency(int channel)
345 {
346 WIFI_LOGI("ChannelToFrequency: %{public}d", channel);
347 if (channel >= MIN_24G_CHANNEL && channel <= MAX_24G_CHANNEL) {
348 return ((channel - MIN_24G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_1);
349 }
350 if (MIN_5G_CHANNEL <= channel && channel <= MAX_5G_CHANNEL) {
351 return ((channel - MIN_5G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_36);
352 }
353 return INVALID_FREQ_OR_CHANNEL;
354 }
355
356 } // namespace Wifi
357 } // namespace OHOS
358