Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UUID.h Source File

UUID.h

Go to the documentation of this file.
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__