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) && (idx < WIFI_MAC_LEN)) {
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 AppExecFwk::BundleInfo bundleInfo;
253 auto ret = bundleInstance->GetBundleInfoForSelf(0, bundleInfo);
254 if (ret != OHOS::ERR_OK) {
255 WIFI_LOGE("GetBundleInfoForSelf failed! ret[%{public}d]", ret);
256 return "";
257 }
258
259 WIFI_LOGI("Get bundle name uid[%{public}d]: %{public}s", bundleInfo.uid, bundleInfo.name.c_str());
260 return bundleInfo.name;
261 }
262
IsSystemApp()263 bool IsSystemApp()
264 {
265 sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
266 if (bundleInstance == nullptr) {
267 return false;
268 }
269
270 int uid = IPCSkeleton::GetCallingUid();
271 bool isSysApp = bundleInstance->CheckIsSystemAppByUid(uid);
272 WIFI_LOGI("Is system App uid[%{public}d]: %{public}d", uid, isSysApp);
273 return isSysApp;
274 }
275
GetCallingPid()276 int GetCallingPid()
277 {
278 return IPCSkeleton::GetCallingPid();
279 }
280
GetCallingUid()281 int GetCallingUid()
282 {
283 return IPCSkeleton::GetCallingUid();
284 }
285
GetCallingTokenId()286 int GetCallingTokenId()
287 {
288 return IPCSkeleton::GetCallingTokenID();
289 }
290
IsForegroundApp(const int uid)291 bool IsForegroundApp(const int uid)
292 {
293 using namespace OHOS::AppExecFwk;
294 using namespace OHOS::AppExecFwk::Constants;
295 constexpr int32_t UID_CALLINGUID_TRANSFORM_DIVISOR = 200000;
296 int32_t userId = static_cast<int32_t>(uid / UID_CALLINGUID_TRANSFORM_DIVISOR);
297
298 auto appMgrClient = std::make_unique<AppMgrClient>();
299 appMgrClient->ConnectAppMgrService();
300 AppMgrResultCode ret;
301 std::vector<RunningProcessInfo> infos;
302 ret = appMgrClient->GetProcessRunningInfosByUserId(infos, userId);
303 if (ret != AppMgrResultCode::RESULT_OK) {
304 WIFI_LOGE("GetProcessRunningInfosByUserId fail, ret = [%{public}d]", ret);
305 return false;
306 }
307
308 auto iter = std::find_if(infos.begin(), infos.end(), [&uid](const RunningProcessInfo &rhs) {
309 return ((rhs.uid_ == uid) && (rhs.state_ == AppProcessState::APP_STATE_FOREGROUND ||
310 rhs.state_ == AppProcessState::APP_STATE_FOCUS));
311 });
312 if (iter != infos.end()) {
313 return true;
314 }
315 return false;
316 }
317
TimeStats(const std::string desc)318 TimeStats::TimeStats(const std::string desc): m_desc(desc)
319 {
320 m_startTime = std::chrono::steady_clock::now();
321 WIFI_LOGI("[Time stats][start] %{public}s.", m_desc.c_str());
322 }
323
~TimeStats()324 TimeStats::~TimeStats()
325 {
326 auto us = std::chrono::duration_cast<std::chrono::microseconds>
327 (std::chrono::steady_clock::now() - m_startTime).count();
328 constexpr int TIME_BASE = 1000;
329 WIFI_LOGI("[Time stats][end] %{public}s, time cost:%{public}lldus, %{public}lldms, %{public}llds",
330 m_desc.c_str(), us, us / TIME_BASE, us / TIME_BASE / TIME_BASE);
331 }
332 #endif
333
FrequencyToChannel(int freq)334 int FrequencyToChannel(int freq)
335 {
336 WIFI_LOGD("FrequencyToChannel: %{public}d", freq);
337 int channel = INVALID_FREQ_OR_CHANNEL;
338 if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
339 channel = (freq - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
340 } else if (freq == CHANNEL_14_FREQ) {
341 channel = CHANNEL_14;
342 } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
343 channel = (freq - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
344 }
345 return channel;
346 }
347
ChannelToFrequency(int channel)348 int ChannelToFrequency(int channel)
349 {
350 WIFI_LOGI("ChannelToFrequency: %{public}d", channel);
351 if (channel >= MIN_24G_CHANNEL && channel <= MAX_24G_CHANNEL) {
352 return ((channel - MIN_24G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_1);
353 }
354 if (MIN_5G_CHANNEL <= channel && channel <= MAX_5G_CHANNEL) {
355 return ((channel - MIN_5G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_36);
356 }
357 return INVALID_FREQ_OR_CHANNEL;
358 }
359
360 } // namespace Wifi
361 } // namespace OHOS
362