Rtos API example

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 <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__