add "LE Device Address" 0x1B to advertising data types

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Mon Jan 11 08:51:49 2016 +0000
Revision:
1088:709ebced28ab
Parent:
1056:ce2fb3d09929
Synchronized with git rev 0781293b
Author: Andres Amaya Garcia
Add onShutdown to register callbacks

Add an onShutdown() function to Gap, GattClient, GattServer and
SecurityManager. The callbacks are added to a private callback chain in each of
the instances. The callbacks will be executed inside each object's reset()
function BEFORE the state of the instance is cleared. The developers of the
platform-specific implementation must call the parent class' reset() function
for the callbacks to be executed.

Finally, an onShutdown() function that returns the shutdown callchain is added
to allow detaching callbacks.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 710:b2e1a2660ec2 1 /* mbed Microcontroller Library
rgrover1 710:b2e1a2660ec2 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 710:b2e1a2660ec2 3 *
rgrover1 710:b2e1a2660ec2 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 710:b2e1a2660ec2 5 * you may not use this file except in compliance with the License.
rgrover1 710:b2e1a2660ec2 6 * You may obtain a copy of the License at
rgrover1 710:b2e1a2660ec2 7 *
rgrover1 710:b2e1a2660ec2 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 710:b2e1a2660ec2 9 *
rgrover1 710:b2e1a2660ec2 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 710:b2e1a2660ec2 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 710:b2e1a2660ec2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 710:b2e1a2660ec2 13 * See the License for the specific language governing permissions and
rgrover1 710:b2e1a2660ec2 14 * limitations under the License.
rgrover1 710:b2e1a2660ec2 15 */
rgrover1 710:b2e1a2660ec2 16
rgrover1 710:b2e1a2660ec2 17 #ifndef __UUID_H__
rgrover1 710:b2e1a2660ec2 18 #define __UUID_H__
rgrover1 710:b2e1a2660ec2 19
rgrover1 710:b2e1a2660ec2 20 #include <stdint.h>
rgrover1 710:b2e1a2660ec2 21 #include <string.h>
vcoubard 1056:ce2fb3d09929 22 #include <algorithm>
rgrover1 710:b2e1a2660ec2 23
rgrover1 710:b2e1a2660ec2 24 #include "blecommon.h"
rgrover1 710:b2e1a2660ec2 25
vcoubard 1056:ce2fb3d09929 26 /**
vcoubard 1056:ce2fb3d09929 27 * A trivial converter for single hexadecimal character to unsigned-int.
vcoubard 1056:ce2fb3d09929 28 * @param c hexadecimal character.
vcoubard 1056:ce2fb3d09929 29 * @return the corresponding value as unsigned int.
vcoubard 1056:ce2fb3d09929 30 */
vcoubard 1056:ce2fb3d09929 31 static uint8_t char2int(char c) {
vcoubard 1056:ce2fb3d09929 32 if ((c >= '0') && (c <= '9')) {
vcoubard 1056:ce2fb3d09929 33 return c - '0';
vcoubard 1056:ce2fb3d09929 34 } else if ((c >= 'a') && (c <= 'f')) {
vcoubard 1056:ce2fb3d09929 35 return c - 'a' + 10;
vcoubard 1056:ce2fb3d09929 36 } else if ((c >= 'A') && (c <= 'F')) {
vcoubard 1056:ce2fb3d09929 37 return c - 'A' + 10;
vcoubard 1056:ce2fb3d09929 38 } else {
vcoubard 1056:ce2fb3d09929 39 return 0;
vcoubard 1056:ce2fb3d09929 40 }
vcoubard 1056:ce2fb3d09929 41 }
vcoubard 1056:ce2fb3d09929 42
rgrover1 710:b2e1a2660ec2 43 class UUID {
rgrover1 710:b2e1a2660ec2 44 public:
rgrover1 710:b2e1a2660ec2 45 enum UUID_Type_t {
vcoubard 1048:efb29faf12fc 46 UUID_TYPE_SHORT = 0, // Short BLE UUID.
vcoubard 1048:efb29faf12fc 47 UUID_TYPE_LONG = 1 // Full 128-bit UUID.
rgrover1 710:b2e1a2660ec2 48 };
rgrover1 710:b2e1a2660ec2 49
vcoubard 1056:ce2fb3d09929 50 /**
vcoubard 1056:ce2fb3d09929 51 * An enumeration to specify byte ordering of the long version of the UUID.
vcoubard 1056:ce2fb3d09929 52 */
vcoubard 1056:ce2fb3d09929 53 typedef enum {
vcoubard 1056:ce2fb3d09929 54 MSB, /*!< Most-significant byte first (at the smallest address) */
vcoubard 1056:ce2fb3d09929 55 LSB /*!< least-significant byte first (at the smallest address) */
vcoubard 1056:ce2fb3d09929 56 } ByteOrder_t;
vcoubard 1056:ce2fb3d09929 57
rgrover1 710:b2e1a2660ec2 58 typedef uint16_t ShortUUIDBytes_t;
rgrover1 710:b2e1a2660ec2 59
rgrover1 710:b2e1a2660ec2 60 static const unsigned LENGTH_OF_LONG_UUID = 16;
rgrover1 710:b2e1a2660ec2 61 typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
rgrover1 710:b2e1a2660ec2 62
vcoubard 1056:ce2fb3d09929 63 static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4;
vcoubard 1056:ce2fb3d09929 64
rgrover1 710:b2e1a2660ec2 65 public:
vcoubard 1056:ce2fb3d09929 66
vcoubard 1056:ce2fb3d09929 67 /**
vcoubard 1056:ce2fb3d09929 68 * Creates a new 128-bit UUID.
vcoubard 1056:ce2fb3d09929 69 *
vcoubard 1056:ce2fb3d09929 70 * @note The UUID is a unique 128-bit (16 byte) ID used to identify
vcoubard 1056:ce2fb3d09929 71 * different service or characteristics on the BLE device.
vcoubard 1056:ce2fb3d09929 72 *
vcoubard 1056:ce2fb3d09929 73 * @param stringUUID
vcoubard 1056:ce2fb3d09929 74 * The 128-bit (16-byte) UUID as a human readable const-string.
vcoubard 1056:ce2fb3d09929 75 * Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
vcoubard 1056:ce2fb3d09929 76 * Upper and lower case supported. Hyphens are optional, but only
vcoubard 1056:ce2fb3d09929 77 * upto four of them. The UUID is stored internally as a 16 byte
vcoubard 1056:ce2fb3d09929 78 * array, LSB (little endian), which is opposite from the string.
vcoubard 1056:ce2fb3d09929 79 */
vcoubard 1056:ce2fb3d09929 80 UUID(const char* stringUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
vcoubard 1056:ce2fb3d09929 81 bool nibble = false;
vcoubard 1056:ce2fb3d09929 82 uint8_t byte = 0;
vcoubard 1056:ce2fb3d09929 83 size_t baseIndex = 0;
vcoubard 1056:ce2fb3d09929 84 uint8_t tempUUID[LENGTH_OF_LONG_UUID];
vcoubard 1056:ce2fb3d09929 85
vcoubard 1056:ce2fb3d09929 86 // Iterate through string, abort if NULL is encountered prematurely.
vcoubard 1056:ce2fb3d09929 87 // Ignore upto four hyphens.
vcoubard 1056:ce2fb3d09929 88 for (size_t index = 0; (index < MAX_UUID_STRING_LENGTH) && (baseIndex < LENGTH_OF_LONG_UUID); index++) {
vcoubard 1056:ce2fb3d09929 89 if (stringUUID[index] == '\0') {
vcoubard 1056:ce2fb3d09929 90 // error abort
vcoubard 1056:ce2fb3d09929 91 break;
vcoubard 1056:ce2fb3d09929 92 } else if (stringUUID[index] == '-') {
vcoubard 1056:ce2fb3d09929 93 // ignore hyphen
vcoubard 1056:ce2fb3d09929 94 continue;
vcoubard 1056:ce2fb3d09929 95 } else if (nibble) {
vcoubard 1056:ce2fb3d09929 96 // got second nibble
vcoubard 1056:ce2fb3d09929 97 byte |= char2int(stringUUID[index]);
vcoubard 1056:ce2fb3d09929 98 nibble = false;
vcoubard 1056:ce2fb3d09929 99
vcoubard 1056:ce2fb3d09929 100 // store copy
vcoubard 1056:ce2fb3d09929 101 tempUUID[baseIndex++] = byte;
vcoubard 1056:ce2fb3d09929 102 } else {
vcoubard 1056:ce2fb3d09929 103 // got first nibble
vcoubard 1056:ce2fb3d09929 104 byte = char2int(stringUUID[index]) << 4;
vcoubard 1056:ce2fb3d09929 105 nibble = true;
vcoubard 1056:ce2fb3d09929 106 }
vcoubard 1056:ce2fb3d09929 107 }
vcoubard 1056:ce2fb3d09929 108
vcoubard 1056:ce2fb3d09929 109 // populate internal variables if string was successfully parsed
vcoubard 1056:ce2fb3d09929 110 if (baseIndex == LENGTH_OF_LONG_UUID) {
vcoubard 1056:ce2fb3d09929 111 setupLong(tempUUID, UUID::MSB);
vcoubard 1056:ce2fb3d09929 112 } else {
vcoubard 1056:ce2fb3d09929 113 const uint8_t sig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
vcoubard 1056:ce2fb3d09929 114 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
vcoubard 1056:ce2fb3d09929 115 setupLong(sig, UUID::MSB);
vcoubard 1056:ce2fb3d09929 116 }
vcoubard 1056:ce2fb3d09929 117 }
vcoubard 1056:ce2fb3d09929 118
rgrover1 1035:d8ba3cb5a39a 119 /**
vcoubard 1048:efb29faf12fc 120 * Creates a new 128-bit UUID.
rgrover1 710:b2e1a2660ec2 121 *
rgrover1 710:b2e1a2660ec2 122 * @note The UUID is a unique 128-bit (16 byte) ID used to identify
rgrover1 710:b2e1a2660ec2 123 * different service or characteristics on the BLE device.
rgrover1 710:b2e1a2660ec2 124 *
rgrover1 710:b2e1a2660ec2 125 * @param longUUID
vcoubard 1056:ce2fb3d09929 126 * The 128-bit (16-byte) UUID value.
vcoubard 1056:ce2fb3d09929 127 * @param order
vcoubard 1056:ce2fb3d09929 128 * The bit order of the UUID, MSB by default.
rgrover1 710:b2e1a2660ec2 129 */
vcoubard 1056:ce2fb3d09929 130 UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
vcoubard 1056:ce2fb3d09929 131 setupLong(longUUID, order);
rgrover1 710:b2e1a2660ec2 132 }
rgrover1 710:b2e1a2660ec2 133
rgrover1 710:b2e1a2660ec2 134 /**
vcoubard 1048:efb29faf12fc 135 * Creates a new 16-bit UUID.
rgrover1 710:b2e1a2660ec2 136 *
rgrover1 710:b2e1a2660ec2 137 * @note The UUID is a unique 16-bit (2 byte) ID used to identify
rgrover1 710:b2e1a2660ec2 138 * different service or characteristics on the BLE device.
rgrover1 710:b2e1a2660ec2 139 *
rgrover1 710:b2e1a2660ec2 140 * For efficiency, and because 16 bytes would take a large chunk of the
rgrover1 710:b2e1a2660ec2 141 * 27-byte data payload length of the Link Layer, the BLE specification adds
rgrover1 710:b2e1a2660ec2 142 * two additional UUID formats: 16-bit and 32-bit UUIDs. These shortened
rgrover1 710:b2e1a2660ec2 143 * formats can be used only with UUIDs that are defined in the Bluetooth
vcoubard 1048:efb29faf12fc 144 * specification (listed by the Bluetooth SIG as standard
rgrover1 710:b2e1a2660ec2 145 * Bluetooth UUIDs).
rgrover1 710:b2e1a2660ec2 146 *
rgrover1 710:b2e1a2660ec2 147 * To reconstruct the full 128-bit UUID from the shortened version, insert
rgrover1 710:b2e1a2660ec2 148 * the 16-bit short value (indicated by xxxx, including leading zeros) into
rgrover1 710:b2e1a2660ec2 149 * the Bluetooth Base UUID:
rgrover1 710:b2e1a2660ec2 150 *
rgrover1 710:b2e1a2660ec2 151 * 0000xxxx-0000-1000-8000-00805F9B34FB
rgrover1 710:b2e1a2660ec2 152 *
rgrover1 710:b2e1a2660ec2 153 * @note Shortening is not available for UUIDs that are not derived from the
rgrover1 710:b2e1a2660ec2 154 * Bluetooth Base UUID. Such non-standard UUIDs are commonly called
rgrover1 710:b2e1a2660ec2 155 * vendor-specific UUIDs. In these cases, you’ll need to use the full
rgrover1 710:b2e1a2660ec2 156 * 128-bit UUID value at all times.
rgrover1 710:b2e1a2660ec2 157 *
vcoubard 1048:efb29faf12fc 158 * @note We don't yet support 32-bit shortened UUIDs.
rgrover1 710:b2e1a2660ec2 159 */
rgrover1 911:885ee648c6ab 160 UUID(ShortUUIDBytes_t _shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(_shortUUID) {
vcoubard 1048:efb29faf12fc 161 /* Empty */
rgrover1 710:b2e1a2660ec2 162 }
rgrover1 710:b2e1a2660ec2 163
rgrover1 710:b2e1a2660ec2 164 UUID(const UUID &source) {
rgrover1 710:b2e1a2660ec2 165 type = source.type;
rgrover1 710:b2e1a2660ec2 166 shortUUID = source.shortUUID;
rgrover1 710:b2e1a2660ec2 167 memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID);
rgrover1 710:b2e1a2660ec2 168 }
rgrover1 710:b2e1a2660ec2 169
rgrover1 710:b2e1a2660ec2 170 UUID(void) : type(UUID_TYPE_SHORT), shortUUID(BLE_UUID_UNKNOWN) {
rgrover1 710:b2e1a2660ec2 171 /* empty */
rgrover1 710:b2e1a2660ec2 172 }
rgrover1 710:b2e1a2660ec2 173
rgrover1 710:b2e1a2660ec2 174 /**
vcoubard 1048:efb29faf12fc 175 * Fill in a 128-bit UUID; this is useful when the UUID isn't known at the time of the object construction.
rgrover1 710:b2e1a2660ec2 176 */
vcoubard 1056:ce2fb3d09929 177 void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) {
rgrover1 710:b2e1a2660ec2 178 type = UUID_TYPE_LONG;
vcoubard 1056:ce2fb3d09929 179 if (order == UUID::MSB) {
vcoubard 1056:ce2fb3d09929 180 // Switch endian. Input is big-endian, internal representation is little endian.
vcoubard 1056:ce2fb3d09929 181 std::reverse_copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID);
vcoubard 1056:ce2fb3d09929 182 } else {
vcoubard 1056:ce2fb3d09929 183 std::copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID);
vcoubard 1056:ce2fb3d09929 184 }
vcoubard 1056:ce2fb3d09929 185 shortUUID = (uint16_t)((baseUUID[13] << 8) | (baseUUID[12]));
rgrover1 710:b2e1a2660ec2 186 }
rgrover1 710:b2e1a2660ec2 187
rgrover1 710:b2e1a2660ec2 188 public:
rgrover1 710:b2e1a2660ec2 189 UUID_Type_t shortOrLong(void) const {return type; }
rgrover1 710:b2e1a2660ec2 190 const uint8_t *getBaseUUID(void) const {
rgrover1 710:b2e1a2660ec2 191 if (type == UUID_TYPE_SHORT) {
rgrover1 710:b2e1a2660ec2 192 return (const uint8_t*)&shortUUID;
rgrover1 710:b2e1a2660ec2 193 } else {
rgrover1 710:b2e1a2660ec2 194 return baseUUID;
rgrover1 710:b2e1a2660ec2 195 }
rgrover1 710:b2e1a2660ec2 196 }
rgrover1 710:b2e1a2660ec2 197
rgrover1 710:b2e1a2660ec2 198 ShortUUIDBytes_t getShortUUID(void) const {return shortUUID;}
rgrover1 710:b2e1a2660ec2 199 uint8_t getLen(void) const {
rgrover1 710:b2e1a2660ec2 200 return ((type == UUID_TYPE_SHORT) ? sizeof(ShortUUIDBytes_t) : LENGTH_OF_LONG_UUID);
rgrover1 710:b2e1a2660ec2 201 }
rgrover1 710:b2e1a2660ec2 202
rgrover1 710:b2e1a2660ec2 203 bool operator== (const UUID &other) const {
rgrover1 710:b2e1a2660ec2 204 if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) &&
rgrover1 710:b2e1a2660ec2 205 (this->shortUUID == other.shortUUID)) {
rgrover1 710:b2e1a2660ec2 206 return true;
rgrover1 710:b2e1a2660ec2 207 }
rgrover1 710:b2e1a2660ec2 208
rgrover1 710:b2e1a2660ec2 209 if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) &&
rgrover1 710:b2e1a2660ec2 210 (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) {
rgrover1 710:b2e1a2660ec2 211 return true;
rgrover1 710:b2e1a2660ec2 212 }
rgrover1 710:b2e1a2660ec2 213
rgrover1 710:b2e1a2660ec2 214 return false;
rgrover1 710:b2e1a2660ec2 215 }
rgrover1 710:b2e1a2660ec2 216
rgrover1 710:b2e1a2660ec2 217 bool operator!= (const UUID &other) const {
rgrover1 710:b2e1a2660ec2 218 return !(*this == other);
rgrover1 710:b2e1a2660ec2 219 }
rgrover1 710:b2e1a2660ec2 220
rgrover1 710:b2e1a2660ec2 221 private:
rgrover1 710:b2e1a2660ec2 222 UUID_Type_t type; // UUID_TYPE_SHORT or UUID_TYPE_LONG
vcoubard 1056:ce2fb3d09929 223 LongUUIDBytes_t baseUUID; // The long UUID
vcoubard 1056:ce2fb3d09929 224 ShortUUIDBytes_t shortUUID; // 16 bit UUID
rgrover1 710:b2e1a2660ec2 225 };
rgrover1 710:b2e1a2660ec2 226
rgrover1 710:b2e1a2660ec2 227 #endif // ifndef __UUID_H__