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 #ifndef BT_UUID_H
17 #define BT_UUID_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <array>
22 #include "cstdint"
23 #include "iosfwd"
24 #include <string>
25 
26 /**
27  * @brief The bluetooth subsystem.
28  */
29 namespace OHOS {
30 namespace bluetooth {
31 /**
32  * @brief This class provides service uuid.
33  *
34  * @since 6
35  */
36 class Uuid {
37 public:
38     // 128 bits uuid length type
39     const static int UUID128_BYTES_TYPE = 16;
40     // 32 bits uuid length
41     const static int UUID32_BYTES_TYPE = 4;
42     // 16 bits uuid length
43     const static int UUID16_BYTES_TYPE = 2;
44     using UUID128Bit = std::array<uint8_t, UUID128_BYTES_TYPE>;
45 
46     const static int UUID_TIME_LOW_FIRST_BYTE = 0;
47     const static int UUID_TIME_LOW_SECEND_BYTE = 1;
48     const static int UUID_TIME_LOW_THIRD_BYTE = 2;
49     const static int UUID_TIME_LOW_FOURTH_BYTE = 3;
50     const static int UUID_TIME_MID_FIRST_BYTE = 4;
51     const static int UUID_TIME_MID_SECEND_BYTE = 5;
52     const static int UUID_VERSION = 6;
53     const static int UUID_TIME_HIGH = 7;
54     const static int UUID_VARIANT = 8;
55     const static int UUID_CLOCK_SEQ = 9;
56     const static int UUID_NODE_FIRST_BYTE = 10;
57     const static int UUID_NODE_SECEND_BYTE = 11;
58     const static int UUID_NODE_THIRD_BYTE = 12;
59     const static int UUID_NODE_FOURTH_BYTE = 13;
60     const static int UUID_NODE_FIFTH_BYTE = 14;
61     const static int UUID_NODE_SIXTH_BYTE = 15;
62 
63     const static int BASE_BIT_OPT_SIZE = 8;
64     const static int BIT_OPT_TWO_BYTE = 2;
65     const static int BIT_OPT_THREE_BYTE = 3;
66     const static int BIT_OPT_FOUR_BYTE = 4;
67     const static int BIT_OPT_FIVE_BYTE = 5;
68     const static int BIT_OPT_SIX_BYTE = 6;
69     const static int BIT_OPT_SEVEN_BYTE = 7;
70 
71     const static int SIZE_STRING_TO_INT = 2;
72     /**
73      * @brief A constructor used to create an <b>UUID</b> instance.
74      *
75      * @since 6
76      */
77     Uuid() = default;
78 
79     /**
80      * @brief A constructor used to create an <b>UUID</b> instance.
81      *
82      * @param other Other uuid to create an <b>UUID</b> instance.
83      * @since 6
84      */
85     Uuid(const Uuid &other) = default;
86 
87     /**
88      * @brief The assignment constructor.
89      *
90      * @param other Other uuid object.
91      * @return Returns the reference of Uuid.
92      * @since 6
93      */
94     Uuid &operator=(const Uuid &other) = default;
95 
96     /**
97      * @brief A destructor used to delete the <b>UUID</b> instance.
98      *
99      * @since 6
100      */
101     ~Uuid() = default;
102 
103     /**
104      * @brief Create a random uuid.
105      *
106      * @return @c Uuid : The function return a random uuid.
107      */
108     static Uuid Random();
109 
110     /**
111      * @brief Constructor a new Uuid from string.
112      *
113      * @param name The value of string to create Uuid.
114      *      for example : "00000000-0000-1000-8000-00805F9B34FB"
115      * @return Returns a specified Uuid.
116      * @since 6
117      */
118     static Uuid ConvertFromString(const std::string &name);
119 
120     /**
121      * @brief Create a new uuid from uint16_t.
122      *
123      * @param uuid The 16 bits is a part of 128 bits.
124      * @return Returns a new uuid.
125      * @since 6
126      */
127     static Uuid ConvertFrom16Bits(uint16_t uuid);
128 
129     /**
130      * @brief Create a new uuid from uint32_t.
131      *
132      * @param uuid The 32 bits is a part of 128 bits.
133      * @return Return a new uuid.
134      * @since 6
135      */
136     static Uuid ConvertFrom32Bits(uint32_t uuid);
137 
138     /**
139      * @brief Create a new uuid from little endian bytes.
140      *
141      * @param uuid The 128 bits value for a uuid.
142      * @return Returns a new uuid.
143      * @since 6
144      */
145     static Uuid ConvertFromBytesLE(const uint8_t *uuid, const size_t size = 16);
146 
147     /**
148      * @brief Create a new uuid by most significant 64 bits and least signigicant 64 bits.
149      *
150      * @param uuid The 128 bits value for a uuid.
151      * @return Returns a new uuid.
152      * @since 6
153      */
154     static Uuid ConvertFromMostAndLeastBit(uint64_t mostSigBits, uint64_t leastSigBits);
155 
156     /**
157      * @brief Create a new uuid from uint8_t array.
158      *
159      * @param uuid The 128 bits value for a uuid.
160      * @return Returns a uuid from uint8_t array.
161      * @since 6
162      */
163     static Uuid ConvertFrom128Bits(const UUID128Bit &uuid);
164 
165     /**
166      * @brief Convert uuid to 16 bits.
167      *
168      * @return Returns a uint16_t value from uuid.
169      * @since 6
170      */
171     uint16_t ConvertTo16Bits() const;
172 
173     /**
174      * @brief Convert uuid to 32 bits.
175      *
176      * @return Returns a uint32_t value from uuid.
177      * @since 6
178      */
179     uint32_t ConvertTo32Bits() const;
180 
181     /**
182      * @brief Convert uuid to uint8_t* with little endian.
183      *
184      * @param[in] value : The 128 bits value for a uuid.
185      * @return Returns <b>true</b> if the operation is successful;
186      *         returns <b>false</b> if the operation fails.
187      * @since 6
188      */
189     bool ConvertToBytesLE(uint8_t *value, const size_t size = 16) const;
190 
191     /**
192      * @brief Convert uuid to uint8_t array.
193      *
194      * @return Returns a new uuid.
195      * @since 6
196      */
197     UUID128Bit ConvertTo128Bits() const;
198 
199     /**
200      * @brief Get UUID type: 16 bits or 32 bits or 128 bits
201      *
202      * @return Returns uuid type.
203      *         UUID128_BYTES_TYPE : 128 bits uuid.
204      *         UUID32_BYTES_TYPE : 32 bits uuid.
205      *         UUID16_BYTES_TYPE : 16 bits uuid.
206      * @since 6
207      */
208     int GetUuidType() const;
209 
210     /**
211      * @brief Compare two uuid whether are same or not.
212      *
213      * @param rhs Compared UUID instance.
214      * @return Returns <b>true</b> if this UUID is the same as compared UUID;
215      *         returns <b>false</b> if this UUID is not the same as compared UUID.
216      * @since 6
217      */
218     bool operator==(const Uuid &rhs) const;
219 
220     /**
221      * @brief Compare two uuid whether are different or not.
222      *
223      * @param rhs Compared UUID instance.
224      * @return Returns <b>true</b> if this UUID is different as compared UUID;
225      *         returns <b>false</b> if this UUID is not different as compared UUID.
226      * @since 6
227      */
228     bool operator!=(const Uuid &rhs) const;
229 
230     /**
231      * @brief In order to use the object key in the map object, overload the operator <.
232      * @param[in] uuid : Uuid object.
233      * @return @c bool : If the object uuid is the same, return true, otherwise return false.
234      */
235     bool operator<(const Uuid &uuid) const
236     {
237         return *this != uuid;
238     }
239 
240     /**
241      * @brief Convert UUID to string.
242      *
243      * @return Returns a String object representing this UUID.
244      * @since 6
245      */
ToString()246     std::string ToString() const
247     {
248         std::string tmp = "";
249         std::string ret = "";
250         static const char *hex = "0123456789ABCDEF";
251         const uint8_t size4 = 4;
252         const uint8_t pos8 = 8;
253         const uint8_t pos12 = 12;
254         const uint8_t pos16 = 16;
255         const uint8_t pos20 = 20;
256 
257         for (auto it = this->uuid_.begin(); it != this->uuid_.end(); ++it) {
258             tmp.push_back(hex[(((*it) >> size4) & 0xF)]);
259             tmp.push_back(hex[(*it) & 0xF]);
260         }
261         // 00000000-0000-1000-8000-00805F9B34FB
262         ret = tmp.substr(0, pos8) + "-" + tmp.substr(pos8, size4) + "-" + tmp.substr(pos12, size4) + "-" +
263             tmp.substr(pos16, size4) + "-" + tmp.substr(pos20);
264 
265         return ret;
266     }
267 
268 protected:
269     /**
270      * @brief Constructor.
271      */
Uuid(const UUID128Bit uuid)272     explicit Uuid(const UUID128Bit uuid) : uuid_(uuid) {};
273 
274     // base uuid value
275     std::array<uint8_t, UUID128_BYTES_TYPE> BASE_UUID = {
276         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
277         0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
278     };
279 
280     std::array<uint8_t, UUID128_BYTES_TYPE> uuid_ = BASE_UUID;
281 };
282 }  // namespace bluetooth
283 }  // namespace OHOS
284 
285 #endif  // BT_UUID_H