High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
Diff: ble/UUID.h
- Revision:
- 1134:d540a48f650d
- Parent:
- 1131:692ddf04fc42
- Child:
- 1170:e8f2db0e8e11
--- a/ble/UUID.h Wed Apr 06 19:13:50 2016 +0100 +++ b/ble/UUID.h Wed Apr 06 19:13:52 2016 +0100 @@ -19,9 +19,27 @@ #include <stdint.h> #include <string.h> +#include <algorithm> #include "blecommon.h" +/** + * A trivial converter for single hexadecimal character to unsigned-int. + * @param c hexadecimal character. + * @return the corresponding value as unsigned int. + */ +static uint8_t char2int(char c) { + if ((c >= '0') && (c <= '9')) { + return c - '0'; + } else if ((c >= 'a') && (c <= 'f')) { + return c - 'a' + 10; + } else if ((c >= 'A') && (c <= 'F')) { + return c - 'A' + 10; + } else { + return 0; + } +} + class UUID { public: enum UUID_Type_t { @@ -29,12 +47,75 @@ UUID_TYPE_LONG = 1 // Full 128-bit UUID. }; + /** + * An enumeration to specify byte ordering of the long version of the UUID. + */ + typedef enum { + MSB, /*!< Most-significant byte first (at the smallest address) */ + LSB /*!< least-significant byte first (at the smallest address) */ + } ByteOrder_t; + typedef uint16_t ShortUUIDBytes_t; static const unsigned LENGTH_OF_LONG_UUID = 16; typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; + static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4; + public: + + /** + * Creates a new 128-bit UUID. + * + * @note The UUID is a unique 128-bit (16 byte) ID used to identify + * different service or characteristics on the BLE device. + * + * @param stringUUID + * The 128-bit (16-byte) UUID as a human readable const-string. + * Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + * Upper and lower case supported. Hyphens are optional, but only + * upto four of them. The UUID is stored internally as a 16 byte + * array, LSB (little endian), which is opposite from the string. + */ + UUID(const char* stringUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { + bool nibble = false; + uint8_t byte = 0; + size_t baseIndex = 0; + uint8_t tempUUID[LENGTH_OF_LONG_UUID]; + + // Iterate through string, abort if NULL is encountered prematurely. + // Ignore upto four hyphens. + for (size_t index = 0; (index < MAX_UUID_STRING_LENGTH) && (baseIndex < LENGTH_OF_LONG_UUID); index++) { + if (stringUUID[index] == '\0') { + // error abort + break; + } else if (stringUUID[index] == '-') { + // ignore hyphen + continue; + } else if (nibble) { + // got second nibble + byte |= char2int(stringUUID[index]); + nibble = false; + + // store copy + tempUUID[baseIndex++] = byte; + } else { + // got first nibble + byte = char2int(stringUUID[index]) << 4; + nibble = true; + } + } + + // populate internal variables if string was successfully parsed + if (baseIndex == LENGTH_OF_LONG_UUID) { + setupLong(tempUUID, UUID::MSB); + } else { + const uint8_t sig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; + setupLong(sig, UUID::MSB); + } + } + /** * Creates a new 128-bit UUID. * @@ -42,10 +123,12 @@ * different service or characteristics on the BLE device. * * @param longUUID - * The 128-bit (16-byte) UUID value, MSB first (big-endian). + * The 128-bit (16-byte) UUID value. + * @param order + * The bit order of the UUID, MSB by default. */ - UUID(const LongUUIDBytes_t longUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { - setupLong(longUUID); + UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { + setupLong(longUUID, order); } /** @@ -91,10 +174,15 @@ /** * Fill in a 128-bit UUID; this is useful when the UUID isn't known at the time of the object construction. */ - void setupLong(const LongUUIDBytes_t longUUID) { + void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) { type = UUID_TYPE_LONG; - memcpy(baseUUID, longUUID, LENGTH_OF_LONG_UUID); - shortUUID = (uint16_t)((longUUID[2] << 8) | (longUUID[3])); + if (order == UUID::MSB) { + // Switch endian. Input is big-endian, internal representation is little endian. + std::reverse_copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID); + } else { + std::copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID); + } + shortUUID = (uint16_t)((baseUUID[13] << 8) | (baseUUID[12])); } public: @@ -132,12 +220,8 @@ private: UUID_Type_t type; // UUID_TYPE_SHORT or UUID_TYPE_LONG - LongUUIDBytes_t baseUUID; /* The base of the long UUID (if - * used). Note: bytes 12 and 13 (counting from LSB) - * are zeroed out to allow comparison with other long - * UUIDs, which differ only in the 16-bit relative - * part.*/ - ShortUUIDBytes_t shortUUID; // 16 bit UUID (byte 2-3 using with base). + LongUUIDBytes_t baseUUID; // The long UUID + ShortUUIDBytes_t shortUUID; // 16 bit UUID }; #endif // ifndef __UUID_H__ \ No newline at end of file