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 "bt_uuid.h"
17
18 #include <sys/time.h>
19 #include <algorithm>
20 #include <cstdlib>
21 #include "array"
22 #include "securec.h"
23 #include <cstdlib>
24 #include "string"
25 #include "sys/time.h"
26 #include <ctime>
27
28 namespace OHOS {
29 namespace bluetooth {
Random()30 Uuid Uuid::Random()
31 {
32 Uuid random;
33
34 struct timeval tv = {};
35 struct timezone tz = {};
36 struct tm randomTime = {};
37 unsigned int randNum = 0;
38 unsigned long int tvUsec = 0;
39
40 rand_r(&randNum);
41 gettimeofday(&tv, &tz);
42 localtime_r(&tv.tv_sec, &randomTime);
43
44 tvUsec = static_cast<unsigned long int>(tv.tv_usec);
45
46 random.uuid_[UUID_NODE_SIXTH_BYTE] =
47 static_cast<uint8_t>(tvUsec & 0x00000000000000FF);
48 random.uuid_[UUID_NODE_FIFTH_BYTE] =
49 static_cast<uint8_t>((tvUsec & 0x000000000000FF00) >> BASE_BIT_OPT_SIZE);
50 random.uuid_[UUID_NODE_FOURTH_BYTE] =
51 static_cast<uint8_t>((tvUsec & 0x0000000000FF0000) >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE);
52 random.uuid_[UUID_NODE_THIRD_BYTE] =
53 static_cast<uint8_t>((tvUsec & 0x00000000FF000000) >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE);
54 random.uuid_[UUID_NODE_FIRST_BYTE] =
55 static_cast<uint8_t>((tvUsec & 0x000000FF00000000) >> BIT_OPT_FOUR_BYTE * BASE_BIT_OPT_SIZE);
56 random.uuid_[UUID_CLOCK_SEQ] =
57 static_cast<uint8_t>((tvUsec & 0x0000FF0000000000) >> BIT_OPT_FIVE_BYTE * BASE_BIT_OPT_SIZE);
58 random.uuid_[UUID_VARIANT] =
59 static_cast<uint8_t>((tvUsec & 0x00FF000000000000) >> BIT_OPT_SIX_BYTE * BASE_BIT_OPT_SIZE);
60 random.uuid_[UUID_TIME_HIGH] =
61 static_cast<uint8_t>((tvUsec & 0xFF00000000000000) >> BIT_OPT_SEVEN_BYTE * BASE_BIT_OPT_SIZE);
62 random.uuid_[UUID_VERSION] =
63 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_sec) + randNum) & 0xFF);
64 random.uuid_[UUID_TIME_MID_SECEND_BYTE] =
65 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_min) + (randNum >> BASE_BIT_OPT_SIZE)) & 0xFF);
66 random.uuid_[UUID_TIME_MID_FIRST_BYTE] =
67 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_hour) +
68 (randNum >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF);
69 random.uuid_[UUID_TIME_LOW_FOURTH_BYTE] =
70 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_mday) +
71 (randNum >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF);
72 random.uuid_[UUID_TIME_LOW_THIRD_BYTE] =
73 static_cast<uint8_t>(static_cast<unsigned int>(randomTime.tm_mon) & 0xFF);
74 random.uuid_[UUID_TIME_LOW_SECEND_BYTE] =
75 static_cast<uint8_t>(static_cast<unsigned int>(randomTime.tm_year) & 0xFF);
76 random.uuid_[UUID_TIME_LOW_FIRST_BYTE] =
77 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_year) & 0xFF00) >> BASE_BIT_OPT_SIZE);
78
79 return random;
80 }
81
ConvertFromString(const std::string & name)82 Uuid Uuid::ConvertFromString(const std::string &name)
83 {
84 Uuid ret;
85 std::string tmp = name;
86 std::size_t pos = tmp.find("-");
87
88 while (pos != std::string::npos) {
89 tmp.replace(pos, 1, "");
90 pos = tmp.find("-");
91 }
92
93 for (std::size_t i = 0; (i + 1) < tmp.length(); i += SIZE_STRING_TO_INT) {
94 ret.uuid_[i / SIZE_STRING_TO_INT] = std::stoi(tmp.substr(i, SIZE_STRING_TO_INT), nullptr, UUID128_BYTES_TYPE);
95 }
96
97 return ret;
98 }
99
ConvertFrom16Bits(uint16_t uuid)100 Uuid Uuid::ConvertFrom16Bits(uint16_t uuid)
101 {
102 Uuid tmp;
103 tmp.uuid_[UUID_TIME_LOW_THIRD_BYTE] = static_cast<uint8_t>((uuid & 0xFF00) >> BASE_BIT_OPT_SIZE);
104 tmp.uuid_[UUID_TIME_LOW_FOURTH_BYTE] = static_cast<uint8_t>(uuid & 0x00FF);
105 return tmp;
106 }
107
ConvertFrom32Bits(uint32_t uuid)108 Uuid Uuid::ConvertFrom32Bits(uint32_t uuid)
109 {
110 Uuid tmp;
111 tmp.uuid_[UUID_TIME_LOW_FIRST_BYTE] =
112 static_cast<uint8_t>((uuid & 0xFF000000) >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE);
113 tmp.uuid_[UUID_TIME_LOW_SECEND_BYTE] =
114 static_cast<uint8_t>((uuid & 0x00FF0000) >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE);
115 tmp.uuid_[UUID_TIME_LOW_THIRD_BYTE] =
116 static_cast<uint8_t>((uuid & 0x0000FF00) >> BASE_BIT_OPT_SIZE);
117 tmp.uuid_[UUID_TIME_LOW_FOURTH_BYTE] =
118 static_cast<uint8_t>(uuid & 0x000000FF);
119 return tmp;
120 }
121
ConvertFromBytesLE(const uint8_t * uuid,const size_t size)122 Uuid Uuid::ConvertFromBytesLE(const uint8_t *uuid, const size_t size)
123 {
124 Uuid leUuid;
125 if (size < UUID128_BYTES_TYPE) {
126 return leUuid;
127 }
128 UUID128Bit le;
129 if (memcpy_s(le.data(), UUID128_BYTES_TYPE, uuid, UUID128_BYTES_TYPE) != EOK) {
130 return leUuid;
131 }
132 std::reverse_copy(le.data(), le.data() + UUID128_BYTES_TYPE, leUuid.uuid_.begin());
133 return leUuid;
134 }
135
ConvertFromMostAndLeastBit(uint64_t mostSigBits,uint64_t leastSigBits)136 Uuid Uuid::ConvertFromMostAndLeastBit(uint64_t mostSigBits, uint64_t leastSigBits)
137 {
138 Uuid tmp;
139 int division = UUID128_BYTES_TYPE / SIZE_STRING_TO_INT;
140
141 for (int i = 0; i < division; i++) {
142 tmp.uuid_[i] = (mostSigBits >> (BASE_BIT_OPT_SIZE * (division - i - 1))) & 0xFF;
143 }
144
145 for (int i = division; i < UUID128_BYTES_TYPE; i++) {
146 tmp.uuid_[i] = (leastSigBits >> (BASE_BIT_OPT_SIZE * (2 * division - i - 1))) & 0xFF; // value of division * 2
147 }
148
149 return tmp;
150 }
151
ConvertFrom128Bits(const UUID128Bit & uuid)152 Uuid Uuid::ConvertFrom128Bits(const UUID128Bit &uuid)
153 {
154 Uuid tmp;
155 tmp.uuid_ = uuid;
156 return tmp;
157 }
158
ConvertTo16Bits() const159 uint16_t Uuid::ConvertTo16Bits() const
160 {
161 uint16_t ret = uuid_[UUID_TIME_LOW_THIRD_BYTE] & 0xFF;
162 ret = (ret << BASE_BIT_OPT_SIZE) + uuid_[UUID_TIME_LOW_FOURTH_BYTE];
163 return ret;
164 }
165
ConvertTo32Bits() const166 uint32_t Uuid::ConvertTo32Bits() const
167 {
168 uint32_t ret = 0;
169 for (int i = 0; i < UUID32_BYTES_TYPE; i++) {
170 ret = (ret << BASE_BIT_OPT_SIZE) + uuid_[i];
171 }
172 return ret;
173 }
174
ConvertToBytesLE(uint8_t * value,const size_t size) const175 bool Uuid::ConvertToBytesLE(uint8_t *value, const size_t size) const
176 {
177 if (size < UUID128_BYTES_TYPE) {
178 return false;
179 }
180
181 UUID128Bit le;
182 std::reverse_copy(uuid_.data(), uuid_.data() + UUID128_BYTES_TYPE, le.begin());
183 if (memcpy_s(value, UUID128_BYTES_TYPE, le.data(), UUID128_BYTES_TYPE) != EOK) {
184 return false;
185 }
186 return true;
187 }
188
ConvertTo128Bits() const189 Uuid::UUID128Bit Uuid::ConvertTo128Bits() const
190 {
191 return uuid_;
192 }
193
GetUuidType() const194 int Uuid::GetUuidType() const
195 {
196 for (int i = UUID32_BYTES_TYPE; i < UUID128_BYTES_TYPE; i++) {
197 if (BASE_UUID[i] != uuid_[i]) {
198 return UUID128_BYTES_TYPE;
199 }
200 }
201
202 if ((uuid_[0] == 0) && (uuid_[1] == 0)) {
203 return UUID16_BYTES_TYPE;
204 }
205
206 return UUID32_BYTES_TYPE;
207 }
208
operator ==(const Uuid & rhs) const209 bool Uuid::operator==(const Uuid &rhs) const
210 {
211 return (uuid_ == rhs.uuid_);
212 }
213
operator !=(const Uuid & rhs) const214 bool Uuid::operator!=(const Uuid &rhs) const
215 {
216 return (uuid_ != rhs.uuid_);
217 }
218 } // namespace bluetooth
219 } // namespace OHOS