1 /*
2 * Copyright (c) 2021 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 <random>
21 #include <sstream>
22 #include <sys/time.h>
23
24 #include "openssl/sha.h"
25 #include "softbus_common.h"
26 #include "softbus_bus_center.h"
27
28 #include "constants.h"
29 #include "distributed_hardware_errno.h"
30 #include "distributed_hardware_log.h"
31
32 namespace OHOS {
33 namespace DistributedHardware {
34 constexpr int32_t MS_ONE_SECOND = 1000;
35 constexpr int32_t WORD_WIDTH_8 = 8;
36 constexpr int32_t WORD_WIDTH_4 = 4;
37
GetCurrentTime()38 int64_t GetCurrentTime()
39 {
40 struct timeval tv {
41 0
42 };
43 gettimeofday(&tv, nullptr);
44 return tv.tv_sec * MS_ONE_SECOND + tv.tv_usec / MS_ONE_SECOND;
45 }
46
GetRandomID()47 std::string GetRandomID()
48 {
49 static std::random_device rd;
50 static std::uniform_int_distribution<uint64_t> dist(0ULL, 0xFFFFFFFFFFFFFFFFULL);
51 uint64_t ab = dist(rd);
52 uint64_t cd = dist(rd);
53 uint32_t a, b, c, d;
54 std::stringstream ss;
55 ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;
56 cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;
57 a = (ab >> 32U);
58 b = (ab & 0xFFFFFFFFU);
59 c = (cd >> 32U);
60 d = (cd & 0xFFFFFFFFU);
61 ss << std::hex << std::nouppercase << std::setfill('0');
62 ss << std::setw(WORD_WIDTH_8) << (a);
63 ss << std::setw(WORD_WIDTH_4) << (b >> 16U);
64 ss << std::setw(WORD_WIDTH_4) << (b & 0xFFFFU);
65 ss << std::setw(WORD_WIDTH_4) << (c >> 16U);
66 ss << std::setw(WORD_WIDTH_4) << (c & 0xFFFFU);
67 ss << std::setw(WORD_WIDTH_8) << d;
68
69 return ss.str();
70 }
71
GetUUIDBySoftBus(const std::string & networkId)72 std::string GetUUIDBySoftBus(const std::string &networkId)
73 {
74 if (networkId.empty()) {
75 return "";
76 }
77 char uuid[UUID_BUF_LEN] = {0};
78 auto ret = GetNodeKeyInfo(DH_FWK_PKG_NAME.c_str(), networkId.c_str(), NodeDeviceInfoKey::NODE_KEY_UUID,
79 reinterpret_cast<uint8_t *>(uuid), UUID_BUF_LEN);
80 return (ret == DH_FWK_SUCCESS) ? std::string(uuid) : "";
81 }
82
GetDeviceIdByUUID(const std::string & uuid)83 std::string GetDeviceIdByUUID(const std::string &uuid)
84 {
85 if (uuid.size() == 0 || uuid.size() > MAX_ID_LEN) {
86 DHLOGE("uuid is invalid!");
87 return "";
88 }
89 return Sha256(uuid);
90 }
91
Sha256(const std::string & in)92 std::string Sha256(const std::string& in)
93 {
94 unsigned char out[SHA256_DIGEST_LENGTH * 2 + 1] = {0};
95 SHA256_CTX ctx;
96 SHA256_Init(&ctx);
97 SHA256_Update(&ctx, in.data(), in.size());
98 SHA256_Final(&out[SHA256_DIGEST_LENGTH], &ctx);
99 // here we translate sha256 hash to hexadecimal. each 8-bit char will be presented by two characters([0-9a-f])
100 constexpr int32_t WIDTH = 4;
101 constexpr unsigned char MASK = 0x0F;
102 const char* hexCode = "0123456789abcdef";
103 constexpr int32_t DOUBLE_TIMES = 2;
104 for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
105 unsigned char value = out[SHA256_DIGEST_LENGTH + i];
106 // uint8_t is 2 digits in hexadecimal.
107 out[i * DOUBLE_TIMES] = hexCode[(value >> WIDTH) & MASK];
108 out[i * DOUBLE_TIMES + 1] = hexCode[value & MASK];
109 }
110 out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES] = 0;
111 return reinterpret_cast<char*>(out);
112 }
113
GetLocalDeviceInfo()114 DeviceInfo GetLocalDeviceInfo()
115 {
116 DeviceInfo devInfo { "", "", "", 0 };
117 auto info = std::make_unique<NodeBasicInfo>();
118 auto ret = GetLocalNodeDeviceInfo(DH_FWK_PKG_NAME.c_str(), info.get());
119 if (ret != DH_FWK_SUCCESS) {
120 DHLOGE("GetLocalNodeDeviceInfo failed, errCode = %d", ret);
121 return devInfo;
122 }
123 devInfo.uuid = GetUUIDBySoftBus(info->networkId);
124 devInfo.deviceId = GetDeviceIdByUUID(devInfo.uuid);
125 devInfo.deviceName = info->deviceName;
126 devInfo.deviceType = info->deviceTypeId;
127 return devInfo;
128 }
129
IsUInt16(const nlohmann::json & jsonObj,const std::string & key)130 bool IsUInt16(const nlohmann::json& jsonObj, const std::string& key)
131 {
132 bool res = jsonObj.contains(key) && jsonObj[key].is_number_unsigned() && jsonObj[key] <= UINT16_MAX;
133 return res;
134 }
135
IsInt32(const nlohmann::json & jsonObj,const std::string & key)136 bool IsInt32(const nlohmann::json& jsonObj, const std::string& key)
137 {
138 bool res = jsonObj.contains(key) && jsonObj[key].is_number_integer() && INT32_MIN <= jsonObj[key] &&
139 jsonObj[key] <= INT32_MAX;
140 return res;
141 }
142
IsUInt32(const nlohmann::json & jsonObj,const std::string & key)143 bool IsUInt32(const nlohmann::json& jsonObj, const std::string& key)
144 {
145 bool res = jsonObj.contains(key) && jsonObj[key].is_number_unsigned() && jsonObj[key] <= UINT32_MAX;
146 return res;
147 }
148
IsBool(const nlohmann::json & jsonObj,const std::string & key)149 bool IsBool(const nlohmann::json& jsonObj, const std::string& key)
150 {
151 bool res = jsonObj.contains(key) && jsonObj[key].is_boolean();
152 return res;
153 }
154
IsString(const nlohmann::json & jsonObj,const std::string & key)155 bool IsString(const nlohmann::json& jsonObj, const std::string& key)
156 {
157 bool res = jsonObj.contains(key) && jsonObj[key].is_string() && MIN_MESSAGE_LEN < jsonObj[key].size() &&
158 jsonObj[key].size() <= MAX_MESSAGE_LEN;
159 return res;
160 }
161 } // namespace DistributedHardware
162 } // namespace OHOS
163