• 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         random.uuid_[15] = static_cast<uint8_t>(tv.tv_usec & 0x00000000000000FF); // 15是uuid的数组下标
148         random.uuid_[14] = static_cast<uint8_t>((tv.tv_usec & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
149         random.uuid_[13] = static_cast<uint8_t>((tv.tv_usec & 0x0000000000FF0000) >> 16); // 13是uuid的数组下标,右移16位
150         random.uuid_[12] = static_cast<uint8_t>((tv.tv_usec & 0x00000000FF000000) >> 24); // 12是uuid的数组下标,右移24位
151         random.uuid_[10] = static_cast<uint8_t>((tv.tv_usec & 0x000000FF00000000) >> 32); // 10是uuid的数组下标,右移32位
152         random.uuid_[9] = static_cast<uint8_t>((tv.tv_usec & 0x0000FF0000000000) >> 40); // 9是uuid的数组下标,右移40位
153         random.uuid_[8] = static_cast<uint8_t>((tv.tv_usec & 0x00FF000000000000) >> 48); // 8是uuid的数组下标,右移48位
154         random.uuid_[7] = static_cast<uint8_t>((tv.tv_usec & 0xFF00000000000000) >> 56); // 7是uuid的数组下标,右移56位
155         // 6是uuid的数组下标
156         random.uuid_[6] = static_cast<uint8_t>((randomTime.tm_sec + static_cast<int>(randNum)) & 0xFF);
157         // 5是uuid的数组下标,右移8位
158         random.uuid_[5] = static_cast<uint8_t>((randomTime.tm_min + (randNum >> 8)) & 0xFF);
159         // 4是uuid的数组下标,右移16位
160         random.uuid_[4] = static_cast<uint8_t>((randomTime.tm_hour + (randNum >> 16)) & 0xFF);
161         // 3是uuid的数组下标,右移24位
162         random.uuid_[3] = static_cast<uint8_t>((randomTime.tm_mday + (randNum >> 24)) & 0xFF);
163         random.uuid_[2] = static_cast<uint8_t>(randomTime.tm_mon & 0xFF); // 2是uuid的数组下标
164         random.uuid_[1] = static_cast<uint8_t>(randomTime.tm_year & 0xFF); // 1是uuid的数组下标
165         random.uuid_[0] = static_cast<uint8_t>((randomTime.tm_year & 0xFF00) >> 8); // 0是uuid的数组下标,右移8位
166         return random;
167     }
168 
169     /**
170      * @brief Convert UUID to string.
171      *
172      * @return Returns a String object representing this UUID.
173      * @since 6
174      */
ToString()175     std::string ToString() const
176     {
177         std::string tmp = "";
178         std::string ret = "";
179         static const char *hex = "0123456789ABCDEF";
180 
181         for (auto it = this->uuid_.begin(); it != this->uuid_.end(); it++) {
182             tmp.push_back(hex[(((*it) >> 4) & 0xF)]); // 右移4位
183             tmp.push_back(hex[(*it) & 0xF]);
184         }
185         // ToString操作,8, 4, 12, 16,20 作为截取字符的开始位置或截取长度
186         ret = tmp.substr(0, 8) + "-" + tmp.substr(8, 4) + "-" + tmp.substr(12, 4) + "-" + tmp.substr(16, 4) + "-" +
187               tmp.substr(20);
188 
189         return ret;
190     }
191 
192     /**
193      * @brief Compares this UUID with the specified UUID.
194      *
195      * @param[in] val : UUID which this UUID is to be compared.
196      * @return Returns <b> <0 </b> if this UUID is less than compared UUID;
197      *         returns <b> =0 </b> if this UUID is equal to compared UUID;
198      *         returns <b> >0 </b> if this UUID is greater than compared UUID.
199      * @since 6
200      */
CompareTo(const UUID & val)201     int CompareTo(const UUID &val) const
202     {
203         UUID tmp = val;
204         return this->ToString().compare(tmp.ToString());
205     }
206 
207     /**
208      * @brief Compares this object to the specified object.
209      *
210      * @param[in] val : UUID which this UUID is to be compared.
211      * @return Returns <b>true</b> if this UUID is the same as compared UUID;
212      *         returns <b>false</b> if this UUID is not the same as compared UUID.
213      * @since 6
214      */
Equals(const UUID & val)215     bool Equals(const UUID &val) const
216     {
217         for (int i = 0; i < UUID128_BYTES_LEN; i++) {
218             if (this->uuid_[i] != val.uuid_[i]) {
219                 return false;
220             }
221         }
222         return true;
223     }
224 
225     /**
226      * @brief Returns the least significant 64 bits of this UUID's 128 bit value.
227      *
228      * @return Retruns the least significant 64 bits of this UUID's 128 bit value.
229      * @since 6
230      */
GetLeastSignificantBits()231     uint64_t GetLeastSignificantBits() const
232     {
233         uint64_t leastSigBits = 0;
234         for (int i = UUID128_BYTES_LEN / 2; i < UUID128_BYTES_LEN; i++) { // uuid长度/2作为i初始值
235             leastSigBits = (leastSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
236         }
237         return leastSigBits;
238     }
239 
240     /**
241      * @brief Returns the most significant 64 bits of this UUID's 128 bit value.
242      *
243      * @return Returns the most significant 64 bits of this UUID's 128 bit value.
244      * @since 6
245      */
GetMostSignificantBits()246     uint64_t GetMostSignificantBits() const
247     {
248         uint64_t mostSigBits = 0;
249         for (int i = 0 / 2; i < UUID128_BYTES_LEN / 2; i++) { // uuid长度/2作为i最大值
250             mostSigBits = (mostSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
251         }
252         return mostSigBits;
253     }
254 
255     /**
256      * @brief Constructor a new UUID from uint8_t array.
257      *
258      * @param[in] name : The 128 bits value for a UUID.
259      * @return Returns a specified UUID.
260      * @since 6
261      */
ConvertFrom128Bits(const std::array<uint8_t,UUID128_BYTES_LEN> & name)262     static UUID ConvertFrom128Bits(const std::array<uint8_t, UUID128_BYTES_LEN> &name)
263     {
264         UUID tmp;
265         for (int i = 0; i < UUID128_BYTES_LEN; i++) {
266             tmp.uuid_[i] = name[i];
267         }
268         return tmp;
269     }
270 
271     /**
272      * @brief Returns uint8_t array from UUID.
273      *
274      * @return returns a specified array.
275      * @since 6
276      */
ConvertTo128Bits()277     std::array<uint8_t, UUID128_BYTES_LEN> ConvertTo128Bits() const
278     {
279         std::array<uint8_t, UUID128_BYTES_LEN> uuid;
280 
281         for (int i = 0; i < UUID128_BYTES_LEN; i++) {
282             uuid[i] = uuid_[i];
283         }
284 
285         return uuid;
286     }
287 
288     /**
289      * @brief In order to use the object key in the map object, overload the operator <.
290      * @param[in] uuid : UUID object.
291      * @return @c bool : If the object uuid is the same, return true, otherwise return false.
292      */
293     bool operator<(const UUID &uuid) const
294     {
295         return !Equals(uuid);
296     }
297 
298 private:
299     std::array<uint8_t, UUID128_BYTES_LEN> uuid_ = {0x00};
300 };
301 
302 /**
303  * @brief This class provides framework ParcelUuid.
304  *
305  * @since 6
306  */
307 using ParcelUuid = UUID;
308 
309 } // namespace Bluetooth
310 } // namespace OHOS
311 
312 #endif  //DUMMY_UUID_H