Marco Zecchini
/
Example_RTOS
Rtos API example
Diff: mbed-os/features/FEATURE_BLE/ble/UUID.h
- Revision:
- 0:9fca2b23d0ba
diff -r 000000000000 -r 9fca2b23d0ba mbed-os/features/FEATURE_BLE/ble/UUID.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os/features/FEATURE_BLE/ble/UUID.h Sat Feb 23 12:13:36 2019 +0000 @@ -0,0 +1,377 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_UUID_H__ +#define MBED_UUID_H__ + +#include <stdint.h> +#include <string.h> +#include <algorithm> + +#include "blecommon.h" + +/** + * @file + * @addtogroup ble + * @{ + * @addtogroup common + * @{ + */ + +/** + * Convert a character containing an hexadecimal digit into an unsigned integer. + * + * @param[in] c Hexadecimal digit in a character representation. + * + * @return The corresponding value as unsigned integer. + */ +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; + } +} + +/** + * Representation of a Universally Unique Identifier (UUID). + * + * UUIDs are 128-bit wide numbers used to identify data type and elements in + * many layers of the Bluetooth specification. + * + * Two representations of UUIDS exist: + * - 16-bit UUIDs: Shortened representation of the 128 bit UUID + * 0000xxxx-0000-1000-8000-00805F9B34FB where xxxx is the 16 bit UUID. + * Values of those UUIDs are defined by the Bluetooth body. The short + * representation saves bandwidth during protocol transactions. + * - 128-bit UUIDs: Complete representation of a UUID. They are commonly + * used for user defined UUID. + * + * This class acts as an adapter over these two kinds of UUIDs to allow + * indiscriminate use of both forms in Mbed BLE APIs. + * + * @note 32-bit UUID representation is not supported currently. + */ +class UUID { +public: + + /** + * Enumeration of the types of UUIDs. + */ + enum UUID_Type_t { + /** + * 16-bit wide UUID representation. + */ + UUID_TYPE_SHORT = 0, + + /** + * 128-bit wide UUID representation. + */ + UUID_TYPE_LONG = 1 + }; + + /** + * Enumeration of byte ordering. + * + * It is used to construct 128-byte UUIDs. + */ + typedef enum { + /** + * Most significant byte first (at the smallest address). + */ + MSB, + + /** + * Least significant byte first (at the smallest address). + */ + LSB + } ByteOrder_t; + + /** + * Type for a 16-bit UUID. + */ + typedef uint16_t ShortUUIDBytes_t; + + /** + * Length in bytes of a long UUID. + */ + static const unsigned LENGTH_OF_LONG_UUID = 16; + + /** + * Type for a 128-bit UUID. + */ + typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; + + /** + * Maximum length for the string representation of a UUID excluding the null + * terminator. + * + * The string is composed of two characters per byte plus four '-' + * characters. + */ + static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4; + +public: + + /** + * Construct a 128-bit UUID from a string. + * + * @param[in] stringUUID Human readable representation of the UUID following + * the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. + * + * @note Upper and lower case are supported. + * @note Hyphens are optional. The string must include at most four hyphens. + * + * @note Internally, the UUID is stored in the little endian order as a + * 16-byte array. + */ + 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 up to 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); + } + } + + /** + * Construct a new UUID from a 128-bit representation. + * + * @param[in] longUUID The 128-bit (16-byte) of the UUID value. + * @param[in] order Bytes order of @p longUUID. + */ + UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { + setupLong(longUUID, order); + } + + /** + * Creates a new 16-bit UUID. + * + * The Bluetooth standard body defines 16-bit wide UUIDs. They are the + * shortened version of the UUID 0000xxxx-0000-1000-8000-00805F9B34FB, where + * xxxx is the value of the 16-bit UUID. + * + * @important 16-bit UUIDs are not used in user defined data type or + * user defined element ID. + * + * @param[in] _shortUUID 16-bit part of the standard UUID. + * The short UUID value. + * + * @note User defined UUIDs are commonly named vendor-specific UUIDs across + * the Bluetooth literature. + */ + UUID(ShortUUIDBytes_t _shortUUID) : + type(UUID_TYPE_SHORT), + baseUUID(), + shortUUID(_shortUUID) { + } + + /** + * UUID copy constructor. + * + * @param[in] source The UUID to copy. + */ + UUID(const UUID &source) + { + type = source.type; + shortUUID = source.shortUUID; + memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID); + } + + /** + * Default constructor. + * + * Construct an invalid UUID. + * + * @post shortOrLong() returns the value UUID_TYPE_SHORT. + * @post getShortUUID() returns the value BLE_UUID_UNKNOWN. + */ + UUID(void) : + type(UUID_TYPE_SHORT), + shortUUID(BLE_UUID_UNKNOWN) { + } + + /** + * Replace existing value with a 128-bit UUID. + * + * @param[in] longUUID New 16-byte wide UUID value. + * @param[in] order Byte ordering of @p longUUID. + */ + void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) + { + type = UUID_TYPE_LONG; + 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: + /** + * Return the internal type of the UUID. + * + * @return UUID_TYPE_SHORT if the UUID is 16-bit wide. + * @return UUID_TYPE_LONG if the UUID is 128-bit wide. + */ + UUID_Type_t shortOrLong(void) const + { + return type; + } + + /** + * Get a pointer to the UUID value based on the current UUID type. + * + * @return A pointer to an uint16_t object if the UUID is 16 bits long. + * @return A pointer to an array of 16 bytes if the UUID is 128 bits long. + */ + const uint8_t *getBaseUUID(void) const + { + if (type == UUID_TYPE_SHORT) { + return (const uint8_t*)&shortUUID; + } else { + return baseUUID; + } + } + + /** + * Get the uint16_t value of the UUID. + * + * @important This function is not used on long UUIDs. + * + * @return The value of the shortened UUID. + */ + ShortUUIDBytes_t getShortUUID(void) const + { + return shortUUID; + } + + /** + * Get the length (in bytes) of the internal UUID representation. + * + * @return sizeof(ShortUUIDBytes_t) if the UUID type is UUID_TYPE_SHORT. + * @return LENGTH_OF_LONG_UUID if the UUID type is UUID_TYPE_LONG. + */ + uint8_t getLen(void) const + { + return ((type == UUID_TYPE_SHORT) ? + sizeof(ShortUUIDBytes_t) : + LENGTH_OF_LONG_UUID); + } + + /** + * Equal to operator between UUIDs. + * + * @param[in] other The UUID to compare to this. + * + * @return true if both UUIDs are equal and false otherwise. + */ + bool operator== (const UUID &other) const + { + if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) && + (this->shortUUID == other.shortUUID)) { + return true; + } + + if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) && + (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) { + return true; + } + + return false; + } + + /** + * Not equal to operator. + * + * @param[in] other The UUID compared to this. + * + * @return true if both UUIDs are not equal and false otherwise. + */ + bool operator!= (const UUID &other) const + { + return !(*this == other); + } + +private: + /** + * Representation type of the UUID. + */ + UUID_Type_t type; + + /** + * Container of UUID value if the UUID type is equal to UUID_TYPE_LONG. + */ + LongUUIDBytes_t baseUUID; + + /** + * Container of UUID value if the UUID type is equal to UUID_TYPE_SHORT. + */ + ShortUUIDBytes_t shortUUID; +}; + +/** + * @} + * @} + */ + +#endif // ifndef MBED_UUID_H__