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