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