• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "dh_utils_tool.h"
17 
18 #include <algorithm>
19 #include <iomanip>
20 #include <iostream>
21 #include <random>
22 #include <sstream>
23 #include <string>
24 #include <sys/time.h>
25 #include <vector>
26 #include <zlib.h>
27 
28 #include "openssl/sha.h"
29 #include "parameter.h"
30 
31 #include "device_manager.h"
32 #include "dm_device_info.h"
33 
34 #include "constants.h"
35 #include "distributed_hardware_errno.h"
36 #include "distributed_hardware_log.h"
37 
38 namespace OHOS {
39 namespace DistributedHardware {
40 namespace {
41     constexpr int32_t MS_ONE_SECOND = 1000;
42     constexpr int32_t WORD_WIDTH_8 = 8;
43     constexpr int32_t WORD_WIDTH_4 = 4;
44     constexpr int32_t WIDTH = 4;
45     constexpr unsigned char MASK = 0x0F;
46     constexpr int32_t DOUBLE_TIMES = 2;
47     constexpr int32_t COMPRESS_SLICE_SIZE = 1024;
48     const std::string PARAM_KEY_OS_TYPE = "OS_TYPE";
49 }
50 
GetCurrentTime()51 int64_t GetCurrentTime()
52 {
53     struct timeval tv {
54         0
55     };
56     gettimeofday(&tv, nullptr);
57     return tv.tv_sec * MS_ONE_SECOND + tv.tv_usec / MS_ONE_SECOND;
58 }
59 
GetRandomID()60 std::string GetRandomID()
61 {
62     static std::random_device rd;
63     static std::uniform_int_distribution<uint64_t> dist(0ULL, 0xFFFFFFFFFFFFFFFFULL);
64     uint64_t ab = dist(rd);
65     uint64_t cd = dist(rd);
66     uint32_t a;
67     uint32_t b;
68     uint32_t c;
69     uint32_t d;
70     std::stringstream ss;
71     ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;
72     cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;
73     a = (ab >> 32U);
74     b = (ab & 0xFFFFFFFFU);
75     c = (cd >> 32U);
76     d = (cd & 0xFFFFFFFFU);
77     ss << std::hex << std::nouppercase << std::setfill('0');
78     ss << std::setw(WORD_WIDTH_8) << (a);
79     ss << std::setw(WORD_WIDTH_4) << (b >> 16U);
80     ss << std::setw(WORD_WIDTH_4) << (b & 0xFFFFU);
81     ss << std::setw(WORD_WIDTH_4) << (c >> 16U);
82     ss << std::setw(WORD_WIDTH_4) << (c & 0xFFFFU);
83     ss << std::setw(WORD_WIDTH_8) << d;
84 
85     return ss.str();
86 }
87 
GetUUIDByDm(const std::string & networkId)88 std::string GetUUIDByDm(const std::string &networkId)
89 {
90     if (!IsIdLengthValid(networkId)) {
91         return "";
92     }
93     std::string uuid = "";
94     auto ret = DeviceManager::GetInstance().GetUuidByNetworkId(DH_FWK_PKG_NAME, networkId, uuid);
95     return (ret == DH_FWK_SUCCESS) ? uuid : "";
96 }
97 
GetUDIDByDm(const std::string & networkId)98 std::string GetUDIDByDm(const std::string &networkId)
99 {
100     if (!IsIdLengthValid(networkId)) {
101         return "";
102     }
103     std::string udid = "";
104     auto ret = DeviceManager::GetInstance().GetUdidByNetworkId(DH_FWK_PKG_NAME, networkId, udid);
105     return (ret == DH_FWK_SUCCESS) ? udid : "";
106 }
107 
GetDeviceIdByUUID(const std::string & uuid)108 std::string GetDeviceIdByUUID(const std::string &uuid)
109 {
110     if (!IsIdLengthValid(uuid)) {
111         DHLOGE("uuid is invalid!");
112         return "";
113     }
114     return Sha256(uuid);
115 }
116 
Sha256(const std::string & in)117 std::string Sha256(const std::string& in)
118 {
119     unsigned char out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES + 1] = {0};
120     SHA256_CTX ctx;
121     SHA256_Init(&ctx);
122     SHA256_Update(&ctx, in.data(), in.size());
123     SHA256_Final(&out[SHA256_DIGEST_LENGTH], &ctx);
124     // here we translate sha256 hash to hexadecimal. each 8-bit char will be presented by two characters([0-9a-f])
125     const char* hexCode = "0123456789abcdef";
126     for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
127         unsigned char value = out[SHA256_DIGEST_LENGTH + i];
128         // uint8_t is 2 digits in hexadecimal.
129         out[i * DOUBLE_TIMES] = hexCode[(value >> WIDTH) & MASK];
130         out[i * DOUBLE_TIMES + 1] = hexCode[value & MASK];
131     }
132     out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES] = 0;
133     return std::string(reinterpret_cast<char*>(out));
134 }
135 
GetLocalDeviceInfo()136 DeviceInfo GetLocalDeviceInfo()
137 {
138     DeviceInfo devInfo { "", "", "", "", "", "", 0 };
139     DmDeviceInfo info;
140     auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(DH_FWK_PKG_NAME, info);
141     if (ret != DH_FWK_SUCCESS) {
142         DHLOGE("GetLocalNodeDeviceInfo failed, errCode = %{public}d", ret);
143         return devInfo;
144     }
145     devInfo.networkId = info.networkId;
146     devInfo.uuid = GetUUIDByDm(info.networkId);
147     devInfo.deviceId = GetDeviceIdByUUID(devInfo.uuid);
148     devInfo.udid = GetUDIDByDm(info.networkId);
149     devInfo.udidHash = Sha256(devInfo.udid);
150     devInfo.deviceName = info.deviceName;
151     devInfo.deviceType = info.deviceTypeId;
152     return devInfo;
153 }
154 
GetLocalNetworkId()155 std::string GetLocalNetworkId()
156 {
157     DmDeviceInfo info;
158     auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(DH_FWK_PKG_NAME, info);
159     if (ret != DH_FWK_SUCCESS) {
160         DHLOGE("GetLocalNodeDeviceInfo failed, errCode = %{public}d", ret);
161         return "";
162     }
163     return info.networkId;
164 }
165 
IsUInt8(const cJSON * jsonObj)166 bool IsUInt8(const cJSON* jsonObj)
167 {
168     if (jsonObj == NULL || !cJSON_IsNumber(jsonObj)) {
169         return false;
170     }
171     return (jsonObj->valueint >= 0 && static_cast<uint8_t>(jsonObj->valueint) <= UINT8_MAX);
172 }
173 
IsUInt16(const cJSON * jsonObj)174 bool IsUInt16(const cJSON* jsonObj)
175 {
176     if (jsonObj == NULL || !cJSON_IsNumber(jsonObj)) {
177         return false;
178     }
179     return (jsonObj->valueint >= 0 && static_cast<uint16_t>(jsonObj->valueint) <= UINT16_MAX);
180 }
181 
IsInt32(const cJSON * jsonObj)182 bool IsInt32(const cJSON* jsonObj)
183 {
184     if (jsonObj == NULL || !cJSON_IsNumber(jsonObj)) {
185         return false;
186     }
187     return (jsonObj->valueint >= INT32_MIN && jsonObj->valueint <= INT32_MAX);
188 }
189 
IsUInt32(const cJSON * jsonObj)190 bool IsUInt32(const cJSON* jsonObj)
191 {
192     if (jsonObj == NULL || !cJSON_IsNumber(jsonObj)) {
193         return false;
194     }
195     return (jsonObj->valueint >= 0 && static_cast<uint32_t>(jsonObj->valueint) <= UINT32_MAX);
196 }
197 
IsBool(const cJSON * jsonObj)198 bool IsBool(const cJSON* jsonObj)
199 {
200     return (jsonObj != NULL && cJSON_IsBool(jsonObj));
201 }
202 
IsString(const cJSON * jsonObj)203 bool IsString(const cJSON* jsonObj)
204 {
205     if (jsonObj == NULL || !cJSON_IsString(jsonObj)) {
206         return false;
207     }
208     return (strlen(jsonObj->valuestring) > MIN_MESSAGE_LEN && strlen(jsonObj->valuestring) <= MAX_MESSAGE_LEN);
209 }
210 
IsArray(const cJSON * jsonObj)211 bool IsArray(const cJSON* jsonObj)
212 {
213     if (jsonObj == NULL || !cJSON_IsArray(jsonObj)) {
214         return false;
215     }
216     return ((uint32_t)cJSON_GetArraySize(jsonObj) >= 0 && (uint32_t)cJSON_GetArraySize(jsonObj) <= MAX_ARR_SIZE);
217 }
218 
Compress(const std::string & data)219 std::string Compress(const std::string& data)
220 {
221     z_stream strm;
222     strm.zalloc = Z_NULL;
223     strm.zfree = Z_NULL;
224     strm.opaque = Z_NULL;
225     deflateInit(&strm, Z_DEFAULT_COMPRESSION);
226 
227     strm.next_in = reinterpret_cast<Bytef*>(const_cast<char *>(data.data()));
228     strm.avail_in = data.size();
229     std::string out;
230     std::vector<Bytef> temp_out(COMPRESS_SLICE_SIZE, 0);
231 
232     do {
233         strm.next_out = temp_out.data();
234         strm.avail_out = COMPRESS_SLICE_SIZE;
235         deflate(&strm, Z_FINISH);
236         out.append(reinterpret_cast<char*>(temp_out.data()), COMPRESS_SLICE_SIZE - strm.avail_out);
237     } while (strm.avail_out == 0);
238 
239     deflateEnd(&strm);
240     return out;
241 }
242 
Decompress(const std::string & data)243 std::string Decompress(const std::string& data)
244 {
245     z_stream strm;
246     strm.zalloc = Z_NULL;
247     strm.zfree = Z_NULL;
248     strm.opaque = Z_NULL;
249     strm.avail_in = 0;
250     strm.next_in = Z_NULL;
251     inflateInit(&strm);
252 
253     strm.next_in = reinterpret_cast<Bytef*>(const_cast<char *>(data.data()));
254     strm.avail_in = data.size();
255     std::string out;
256     std::vector<Bytef> temp_out(COMPRESS_SLICE_SIZE, 0);
257 
258     do {
259         strm.next_out = temp_out.data();
260         strm.avail_out = COMPRESS_SLICE_SIZE;
261         inflate(&strm, Z_NO_FLUSH);
262         out.append(reinterpret_cast<char*>(temp_out.data()), COMPRESS_SLICE_SIZE - strm.avail_out);
263     } while (strm.avail_out == 0);
264 
265     inflateEnd(&strm);
266     return out;
267 }
268 
GetSysPara(const char * key,bool & value)269 bool GetSysPara(const char *key, bool &value)
270 {
271     if (key == nullptr) {
272         DHLOGE("GetSysPara: key is nullptr");
273         return false;
274     }
275     char paraValue[20] = {0}; // 20 for system parameter
276     auto res = GetParameter(key, "false", paraValue, sizeof(paraValue));
277     if (res <= 0) {
278         DHLOGD("GetSysPara fail, key:%{public}s res:%{public}d", key, res);
279         return false;
280     }
281     DHLOGI("GetSysPara: key:%{public}s value:%{public}s", key, paraValue);
282     std::stringstream valueStr;
283     valueStr << paraValue;
284     valueStr >> std::boolalpha >> value;
285     return true;
286 }
287 
IsIdLengthValid(const std::string & inputID)288 bool IsIdLengthValid(const std::string &inputID)
289 {
290     if (inputID.empty() || inputID.length() > MAX_ID_LEN) {
291         DHLOGE("On parameter length error, maybe empty or beyond MAX_ID_LEN!");
292         return false;
293     }
294     return true;
295 }
296 
IsMessageLengthValid(const std::string & inputMessage)297 bool IsMessageLengthValid(const std::string &inputMessage)
298 {
299     if (inputMessage.empty() || inputMessage.length() > MAX_MESSAGE_LEN) {
300         DHLOGE("On parameter error, maybe empty or beyond MAX_MESSAGE_LEN!");
301         return false;
302     }
303     return true;
304 }
305 
IsJsonLengthValid(const std::string & inputJsonStr)306 bool IsJsonLengthValid(const std::string &inputJsonStr)
307 {
308     if (inputJsonStr.empty() || inputJsonStr.length() > MAX_JSON_SIZE) {
309         DHLOGE("On parameter error, maybe empty or beyond MAX_JSON_SIZE");
310         return false;
311     }
312     return true;
313 }
314 
IsArrayLengthValid(const std::vector<std::string> & inputArray)315 bool IsArrayLengthValid(const std::vector<std::string> &inputArray)
316 {
317     if (inputArray.empty() || inputArray.size() > MAX_ARR_SIZE) {
318         DHLOGE("On parameter error, maybe empty or beyond MAX_ARR_SIZE");
319         return false;
320     }
321     return true;
322 }
323 
IsKeySizeValid(const std::string & inputKey)324 bool IsKeySizeValid(const std::string &inputKey)
325 {
326     if (inputKey.empty() || inputKey.length() > MAX_KEY_SIZE) {
327         DHLOGE("On parameter error, maybe empty or beyond MAX_KEY_SIZE");
328         return false;
329     }
330     return true;
331 }
332 
IsHashSizeValid(const std::string & inputHashValue)333 bool IsHashSizeValid(const std::string &inputHashValue)
334 {
335     if (inputHashValue.empty() || inputHashValue.length() > MAX_HASH_SIZE) {
336         DHLOGE("On parameter error, maybe empty or beyond MAX_HASH_SIZE");
337         return false;
338     }
339     return true;
340 }
341 
GetDeviceSystemType(const std::string & extraData)342 int32_t GetDeviceSystemType(const std::string &extraData)
343 {
344     cJSON *jsonObj = cJSON_Parse(extraData.c_str());
345     if (jsonObj == NULL) {
346         DHLOGE("jsonStr parse failed");
347         return ERR_DH_FWK_INVALID_OSTYPE;
348     }
349     cJSON *paramKey = cJSON_GetObjectItem(jsonObj, PARAM_KEY_OS_TYPE.c_str());
350     if (paramKey == NULL || !cJSON_IsNumber(paramKey)) {
351         DHLOGE("paramKey is null or paramKey is invaild type!");
352         cJSON_Delete(jsonObj);
353         return ERR_DH_FWK_INVALID_OSTYPE;
354     }
355     int32_t osType = paramKey->valueint;
356     cJSON_Delete(jsonObj);
357     return osType;
358 }
359 } // namespace DistributedHardware
360 } // namespace OHOS
361