High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Wed Apr 06 19:15:30 2016 +0100
Revision:
1179:4ab722f8dca0
Parent:
1170:e8f2db0e8e11
Child:
1183:1589830dbdb7
Synchronized with git rev ca632aaf
Author: Andres Amaya Garcia
Update Gap state after advertising times out

The BLE API was not updating the Gap internal state when the advertising stops
because of a user timeout. This commit fixes the issue by updating the internal
state structure in Gap just before the registered callbacks are notified of the
advertising timeout.

Who changed what in which revision?

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