• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /**
17  * @addtogroup Bluetooth
18  * @{
19  *
20  * @brief Defines uuid for framework.
21  *
22  * @since 6
23  */
24 
25 /**
26  * @file uuid.h
27  *
28  * @brief framework uuid interface.
29  *
30  * @since 6
31  */
32 
33 #ifndef DUMMY_UUID_H
34 #define DUMMY_UUID_H
35 
36 #include "sys/time.h"
37 #include <string>
38 #include <array>
39 #include <ctime>
40 #include <regex>
41 
42 namespace OHOS {
43 namespace Bluetooth {
44 const std::regex uuidRegex("^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$");
45 
46 /**
47  * @brief This class provides framework uuid.
48  *
49  * @since 6
50  */
51 class UUID {
52 public:
53     //128 bits uuid length
54     const static int UUID128_BYTES_LEN = 16;
55 
56     /**
57      * @brief A constructor used to create an <b>UUID</b> instance.
58      *
59      * @since 6
60      */
UUID()61     UUID(){};
62 
63     /**
64      * @brief A destructor used to delete the <b>UUID</b> instance.
65      *
66      * @since 6
67      */
~UUID()68     ~UUID(){};
69 
70     /**
71      * @brief A constructor used to create an <b>UUID</b> instance. Constructor a new UUID using most significant 64
72      * bits and least significant 64 bits.
73      *
74      * @param[in] mostSigBits  : The most significant 64 bits of UUID.
75      * @param[in] leastSigBits : The least significant 64 bits of UUID.
76      * @since 6
77      */
UUID(const long mostSigBits,const long leastSigBits)78     UUID(const long mostSigBits, const long leastSigBits)
79     {
80         this->uuid_[15] = static_cast<uint8_t>(leastSigBits & 0x00000000000000FF); // 15是uuid的数组下标
81         this->uuid_[14] = static_cast<uint8_t>((leastSigBits & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
82         // 13是uuid的数组下标,右移16位
83         this->uuid_[13] = static_cast<uint8_t>((leastSigBits & 0x0000000000FF0000) >> 16);
84         // 12是uuid的数组下标,右移24位
85         this->uuid_[12] = static_cast<uint8_t>((leastSigBits & 0x00000000FF000000) >> 24);
86         // 11是uuid的数组下标,右移32位
87         this->uuid_[11] = static_cast<uint8_t>((leastSigBits & 0x000000FF00000000) >> 32);
88         // 10是uuid的数组下标,右移40位
89         this->uuid_[10] = static_cast<uint8_t>((leastSigBits & 0x0000FF0000000000) >> 40);
90         this->uuid_[9] = static_cast<uint8_t>((leastSigBits & 0x00FF000000000000) >> 48); // 9是uuid的数组下标,右移48位
91         this->uuid_[8] = static_cast<uint8_t>((leastSigBits & 0xFF00000000000000) >> 56); // 8是uuid的数组下标,右移56位
92         this->uuid_[7] = static_cast<uint8_t>(mostSigBits & 0x00000000000000FF); // 7是uuid的数组下标,右移8位
93         this->uuid_[6] = static_cast<uint8_t>((mostSigBits & 0x000000000000FF00) >> 8); // 6是uuid的数组下标,右移8位
94         this->uuid_[5] = static_cast<uint8_t>((mostSigBits & 0x0000000000FF0000) >> 16); // 5是uuid的数组下标,右移16位
95         this->uuid_[4] = static_cast<uint8_t>((mostSigBits & 0x00000000FF000000) >> 24); // 4是uuid的数组下标,右移24位
96         this->uuid_[3] = static_cast<uint8_t>((mostSigBits & 0x000000FF00000000) >> 32); // 3是uuid的数组下标,右移32位
97         this->uuid_[2] = static_cast<uint8_t>((mostSigBits & 0x0000FF0000000000) >> 40); // 2是uuid的数组下标,右移40位
98         this->uuid_[1] = static_cast<uint8_t>((mostSigBits & 0x00FF000000000000) >> 48); // 1是uuid的数组下标,右移48位
99         this->uuid_[0] = static_cast<uint8_t>((mostSigBits & 0xFF00000000000000) >> 56); // 0是uuid的数组下标,右移56位
100     }
101 
102     /**
103      * @brief A constructor used to create an <b>UUID</b> instance. Constructor a new UUID from string.
104      *
105      * @param[in] name : The value of string to create UUID.
106      *      for example : "00000000-0000-1000-8000-00805F9B34FB"
107      * @return Returns a specified UUID.
108      * @since 6
109      */
FromString(const std::string & name)110     static UUID FromString(const std::string &name)
111     {
112         UUID ret;
113         std::string tmp = name;
114         std::size_t pos = tmp.find("-");
115 
116         while (pos != std::string::npos) {
117             tmp.replace(pos, 1, "");
118             pos = tmp.find("-");
119         }
120 
121         for (std::size_t i = 0; (i + 1) < tmp.length();) {
122             ret.uuid_[i / 2] = std::stoi(tmp.substr(i, 2), nullptr, 16); // uuid的长度为16,i / 2作为uuid的数组下标
123             i += 2; // for 循环中,每轮增加2
124         }
125 
126         return ret;
127     }
128 
129     /**
130      * @brief A constructor used to create an <b>UUID</b> instance. Constructor a new random UUID.
131      *
132      * @return Returns a random UUID.
133      * @since 6
134      */
RandomUUID()135     static UUID RandomUUID()
136     {
137         UUID random;
138 
139         struct timeval tv;
140         struct timezone tz;
141         struct tm randomTime;
142         unsigned int randNum = 0;
143 
144         rand_r(&randNum);
145         gettimeofday(&tv, &tz);
146         localtime_r(&tv.tv_sec, &randomTime);
147 
148         random.uuid_[15] = (uint8_t)(tv.tv_usec & 0x00000000000000FF);
149         random.uuid_[14] = (uint8_t)((tv.tv_usec & 0x000000000000FF00) >> 8);
150         random.uuid_[13] = (uint8_t)((tv.tv_usec & 0x0000000000FF0000) >> 16);
151         random.uuid_[12] = (uint8_t)((tv.tv_usec & 0x00000000FF000000) >> 24);
152         random.uuid_[10] = (uint8_t)((tv.tv_usec & 0x000000FF00000000) >> 32);
153         random.uuid_[9] = (uint8_t)((tv.tv_usec & 0x0000FF0000000000) >> 40);
154         random.uuid_[8] = (uint8_t)((tv.tv_usec & 0x00FF000000000000) >> 48);
155         random.uuid_[7] = (uint8_t)((tv.tv_usec & 0xFF00000000000000) >> 56);
156         random.uuid_[6] = (uint8_t)((randomTime.tm_sec + randNum) & 0xFF);
157         random.uuid_[5] = (uint8_t)((randomTime.tm_min + (randNum >> 8)) & 0xFF);
158         random.uuid_[4] = (uint8_t)((randomTime.tm_hour + (randNum >> 16)) & 0xFF);
159         random.uuid_[3] = (uint8_t)((randomTime.tm_mday + (randNum >> 24)) & 0xFF);
160         random.uuid_[2] = (uint8_t)(randomTime.tm_mon & 0xFF);
161         random.uuid_[1] = (uint8_t)(randomTime.tm_year & 0xFF);
162         random.uuid_[0] = (uint8_t)((randomTime.tm_year & 0xFF00) >> 8);
163 
164         return random;
165     }
166 
167     /**
168      * @brief Convert UUID to string.
169      *
170      * @return Returns a String object representing this UUID.
171      * @since 6
172      */
ToString()173     std::string ToString() const
174     {
175         std::string tmp = "";
176         std::string ret = "";
177         static const char *hex = "0123456789ABCDEF";
178 
179         for (auto it = this->uuid_.begin(); it != this->uuid_.end(); it++) {
180             tmp.push_back(hex[(((*it) >> 4) & 0xF)]); // 右移4位
181             tmp.push_back(hex[(*it) & 0xF]);
182         }
183         // ToString操作,8, 4, 12, 16,20 作为截取字符的开始位置或截取长度
184         ret = tmp.substr(0, 8) + "-" + tmp.substr(8, 4) + "-" + tmp.substr(12, 4) + "-" + tmp.substr(16, 4) + "-" +
185               tmp.substr(20);
186 
187         return ret;
188     }
189 
190     /**
191      * @brief Compares this UUID with the specified UUID.
192      *
193      * @param[in] val : UUID which this UUID is to be compared.
194      * @return Returns <b> <0 </b> if this UUID is less than compared UUID;
195      *         returns <b> =0 </b> if this UUID is equal to compared UUID;
196      *         returns <b> >0 </b> if this UUID is greater than compared UUID.
197      * @since 6
198      */
CompareTo(const UUID & val)199     int CompareTo(const UUID &val) const
200     {
201         UUID tmp = val;
202         return this->ToString().compare(tmp.ToString());
203     }
204 
205     /**
206      * @brief Compares this object to the specified object.
207      *
208      * @param[in] val : UUID which this UUID is to be compared.
209      * @return Returns <b>true</b> if this UUID is the same as compared UUID;
210      *         returns <b>false</b> if this UUID is not the same as compared UUID.
211      * @since 6
212      */
Equals(const UUID & val)213     bool Equals(const UUID &val) const
214     {
215         for (int i = 0; i < UUID128_BYTES_LEN; i++) {
216             if (this->uuid_[i] != val.uuid_[i]) {
217                 return false;
218             }
219         }
220         return true;
221     }
222 
223     /**
224      * @brief Returns the least significant 64 bits of this UUID's 128 bit value.
225      *
226      * @return Retruns the least significant 64 bits of this UUID's 128 bit value.
227      * @since 6
228      */
GetLeastSignificantBits()229     uint64_t GetLeastSignificantBits() const
230     {
231         uint64_t leastSigBits = 0;
232         for (int i = UUID128_BYTES_LEN / 2; i < UUID128_BYTES_LEN; i++) { // uuid长度/2作为i初始值
233             leastSigBits = (leastSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
234         }
235         return leastSigBits;
236     }
237 
238     /**
239      * @brief Returns the most significant 64 bits of this UUID's 128 bit value.
240      *
241      * @return Returns the most significant 64 bits of this UUID's 128 bit value.
242      * @since 6
243      */
GetMostSignificantBits()244     uint64_t GetMostSignificantBits() const
245     {
246         uint64_t mostSigBits = 0;
247         for (int i = 0 / 2; i < UUID128_BYTES_LEN / 2; i++) { // uuid长度/2作为i最大值
248             mostSigBits = (mostSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
249         }
250         return mostSigBits;
251     }
252 
253     /**
254      * @brief Constructor a new UUID from uint8_t array.
255      *
256      * @param[in] name : The 128 bits value for a UUID.
257      * @return Returns a specified UUID.
258      * @since 6
259      */
ConvertFrom128Bits(const std::array<uint8_t,UUID128_BYTES_LEN> & name)260     static UUID ConvertFrom128Bits(const std::array<uint8_t, UUID128_BYTES_LEN> &name)
261     {
262         UUID tmp;
263         for (int i = 0; i < UUID128_BYTES_LEN; i++) {
264             tmp.uuid_[i] = name[i];
265         }
266         return tmp;
267     }
268 
269     /**
270      * @brief Returns uint8_t array from UUID.
271      *
272      * @return returns a specified array.
273      * @since 6
274      */
ConvertTo128Bits()275     std::array<uint8_t, UUID128_BYTES_LEN> ConvertTo128Bits() const
276     {
277         std::array<uint8_t, UUID128_BYTES_LEN> uuid;
278 
279         for (int i = 0; i < UUID128_BYTES_LEN; i++) {
280             uuid[i] = uuid_[i];
281         }
282 
283         return uuid;
284     }
285 
286     /**
287      * @brief In order to use the object key in the map object, overload the operator <.
288      * @param[in] uuid : UUID object.
289      * @return @c bool : If the object uuid is the same, return true, otherwise return false.
290      */
291     bool operator<(const UUID &uuid) const
292     {
293         return !Equals(uuid);
294     }
295 
296 private:
297     std::array<uint8_t, UUID128_BYTES_LEN> uuid_ = {0x00};
298 };
299 
300 /**
301  * @brief This class provides framework ParcelUuid.
302  *
303  * @since 6
304  */
305 using ParcelUuid = UUID;
306 
307 } // namespace Bluetooth
308 } // namespace OHOS
309 
310 #endif  //DUMMY_UUID_H