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