High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Thu Dec 10 09:15:02 2015 +0000
Revision:
1022:306c409f6c09
Parent:
993:4d62b7967c11
Child:
1023:a072b59caddb
Synchronized with git rev ea69dba5
Author: Marcus Chang
Reversed internal representation of long UUID in the UUID class to little endian to be consistent with the short UUID.

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>
rgrover1 710:b2e1a2660ec2 22
rgrover1 710:b2e1a2660ec2 23 #include "blecommon.h"
rgrover1 710:b2e1a2660ec2 24
rgrover1 1022:306c409f6c09 25 static uint16_t char2int(char c) {
rgrover1 1022:306c409f6c09 26 if ((c >= '0') && (c <= '9')) {
rgrover1 1022:306c409f6c09 27 return c - '0';
rgrover1 1022:306c409f6c09 28 } else if ((c >= 'a') && (c <= 'f')) {
rgrover1 1022:306c409f6c09 29 return c - 'a' + 10;
rgrover1 1022:306c409f6c09 30 } else if ((c >= 'A') && (c <= 'F')) {
rgrover1 1022:306c409f6c09 31 return c - 'A' + 10;
rgrover1 1022:306c409f6c09 32 } else {
rgrover1 1022:306c409f6c09 33 return 0;
rgrover1 1022:306c409f6c09 34 }
rgrover1 1022:306c409f6c09 35 }
rgrover1 1022:306c409f6c09 36
rgrover1 710:b2e1a2660ec2 37 class UUID {
rgrover1 710:b2e1a2660ec2 38 public:
rgrover1 710:b2e1a2660ec2 39 enum UUID_Type_t {
rgrover1 993:4d62b7967c11 40 UUID_TYPE_SHORT = 0, // Short BLE UUID.
rgrover1 993:4d62b7967c11 41 UUID_TYPE_LONG = 1 // Full 128-bit UUID.
rgrover1 710:b2e1a2660ec2 42 };
rgrover1 710:b2e1a2660ec2 43
rgrover1 710:b2e1a2660ec2 44 typedef uint16_t ShortUUIDBytes_t;
rgrover1 710:b2e1a2660ec2 45
rgrover1 710:b2e1a2660ec2 46 static const unsigned LENGTH_OF_LONG_UUID = 16;
rgrover1 710:b2e1a2660ec2 47 typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
rgrover1 710:b2e1a2660ec2 48
rgrover1 710:b2e1a2660ec2 49 public:
rgrover1 1022:306c409f6c09 50
rgrover1 1022:306c409f6c09 51 /**
rgrover1 1022:306c409f6c09 52 * Creates a new 128-bit UUID.
rgrover1 1022:306c409f6c09 53 *
rgrover1 1022:306c409f6c09 54 * @note The UUID is a unique 128-bit (16 byte) ID used to identify
rgrover1 1022:306c409f6c09 55 * different service or characteristics on the BLE device.
rgrover1 1022:306c409f6c09 56 *
rgrover1 1022:306c409f6c09 57 * @param stringUUID
rgrover1 1022:306c409f6c09 58 * The 128-bit (16-byte) UUID as a human readable const-string.
rgrover1 1022:306c409f6c09 59 * Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
rgrover1 1022:306c409f6c09 60 * Upper and lower case supported. Hyphens are optional, but only
rgrover1 1022:306c409f6c09 61 * upto four of them. The UUID is stored internally as a 16 byte
rgrover1 1022:306c409f6c09 62 * array, LSB (little endian), which is opposite from the string.
rgrover1 1022:306c409f6c09 63 */
rgrover1 1022:306c409f6c09 64 UUID(const char* stringUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
rgrover1 1022:306c409f6c09 65 bool nibble = false;
rgrover1 1022:306c409f6c09 66 uint8_t byte = 0;
rgrover1 1022:306c409f6c09 67 size_t baseIndex = 0;
rgrover1 1022:306c409f6c09 68
rgrover1 1022:306c409f6c09 69 // Iterate through string, abort if NULL is encountered prematurely.
rgrover1 1022:306c409f6c09 70 // Ignore upto four hyphens. Reverse endian when storing internally.
rgrover1 1022:306c409f6c09 71 for (size_t index = 0; (index < 36) && (baseIndex < LENGTH_OF_LONG_UUID); index++) {
rgrover1 1022:306c409f6c09 72 if (stringUUID[index] == '\0') {
rgrover1 1022:306c409f6c09 73 // error abort
rgrover1 1022:306c409f6c09 74 break;
rgrover1 1022:306c409f6c09 75 } else if (stringUUID[index] == '-') {
rgrover1 1022:306c409f6c09 76 // ignore hyphen
rgrover1 1022:306c409f6c09 77 continue;
rgrover1 1022:306c409f6c09 78 } else if (nibble) {
rgrover1 1022:306c409f6c09 79 // got second nibble
rgrover1 1022:306c409f6c09 80 byte |= char2int(stringUUID[index]);
rgrover1 1022:306c409f6c09 81 nibble = false;
rgrover1 1022:306c409f6c09 82
rgrover1 1022:306c409f6c09 83 // reverse endian
rgrover1 1022:306c409f6c09 84 baseUUID[LENGTH_OF_LONG_UUID - 1 - baseIndex++] = byte;
rgrover1 1022:306c409f6c09 85 } else {
rgrover1 1022:306c409f6c09 86 // got first nibble
rgrover1 1022:306c409f6c09 87 byte = char2int(stringUUID[index]) << 4;
rgrover1 1022:306c409f6c09 88 nibble = true;
rgrover1 1022:306c409f6c09 89 }
rgrover1 1022:306c409f6c09 90 }
rgrover1 1022:306c409f6c09 91 }
rgrover1 1022:306c409f6c09 92
rgrover1 710:b2e1a2660ec2 93 /**
rgrover1 993:4d62b7967c11 94 * Creates a new 128-bit UUID.
rgrover1 710:b2e1a2660ec2 95 *
rgrover1 710:b2e1a2660ec2 96 * @note The UUID is a unique 128-bit (16 byte) ID used to identify
rgrover1 710:b2e1a2660ec2 97 * different service or characteristics on the BLE device.
rgrover1 710:b2e1a2660ec2 98 *
rgrover1 710:b2e1a2660ec2 99 * @param longUUID
rgrover1 1022:306c409f6c09 100 * The 128-bit (16-byte) UUID value, LSB first (little-endian).
rgrover1 710:b2e1a2660ec2 101 */
rgrover1 710:b2e1a2660ec2 102 UUID(const LongUUIDBytes_t longUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
rgrover1 710:b2e1a2660ec2 103 setupLong(longUUID);
rgrover1 710:b2e1a2660ec2 104 }
rgrover1 710:b2e1a2660ec2 105
rgrover1 710:b2e1a2660ec2 106 /**
rgrover1 993:4d62b7967c11 107 * Creates a new 16-bit UUID.
rgrover1 710:b2e1a2660ec2 108 *
rgrover1 710:b2e1a2660ec2 109 * @note The UUID is a unique 16-bit (2 byte) ID used to identify
rgrover1 710:b2e1a2660ec2 110 * different service or characteristics on the BLE device.
rgrover1 710:b2e1a2660ec2 111 *
rgrover1 710:b2e1a2660ec2 112 * For efficiency, and because 16 bytes would take a large chunk of the
rgrover1 710:b2e1a2660ec2 113 * 27-byte data payload length of the Link Layer, the BLE specification adds
rgrover1 710:b2e1a2660ec2 114 * two additional UUID formats: 16-bit and 32-bit UUIDs. These shortened
rgrover1 710:b2e1a2660ec2 115 * formats can be used only with UUIDs that are defined in the Bluetooth
rgrover1 993:4d62b7967c11 116 * specification (listed by the Bluetooth SIG as standard
rgrover1 710:b2e1a2660ec2 117 * Bluetooth UUIDs).
rgrover1 710:b2e1a2660ec2 118 *
rgrover1 710:b2e1a2660ec2 119 * To reconstruct the full 128-bit UUID from the shortened version, insert
rgrover1 710:b2e1a2660ec2 120 * the 16-bit short value (indicated by xxxx, including leading zeros) into
rgrover1 710:b2e1a2660ec2 121 * the Bluetooth Base UUID:
rgrover1 710:b2e1a2660ec2 122 *
rgrover1 710:b2e1a2660ec2 123 * 0000xxxx-0000-1000-8000-00805F9B34FB
rgrover1 710:b2e1a2660ec2 124 *
rgrover1 710:b2e1a2660ec2 125 * @note Shortening is not available for UUIDs that are not derived from the
rgrover1 710:b2e1a2660ec2 126 * Bluetooth Base UUID. Such non-standard UUIDs are commonly called
rgrover1 710:b2e1a2660ec2 127 * vendor-specific UUIDs. In these cases, you’ll need to use the full
rgrover1 710:b2e1a2660ec2 128 * 128-bit UUID value at all times.
rgrover1 710:b2e1a2660ec2 129 *
rgrover1 993:4d62b7967c11 130 * @note We don't yet support 32-bit shortened UUIDs.
rgrover1 710:b2e1a2660ec2 131 */
rgrover1 911:885ee648c6ab 132 UUID(ShortUUIDBytes_t _shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(_shortUUID) {
rgrover1 993:4d62b7967c11 133 /* Empty */
rgrover1 710:b2e1a2660ec2 134 }
rgrover1 710:b2e1a2660ec2 135
rgrover1 710:b2e1a2660ec2 136 UUID(const UUID &source) {
rgrover1 710:b2e1a2660ec2 137 type = source.type;
rgrover1 710:b2e1a2660ec2 138 shortUUID = source.shortUUID;
rgrover1 710:b2e1a2660ec2 139 memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID);
rgrover1 710:b2e1a2660ec2 140 }
rgrover1 710:b2e1a2660ec2 141
rgrover1 710:b2e1a2660ec2 142 UUID(void) : type(UUID_TYPE_SHORT), shortUUID(BLE_UUID_UNKNOWN) {
rgrover1 710:b2e1a2660ec2 143 /* empty */
rgrover1 710:b2e1a2660ec2 144 }
rgrover1 710:b2e1a2660ec2 145
rgrover1 710:b2e1a2660ec2 146 /**
rgrover1 993:4d62b7967c11 147 * 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 148 */
rgrover1 710:b2e1a2660ec2 149 void setupLong(const LongUUIDBytes_t longUUID) {
rgrover1 710:b2e1a2660ec2 150 type = UUID_TYPE_LONG;
rgrover1 710:b2e1a2660ec2 151 memcpy(baseUUID, longUUID, LENGTH_OF_LONG_UUID);
rgrover1 1022:306c409f6c09 152 shortUUID = (uint16_t)((longUUID[13] << 8) | (longUUID[12]));
rgrover1 710:b2e1a2660ec2 153 }
rgrover1 710:b2e1a2660ec2 154
rgrover1 710:b2e1a2660ec2 155 public:
rgrover1 710:b2e1a2660ec2 156 UUID_Type_t shortOrLong(void) const {return type; }
rgrover1 710:b2e1a2660ec2 157 const uint8_t *getBaseUUID(void) const {
rgrover1 710:b2e1a2660ec2 158 if (type == UUID_TYPE_SHORT) {
rgrover1 710:b2e1a2660ec2 159 return (const uint8_t*)&shortUUID;
rgrover1 710:b2e1a2660ec2 160 } else {
rgrover1 710:b2e1a2660ec2 161 return baseUUID;
rgrover1 710:b2e1a2660ec2 162 }
rgrover1 710:b2e1a2660ec2 163 }
rgrover1 710:b2e1a2660ec2 164
rgrover1 710:b2e1a2660ec2 165 ShortUUIDBytes_t getShortUUID(void) const {return shortUUID;}
rgrover1 710:b2e1a2660ec2 166 uint8_t getLen(void) const {
rgrover1 710:b2e1a2660ec2 167 return ((type == UUID_TYPE_SHORT) ? sizeof(ShortUUIDBytes_t) : LENGTH_OF_LONG_UUID);
rgrover1 710:b2e1a2660ec2 168 }
rgrover1 710:b2e1a2660ec2 169
rgrover1 710:b2e1a2660ec2 170 bool operator== (const UUID &other) const {
rgrover1 710:b2e1a2660ec2 171 if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) &&
rgrover1 710:b2e1a2660ec2 172 (this->shortUUID == other.shortUUID)) {
rgrover1 710:b2e1a2660ec2 173 return true;
rgrover1 710:b2e1a2660ec2 174 }
rgrover1 710:b2e1a2660ec2 175
rgrover1 710:b2e1a2660ec2 176 if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) &&
rgrover1 710:b2e1a2660ec2 177 (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) {
rgrover1 710:b2e1a2660ec2 178 return true;
rgrover1 710:b2e1a2660ec2 179 }
rgrover1 710:b2e1a2660ec2 180
rgrover1 710:b2e1a2660ec2 181 return false;
rgrover1 710:b2e1a2660ec2 182 }
rgrover1 710:b2e1a2660ec2 183
rgrover1 710:b2e1a2660ec2 184 bool operator!= (const UUID &other) const {
rgrover1 710:b2e1a2660ec2 185 return !(*this == other);
rgrover1 710:b2e1a2660ec2 186 }
rgrover1 710:b2e1a2660ec2 187
rgrover1 710:b2e1a2660ec2 188 private:
rgrover1 710:b2e1a2660ec2 189 UUID_Type_t type; // UUID_TYPE_SHORT or UUID_TYPE_LONG
rgrover1 993:4d62b7967c11 190 LongUUIDBytes_t baseUUID; /* The base of the long UUID (if
rgrover1 710:b2e1a2660ec2 191 * used). Note: bytes 12 and 13 (counting from LSB)
rgrover1 710:b2e1a2660ec2 192 * are zeroed out to allow comparison with other long
rgrover1 993:4d62b7967c11 193 * UUIDs, which differ only in the 16-bit relative
rgrover1 710:b2e1a2660ec2 194 * part.*/
rgrover1 993:4d62b7967c11 195 ShortUUIDBytes_t shortUUID; // 16 bit UUID (byte 2-3 using with base).
rgrover1 710:b2e1a2660ec2 196 };
rgrover1 710:b2e1a2660ec2 197
rgrover1 710:b2e1a2660ec2 198 #endif // ifndef __UUID_H__