Mistake on this page?
Report an issue in GitHub or email us
common/UUID.h
Go to the documentation of this file.
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2020 ARM Limited
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #ifndef MBED_UUID_H__
20 #define MBED_UUID_H__
21 
22 #include <cstddef>
23 #include <cstdint>
24 #include <cstring>
25 #include <algorithm>
26 
27 #include "ble/common/blecommon.h"
28 
29 /**
30  * @file
31  * @addtogroup ble
32  * @{
33  * @addtogroup common
34  * @{
35  */
36 
37 /**
38  * Convert a character containing an hexadecimal digit into an unsigned integer.
39  *
40  * @param[in] c Hexadecimal digit in a character representation.
41  *
42  * @return The corresponding value as unsigned integer.
43  */
44 static uint8_t char2int(char c)
45 {
46  if ((c >= '0') && (c <= '9')) {
47  return c - '0';
48  } else if ((c >= 'a') && (c <= 'f')) {
49  return c - 'a' + 10;
50  } else if ((c >= 'A') && (c <= 'F')) {
51  return c - 'A' + 10;
52  } else {
53  return 0;
54  }
55 }
56 
57 /**
58  * Representation of a Universally Unique Identifier (UUID).
59  *
60  * UUIDs are 128-bit wide numbers used to identify data type and elements in
61  * many layers of the Bluetooth specification.
62  *
63  * Two representations of UUIDS exist:
64  * - 16-bit UUIDs: Shortened representation of the 128 bit UUID
65  * 0000xxxx-0000-1000-8000-00805F9B34FB where xxxx is the 16 bit UUID.
66  * Values of those UUIDs are defined by the Bluetooth body. The short
67  * representation saves bandwidth during protocol transactions.
68  * - 128-bit UUIDs: Complete representation of a UUID. They are commonly
69  * used for user defined UUID.
70  *
71  * This class acts as an adapter over these two kinds of UUIDs to allow
72  * indiscriminate use of both forms in Mbed BLE APIs.
73  *
74  * @note 32-bit UUID representation is not supported currently.
75  */
76 class UUID {
77 public:
78 
79  /**
80  * Enumeration of the types of UUIDs.
81  */
82  enum UUID_Type_t {
83  /**
84  * 16-bit wide UUID representation.
85  */
87 
88  /**
89  * 128-bit wide UUID representation.
90  */
92  };
93 
94  /**
95  * Enumeration of byte ordering.
96  *
97  * It is used to construct 128-byte UUIDs.
98  */
99  typedef enum {
100  /**
101  * Most significant byte first (at the smallest address).
102  */
104 
105  /**
106  * Least significant byte first (at the smallest address).
107  */
109  } ByteOrder_t;
110 
111  /**
112  * Type for a 16-bit UUID.
113  */
114  typedef uint16_t ShortUUIDBytes_t;
115 
116  /**
117  * Length in bytes of a long UUID.
118  */
119  static const unsigned LENGTH_OF_LONG_UUID = 16;
120 
121  /**
122  * Type for a 128-bit UUID.
123  */
125 
126  /**
127  * Maximum length for the string representation of a UUID excluding the null
128  * terminator.
129  *
130  * The string is composed of two characters per byte plus four '-'
131  * characters.
132  */
133  static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4;
134 
135 public:
136 
137  /**
138  * Construct a 128-bit UUID from a string.
139  *
140  * @param[in] stringUUID Human readable representation of the UUID following
141  * the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
142  *
143  * @note Upper and lower case are supported.
144  * @note Hyphens are optional. The string must include at most four hyphens.
145  *
146  * @note Internally, the UUID is stored in the little endian order as a
147  * 16-byte array.
148  */
149  UUID(const char* stringUUID) :
150  type(UUID_TYPE_LONG),
151  baseUUID(),
152  shortUUID(0)
153  {
154  bool nibble = false;
155  uint8_t byte = 0;
156  size_t baseIndex = 0;
157  uint8_t tempUUID[LENGTH_OF_LONG_UUID];
158 
159  /*
160  * Iterate through string; abort if NULL is encountered prematurely.
161  * Ignore up to four hyphens.
162  */
163  for (size_t index = 0; (index < MAX_UUID_STRING_LENGTH) && (baseIndex < LENGTH_OF_LONG_UUID); index++) {
164  if (stringUUID[index] == '\0') {
165  /* Error abort */
166  break;
167  } else if (stringUUID[index] == '-') {
168  /* Ignore hyphen */
169  continue;
170  } else if (nibble) {
171  /* Got second nibble */
172  byte |= char2int(stringUUID[index]);
173  nibble = false;
174 
175  /* Store copy */
176  tempUUID[baseIndex++] = byte;
177  } else {
178  /* Got first nibble */
179  byte = char2int(stringUUID[index]) << 4;
180  nibble = true;
181  }
182  }
183 
184  /* Populate internal variables if string was successfully parsed */
185  if (baseIndex == LENGTH_OF_LONG_UUID) {
186  setupLong(tempUUID, UUID::MSB);
187  } else {
188  const uint8_t sig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
189  0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
190  setupLong(sig, UUID::MSB);
191  }
192  }
193 
194  /**
195  * Construct a new UUID from a 128-bit representation.
196  *
197  * @param[in] longUUID The 128-bit (16-byte) of the UUID value.
198  * @param[in] order Bytes order of @p longUUID.
199  */
200  UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
201  setupLong(longUUID, order);
202  }
203 
204  /**
205  * Creates a new 16-bit UUID.
206  *
207  * The Bluetooth standard body defines 16-bit wide UUIDs. They are the
208  * shortened version of the UUID 0000xxxx-0000-1000-8000-00805F9B34FB, where
209  * xxxx is the value of the 16-bit UUID.
210  *
211  * @attention 16-bit UUIDs are not used in user defined data type or
212  * user defined element ID.
213  *
214  * @param[in] _shortUUID 16-bit part of the standard UUID.
215  * The short UUID value.
216  *
217  * @note User defined UUIDs are commonly named vendor-specific UUIDs across
218  * the Bluetooth literature.
219  */
220  UUID(ShortUUIDBytes_t _shortUUID) :
221  type(UUID_TYPE_SHORT),
222  baseUUID(),
223  shortUUID(_shortUUID) {
224  }
225 
226  /**
227  * UUID copy constructor.
228  *
229  * @param[in] source The UUID to copy.
230  */
231  UUID(const UUID &source)
232  {
233  type = source.type;
234  shortUUID = source.shortUUID;
235  memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID);
236  }
237 
238  /**
239  * UUID copy assignment.
240  *
241  * @param[in] source The UUID to copy.
242  */
243  UUID& operator=(const UUID &source) = default;
244 
245  /**
246  * Default constructor.
247  *
248  * Construct an invalid UUID.
249  *
250  * @post shortOrLong() returns the value UUID_TYPE_SHORT.
251  * @post getShortUUID() returns the value BLE_UUID_UNKNOWN.
252  */
253  UUID() :
254  type(UUID_TYPE_SHORT),
255  shortUUID(BLE_UUID_UNKNOWN) {
256  }
257 
258  /**
259  * Replace existing value with a 128-bit UUID.
260  *
261  * @param[in] longUUID New 16-byte wide UUID value.
262  * @param[in] order Byte ordering of @p longUUID.
263  */
264  void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB)
265  {
266  type = UUID_TYPE_LONG;
267  if (order == UUID::MSB) {
268  /*
269  * Switch endian. Input is big-endian, internal representation
270  * is little endian.
271  */
272  std::reverse_copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID);
273  } else {
274  std::copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID);
275  }
276  shortUUID = (uint16_t)((baseUUID[13] << 8) | (baseUUID[12]));
277  }
278 
279 public:
280  /**
281  * Return the internal type of the UUID.
282  *
283  * @return UUID_TYPE_SHORT if the UUID is 16-bit wide.
284  * @return UUID_TYPE_LONG if the UUID is 128-bit wide.
285  */
287  {
288  return type;
289  }
290 
291  /**
292  * Get a pointer to the UUID value based on the current UUID type.
293  *
294  * @return A pointer to an uint16_t object if the UUID is 16 bits long.
295  * @return A pointer to an array of 16 bytes if the UUID is 128 bits long.
296  */
297  const uint8_t *getBaseUUID() const
298  {
299  if (type == UUID_TYPE_SHORT) {
300  return (const uint8_t*)&shortUUID;
301  } else {
302  return baseUUID;
303  }
304  }
305 
306  /**
307  * Get the uint16_t value of the UUID.
308  *
309  * @attention This function is not used on long UUIDs.
310  *
311  * @return The value of the shortened UUID.
312  */
313  ShortUUIDBytes_t getShortUUID() const
314  {
315  return shortUUID;
316  }
317 
318  /**
319  * Get the length (in bytes) of the internal UUID representation.
320  *
321  * @return sizeof(ShortUUIDBytes_t) if the UUID type is UUID_TYPE_SHORT.
322  * @return LENGTH_OF_LONG_UUID if the UUID type is UUID_TYPE_LONG.
323  */
324  uint8_t getLen() const
325  {
326  return ((type == UUID_TYPE_SHORT) ?
327  sizeof(ShortUUIDBytes_t) :
328  LENGTH_OF_LONG_UUID);
329  }
330 
331  /**
332  * Equal to operator between UUIDs.
333  *
334  * @param[in] other The UUID to compare to this.
335  *
336  * @return true if both UUIDs are equal and false otherwise.
337  */
338  bool operator== (const UUID &other) const
339  {
340  if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) &&
341  (this->shortUUID == other.shortUUID)) {
342  return true;
343  }
344 
345  if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) &&
346  (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) {
347  return true;
348  }
349 
350  return false;
351  }
352 
353  /**
354  * Not equal to operator.
355  *
356  * @param[in] other The UUID compared to this.
357  *
358  * @return true if both UUIDs are not equal and false otherwise.
359  */
360  bool operator!= (const UUID &other) const
361  {
362  return !(*this == other);
363  }
364 
365 private:
366  /**
367  * Representation type of the UUID.
368  */
369  UUID_Type_t type;
370 
371  /**
372  * Container of UUID value if the UUID type is equal to UUID_TYPE_LONG.
373  */
374  LongUUIDBytes_t baseUUID;
375 
376  /**
377  * Container of UUID value if the UUID type is equal to UUID_TYPE_SHORT.
378  */
379  ShortUUIDBytes_t shortUUID;
380 };
381 
382 /**
383  * @}
384  * @}
385  */
386 
387 #endif // ifndef MBED_UUID_H__
uint8_t getLen() const
Get the length (in bytes) of the internal UUID representation.
Definition: common/UUID.h:324
ByteOrder_t
Enumeration of byte ordering.
Definition: common/UUID.h:99
const uint8_t * getBaseUUID() const
Get a pointer to the UUID value based on the current UUID type.
Definition: common/UUID.h:297
UUID(ShortUUIDBytes_t _shortUUID)
Creates a new 16-bit UUID.
Definition: common/UUID.h:220
static const unsigned LENGTH_OF_LONG_UUID
Length in bytes of a long UUID.
Definition: common/UUID.h:119
Least significant byte first (at the smallest address).
Definition: common/UUID.h:108
UUID(const UUID &source)
UUID copy constructor.
Definition: common/UUID.h:231
UUID(const char *stringUUID)
Construct a 128-bit UUID from a string.
Definition: common/UUID.h:149
UUID_Type_t
Enumeration of the types of UUIDs.
Definition: common/UUID.h:82
Most significant byte first (at the smallest address).
Definition: common/UUID.h:103
Reserved UUID.
static const unsigned MAX_UUID_STRING_LENGTH
Maximum length for the string representation of a UUID excluding the null terminator.
Definition: common/UUID.h:133
uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]
Type for a 128-bit UUID.
Definition: common/UUID.h:124
bool operator==(const UUID &other) const
Equal to operator between UUIDs.
Definition: common/UUID.h:338
ShortUUIDBytes_t getShortUUID() const
Get the uint16_t value of the UUID.
Definition: common/UUID.h:313
Representation of a Universally Unique Identifier (UUID).
Definition: common/UUID.h:76
UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order=UUID::MSB)
Construct a new UUID from a 128-bit representation.
Definition: common/UUID.h:200
uint16_t ShortUUIDBytes_t
Type for a 16-bit UUID.
Definition: common/UUID.h:114
UUID()
Default constructor.
Definition: common/UUID.h:253
static uint8_t char2int(char c)
Convert a character containing an hexadecimal digit into an unsigned integer.
Definition: common/UUID.h:44
void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order=UUID::MSB)
Replace existing value with a 128-bit UUID.
Definition: common/UUID.h:264
UUID & operator=(const UUID &source)=default
UUID copy assignment.
bool operator!=(const UUID &other) const
Not equal to operator.
Definition: common/UUID.h:360
16-bit wide UUID representation.
Definition: common/UUID.h:86
UUID_Type_t shortOrLong() const
Return the internal type of the UUID.
Definition: common/UUID.h:286
128-bit wide UUID representation.
Definition: common/UUID.h:91
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.