Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
UUID.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef MBED_UUID_H__ 00018 #define MBED_UUID_H__ 00019 00020 #include <stdint.h> 00021 #include <string.h> 00022 #include <algorithm> 00023 00024 #include "blecommon.h" 00025 00026 /** 00027 * @file 00028 * @addtogroup ble 00029 * @{ 00030 * @addtogroup common 00031 * @{ 00032 */ 00033 00034 /** 00035 * Convert a character containing an hexadecimal digit into an unsigned integer. 00036 * 00037 * @param[in] c Hexadecimal digit in a character representation. 00038 * 00039 * @return The corresponding value as unsigned integer. 00040 */ 00041 static uint8_t char2int(char c) 00042 { 00043 if ((c >= '0') && (c <= '9')) { 00044 return c - '0'; 00045 } else if ((c >= 'a') && (c <= 'f')) { 00046 return c - 'a' + 10; 00047 } else if ((c >= 'A') && (c <= 'F')) { 00048 return c - 'A' + 10; 00049 } else { 00050 return 0; 00051 } 00052 } 00053 00054 /** 00055 * Representation of a Universally Unique Identifier (UUID). 00056 * 00057 * UUIDs are 128-bit wide numbers used to identify data type and elements in 00058 * many layers of the Bluetooth specification. 00059 * 00060 * Two representations of UUIDS exist: 00061 * - 16-bit UUIDs: Shortened representation of the 128 bit UUID 00062 * 0000xxxx-0000-1000-8000-00805F9B34FB where xxxx is the 16 bit UUID. 00063 * Values of those UUIDs are defined by the Bluetooth body. The short 00064 * representation saves bandwidth during protocol transactions. 00065 * - 128-bit UUIDs: Complete representation of a UUID. They are commonly 00066 * used for user defined UUID. 00067 * 00068 * This class acts as an adapter over these two kinds of UUIDs to allow 00069 * indiscriminate use of both forms in Mbed BLE APIs. 00070 * 00071 * @note 32-bit UUID representation is not supported currently. 00072 */ 00073 class UUID { 00074 public: 00075 00076 /** 00077 * Enumeration of the types of UUIDs. 00078 */ 00079 enum UUID_Type_t { 00080 /** 00081 * 16-bit wide UUID representation. 00082 */ 00083 UUID_TYPE_SHORT = 0, 00084 00085 /** 00086 * 128-bit wide UUID representation. 00087 */ 00088 UUID_TYPE_LONG = 1 00089 }; 00090 00091 /** 00092 * Enumeration of byte ordering. 00093 * 00094 * It is used to construct 128-byte UUIDs. 00095 */ 00096 typedef enum { 00097 /** 00098 * Most significant byte first (at the smallest address). 00099 */ 00100 MSB, 00101 00102 /** 00103 * Least significant byte first (at the smallest address). 00104 */ 00105 LSB 00106 } ByteOrder_t; 00107 00108 /** 00109 * Type for a 16-bit UUID. 00110 */ 00111 typedef uint16_t ShortUUIDBytes_t; 00112 00113 /** 00114 * Length in bytes of a long UUID. 00115 */ 00116 static const unsigned LENGTH_OF_LONG_UUID = 16; 00117 00118 /** 00119 * Type for a 128-bit UUID. 00120 */ 00121 typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; 00122 00123 /** 00124 * Maximum length for the string representation of a UUID excluding the null 00125 * terminator. 00126 * 00127 * The string is composed of two characters per byte plus four '-' 00128 * characters. 00129 */ 00130 static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4; 00131 00132 public: 00133 00134 /** 00135 * Construct a 128-bit UUID from a string. 00136 * 00137 * @param[in] stringUUID Human readable representation of the UUID following 00138 * the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. 00139 * 00140 * @note Upper and lower case are supported. 00141 * @note Hyphens are optional. The string must include at most four hyphens. 00142 * 00143 * @note Internally, the UUID is stored in the little endian order as a 00144 * 16-byte array. 00145 */ 00146 UUID(const char* stringUUID) : 00147 type(UUID_TYPE_LONG), 00148 baseUUID(), 00149 shortUUID(0) 00150 { 00151 bool nibble = false; 00152 uint8_t byte = 0; 00153 size_t baseIndex = 0; 00154 uint8_t tempUUID[LENGTH_OF_LONG_UUID]; 00155 00156 /* 00157 * Iterate through string; abort if NULL is encountered prematurely. 00158 * Ignore up to four hyphens. 00159 */ 00160 for (size_t index = 0; (index < MAX_UUID_STRING_LENGTH) && (baseIndex < LENGTH_OF_LONG_UUID); index++) { 00161 if (stringUUID[index] == '\0') { 00162 /* Error abort */ 00163 break; 00164 } else if (stringUUID[index] == '-') { 00165 /* Ignore hyphen */ 00166 continue; 00167 } else if (nibble) { 00168 /* Got second nibble */ 00169 byte |= char2int(stringUUID[index]); 00170 nibble = false; 00171 00172 /* Store copy */ 00173 tempUUID[baseIndex++] = byte; 00174 } else { 00175 /* Got first nibble */ 00176 byte = char2int(stringUUID[index]) << 4; 00177 nibble = true; 00178 } 00179 } 00180 00181 /* Populate internal variables if string was successfully parsed */ 00182 if (baseIndex == LENGTH_OF_LONG_UUID) { 00183 setupLong(tempUUID, UUID::MSB); 00184 } else { 00185 const uint8_t sig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 00186 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; 00187 setupLong(sig, UUID::MSB); 00188 } 00189 } 00190 00191 /** 00192 * Construct a new UUID from a 128-bit representation. 00193 * 00194 * @param[in] longUUID The 128-bit (16-byte) of the UUID value. 00195 * @param[in] order Bytes order of @p longUUID. 00196 */ 00197 UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { 00198 setupLong(longUUID, order); 00199 } 00200 00201 /** 00202 * Creates a new 16-bit UUID. 00203 * 00204 * The Bluetooth standard body defines 16-bit wide UUIDs. They are the 00205 * shortened version of the UUID 0000xxxx-0000-1000-8000-00805F9B34FB, where 00206 * xxxx is the value of the 16-bit UUID. 00207 * 00208 * @important 16-bit UUIDs are not used in user defined data type or 00209 * user defined element ID. 00210 * 00211 * @param[in] _shortUUID 16-bit part of the standard UUID. 00212 * The short UUID value. 00213 * 00214 * @note User defined UUIDs are commonly named vendor-specific UUIDs across 00215 * the Bluetooth literature. 00216 */ 00217 UUID(ShortUUIDBytes_t _shortUUID) : 00218 type(UUID_TYPE_SHORT), 00219 baseUUID(), 00220 shortUUID(_shortUUID) { 00221 } 00222 00223 /** 00224 * UUID copy constructor. 00225 * 00226 * @param[in] source The UUID to copy. 00227 */ 00228 UUID(const UUID &source) 00229 { 00230 type = source.type; 00231 shortUUID = source.shortUUID; 00232 memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID); 00233 } 00234 00235 /** 00236 * Default constructor. 00237 * 00238 * Construct an invalid UUID. 00239 * 00240 * @post shortOrLong() returns the value UUID_TYPE_SHORT. 00241 * @post getShortUUID() returns the value BLE_UUID_UNKNOWN. 00242 */ 00243 UUID(void) : 00244 type(UUID_TYPE_SHORT), 00245 shortUUID(BLE_UUID_UNKNOWN) { 00246 } 00247 00248 /** 00249 * Replace existing value with a 128-bit UUID. 00250 * 00251 * @param[in] longUUID New 16-byte wide UUID value. 00252 * @param[in] order Byte ordering of @p longUUID. 00253 */ 00254 void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) 00255 { 00256 type = UUID_TYPE_LONG; 00257 if (order == UUID::MSB) { 00258 /* 00259 * Switch endian. Input is big-endian, internal representation 00260 * is little endian. 00261 */ 00262 std::reverse_copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID); 00263 } else { 00264 std::copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID); 00265 } 00266 shortUUID = (uint16_t)((baseUUID[13] << 8) | (baseUUID[12])); 00267 } 00268 00269 public: 00270 /** 00271 * Return the internal type of the UUID. 00272 * 00273 * @return UUID_TYPE_SHORT if the UUID is 16-bit wide. 00274 * @return UUID_TYPE_LONG if the UUID is 128-bit wide. 00275 */ 00276 UUID_Type_t shortOrLong(void) const 00277 { 00278 return type; 00279 } 00280 00281 /** 00282 * Get a pointer to the UUID value based on the current UUID type. 00283 * 00284 * @return A pointer to an uint16_t object if the UUID is 16 bits long. 00285 * @return A pointer to an array of 16 bytes if the UUID is 128 bits long. 00286 */ 00287 const uint8_t *getBaseUUID(void) const 00288 { 00289 if (type == UUID_TYPE_SHORT) { 00290 return (const uint8_t*)&shortUUID; 00291 } else { 00292 return baseUUID; 00293 } 00294 } 00295 00296 /** 00297 * Get the uint16_t value of the UUID. 00298 * 00299 * @important This function is not used on long UUIDs. 00300 * 00301 * @return The value of the shortened UUID. 00302 */ 00303 ShortUUIDBytes_t getShortUUID(void) const 00304 { 00305 return shortUUID; 00306 } 00307 00308 /** 00309 * Get the length (in bytes) of the internal UUID representation. 00310 * 00311 * @return sizeof(ShortUUIDBytes_t) if the UUID type is UUID_TYPE_SHORT. 00312 * @return LENGTH_OF_LONG_UUID if the UUID type is UUID_TYPE_LONG. 00313 */ 00314 uint8_t getLen(void) const 00315 { 00316 return ((type == UUID_TYPE_SHORT) ? 00317 sizeof(ShortUUIDBytes_t) : 00318 LENGTH_OF_LONG_UUID); 00319 } 00320 00321 /** 00322 * Equal to operator between UUIDs. 00323 * 00324 * @param[in] other The UUID to compare to this. 00325 * 00326 * @return true if both UUIDs are equal and false otherwise. 00327 */ 00328 bool operator== (const UUID &other) const 00329 { 00330 if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) && 00331 (this->shortUUID == other.shortUUID)) { 00332 return true; 00333 } 00334 00335 if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) && 00336 (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) { 00337 return true; 00338 } 00339 00340 return false; 00341 } 00342 00343 /** 00344 * Not equal to operator. 00345 * 00346 * @param[in] other The UUID compared to this. 00347 * 00348 * @return true if both UUIDs are not equal and false otherwise. 00349 */ 00350 bool operator!= (const UUID &other) const 00351 { 00352 return !(*this == other); 00353 } 00354 00355 private: 00356 /** 00357 * Representation type of the UUID. 00358 */ 00359 UUID_Type_t type; 00360 00361 /** 00362 * Container of UUID value if the UUID type is equal to UUID_TYPE_LONG. 00363 */ 00364 LongUUIDBytes_t baseUUID; 00365 00366 /** 00367 * Container of UUID value if the UUID type is equal to UUID_TYPE_SHORT. 00368 */ 00369 ShortUUIDBytes_t shortUUID; 00370 }; 00371 00372 /** 00373 * @} 00374 * @} 00375 */ 00376 00377 #endif // ifndef MBED_UUID_H__
Generated on Thu Jul 14 2022 14:36:24 by
