Bruno Horta / DOOR_BLE_API

Dependents:   DOOR_BLE_PROGRAM

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Thu Jul 02 09:06:11 2015 +0100
Revision:
714:a6130aaa0fd9
Synchronized with git rev 7e8977d8
Author: Rohit Grover
Release 0.3.8
=============

This is a minor set of enhancements before we yotta-ize BLE_API.

Enhancements
~~~~~~~~~~~~

* Minor rework for class UUID; added a default and copy constructor; and a != operator.

* Added copy constructor and accessors for GapAdvertisingParams.

* GapScanningParams:: remove unnecessary checks for SCAN_TIMEOUT_MAX.

* Add a comment header block to explain why BLEDevice::init() may not be safe
to call from global static context.

* Introduce GattAttribute::INVALID_HANDLE.

* Replace some deprecated uses of Gap::address_t with Gap::Address_t.

Bugfixes
~~~~~~~~

* None.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 714:a6130aaa0fd9 1 /* mbed Microcontroller Library
rgrover1 714:a6130aaa0fd9 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 714:a6130aaa0fd9 3 *
rgrover1 714:a6130aaa0fd9 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 714:a6130aaa0fd9 5 * you may not use this file except in compliance with the License.
rgrover1 714:a6130aaa0fd9 6 * You may obtain a copy of the License at
rgrover1 714:a6130aaa0fd9 7 *
rgrover1 714:a6130aaa0fd9 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 714:a6130aaa0fd9 9 *
rgrover1 714:a6130aaa0fd9 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 714:a6130aaa0fd9 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 714:a6130aaa0fd9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 714:a6130aaa0fd9 13 * See the License for the specific language governing permissions and
rgrover1 714:a6130aaa0fd9 14 * limitations under the License.
rgrover1 714:a6130aaa0fd9 15 */
rgrover1 714:a6130aaa0fd9 16
rgrover1 714:a6130aaa0fd9 17 #ifndef __BLE_UART_SERVICE_H__
rgrover1 714:a6130aaa0fd9 18 #define __BLE_UART_SERVICE_H__
rgrover1 714:a6130aaa0fd9 19
rgrover1 714:a6130aaa0fd9 20 #include "mbed.h"
rgrover1 714:a6130aaa0fd9 21 #include "Stream.h"
rgrover1 714:a6130aaa0fd9 22
rgrover1 714:a6130aaa0fd9 23 #include "UUID.h"
rgrover1 714:a6130aaa0fd9 24 #include "BLEDevice.h"
rgrover1 714:a6130aaa0fd9 25
rgrover1 714:a6130aaa0fd9 26 extern const uint8_t UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID];
rgrover1 714:a6130aaa0fd9 27 extern const uint16_t UARTServiceShortUUID;
rgrover1 714:a6130aaa0fd9 28 extern const uint16_t UARTServiceTXCharacteristicShortUUID;
rgrover1 714:a6130aaa0fd9 29 extern const uint16_t UARTServiceRXCharacteristicShortUUID;
rgrover1 714:a6130aaa0fd9 30
rgrover1 714:a6130aaa0fd9 31 extern const uint8_t UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID];
rgrover1 714:a6130aaa0fd9 32 extern const uint8_t UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID];
rgrover1 714:a6130aaa0fd9 33
rgrover1 714:a6130aaa0fd9 34 extern const uint8_t UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
rgrover1 714:a6130aaa0fd9 35 extern const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
rgrover1 714:a6130aaa0fd9 36
rgrover1 714:a6130aaa0fd9 37 /**
rgrover1 714:a6130aaa0fd9 38 * @class UARTService
rgrover1 714:a6130aaa0fd9 39 * @brief BLE Service to enable UART over BLE
rgrover1 714:a6130aaa0fd9 40 */
rgrover1 714:a6130aaa0fd9 41 class UARTService {
rgrover1 714:a6130aaa0fd9 42 public:
rgrover1 714:a6130aaa0fd9 43 /**< Maximum length of data (in bytes) that can be transmitted by the UART service module to the peer. */
rgrover1 714:a6130aaa0fd9 44 static const unsigned GATT_MTU_SIZE_DEFAULT = 23;
rgrover1 714:a6130aaa0fd9 45 static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (GATT_MTU_SIZE_DEFAULT - 3);
rgrover1 714:a6130aaa0fd9 46
rgrover1 714:a6130aaa0fd9 47 public:
rgrover1 714:a6130aaa0fd9 48
rgrover1 714:a6130aaa0fd9 49 /**
rgrover1 714:a6130aaa0fd9 50 * @param[ref] ble
rgrover1 714:a6130aaa0fd9 51 * BLEDevice object for the underlying controller.
rgrover1 714:a6130aaa0fd9 52 */
rgrover1 714:a6130aaa0fd9 53 UARTService(BLEDevice &_ble) :
rgrover1 714:a6130aaa0fd9 54 ble(_ble),
rgrover1 714:a6130aaa0fd9 55 receiveBuffer(),
rgrover1 714:a6130aaa0fd9 56 sendBuffer(),
rgrover1 714:a6130aaa0fd9 57 sendBufferIndex(0),
rgrover1 714:a6130aaa0fd9 58 numBytesReceived(0),
rgrover1 714:a6130aaa0fd9 59 receiveBufferIndex(0),
rgrover1 714:a6130aaa0fd9 60 txCharacteristic(UARTServiceTXCharacteristicUUID, receiveBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN,
rgrover1 714:a6130aaa0fd9 61 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
rgrover1 714:a6130aaa0fd9 62 rxCharacteristic(UARTServiceRXCharacteristicUUID, sendBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) {
rgrover1 714:a6130aaa0fd9 63 GattCharacteristic *charTable[] = {&txCharacteristic, &rxCharacteristic};
rgrover1 714:a6130aaa0fd9 64 GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
rgrover1 714:a6130aaa0fd9 65
rgrover1 714:a6130aaa0fd9 66 ble.addService(uartService);
rgrover1 714:a6130aaa0fd9 67 ble.onDataWritten(this, &UARTService::onDataWritten);
rgrover1 714:a6130aaa0fd9 68 }
rgrover1 714:a6130aaa0fd9 69
rgrover1 714:a6130aaa0fd9 70 /**
rgrover1 714:a6130aaa0fd9 71 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
rgrover1 714:a6130aaa0fd9 72 */
rgrover1 714:a6130aaa0fd9 73 uint16_t getTXCharacteristicHandle() {
rgrover1 714:a6130aaa0fd9 74 return txCharacteristic.getValueAttribute().getHandle();
rgrover1 714:a6130aaa0fd9 75 }
rgrover1 714:a6130aaa0fd9 76
rgrover1 714:a6130aaa0fd9 77 /**
rgrover1 714:a6130aaa0fd9 78 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
rgrover1 714:a6130aaa0fd9 79 */
rgrover1 714:a6130aaa0fd9 80 uint16_t getRXCharacteristicHandle() {
rgrover1 714:a6130aaa0fd9 81 return rxCharacteristic.getValueAttribute().getHandle();
rgrover1 714:a6130aaa0fd9 82 }
rgrover1 714:a6130aaa0fd9 83
rgrover1 714:a6130aaa0fd9 84 /**
rgrover1 714:a6130aaa0fd9 85 * We attempt to collect bytes before pushing them to the UART RX
rgrover1 714:a6130aaa0fd9 86 * characteristic--writing to the RX characteristic will then generate
rgrover1 714:a6130aaa0fd9 87 * notifications for the client. Updates made in quick succession to a
rgrover1 714:a6130aaa0fd9 88 * notification-generating characteristic will result in data being buffered
rgrover1 714:a6130aaa0fd9 89 * in the bluetooth stack as notifications are sent out. The stack will have
rgrover1 714:a6130aaa0fd9 90 * its limits for this buffering; typically a small number under 10.
rgrover1 714:a6130aaa0fd9 91 * Collecting data into the sendBuffer buffer helps mitigate the rate of
rgrover1 714:a6130aaa0fd9 92 * updates. But we shouldn't buffer a large amount of data before updating
rgrover1 714:a6130aaa0fd9 93 * the characteristic otherwise the client will need to turn around and make
rgrover1 714:a6130aaa0fd9 94 * a long read request; this is because notifications include only the first
rgrover1 714:a6130aaa0fd9 95 * 20 bytes of the updated data.
rgrover1 714:a6130aaa0fd9 96 *
rgrover1 714:a6130aaa0fd9 97 * @param buffer The received update
rgrover1 714:a6130aaa0fd9 98 * @param length Amount of characters to be appended.
rgrover1 714:a6130aaa0fd9 99 * @return Amount of characters appended to the rxCharacteristic.
rgrover1 714:a6130aaa0fd9 100 */
rgrover1 714:a6130aaa0fd9 101 size_t write(const void *_buffer, size_t length) {
rgrover1 714:a6130aaa0fd9 102 size_t origLength = length;
rgrover1 714:a6130aaa0fd9 103 const uint8_t *buffer = static_cast<const uint8_t *>(_buffer);
rgrover1 714:a6130aaa0fd9 104
rgrover1 714:a6130aaa0fd9 105 if (ble.getGapState().connected) {
rgrover1 714:a6130aaa0fd9 106 unsigned bufferIndex = 0;
rgrover1 714:a6130aaa0fd9 107 while (length) {
rgrover1 714:a6130aaa0fd9 108 unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex;
rgrover1 714:a6130aaa0fd9 109 unsigned bytesToCopy = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer;
rgrover1 714:a6130aaa0fd9 110
rgrover1 714:a6130aaa0fd9 111 /* copy bytes into sendBuffer */
rgrover1 714:a6130aaa0fd9 112 memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy);
rgrover1 714:a6130aaa0fd9 113 length -= bytesToCopy;
rgrover1 714:a6130aaa0fd9 114 sendBufferIndex += bytesToCopy;
rgrover1 714:a6130aaa0fd9 115 bufferIndex += bytesToCopy;
rgrover1 714:a6130aaa0fd9 116
rgrover1 714:a6130aaa0fd9 117 /* have we collected enough? */
rgrover1 714:a6130aaa0fd9 118 if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) ||
rgrover1 714:a6130aaa0fd9 119 // (sendBuffer[sendBufferIndex - 1] == '\r') ||
rgrover1 714:a6130aaa0fd9 120 (sendBuffer[sendBufferIndex - 1] == '\n')) {
rgrover1 714:a6130aaa0fd9 121 ble.updateCharacteristicValue(getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex);
rgrover1 714:a6130aaa0fd9 122 sendBufferIndex = 0;
rgrover1 714:a6130aaa0fd9 123 }
rgrover1 714:a6130aaa0fd9 124 }
rgrover1 714:a6130aaa0fd9 125 }
rgrover1 714:a6130aaa0fd9 126
rgrover1 714:a6130aaa0fd9 127 return origLength;
rgrover1 714:a6130aaa0fd9 128 }
rgrover1 714:a6130aaa0fd9 129
rgrover1 714:a6130aaa0fd9 130 /**
rgrover1 714:a6130aaa0fd9 131 * Helper function to write out strings.
rgrover1 714:a6130aaa0fd9 132 * @param str The received string.
rgrover1 714:a6130aaa0fd9 133 * @return Amount of characters appended to the rxCharacteristic.
rgrover1 714:a6130aaa0fd9 134 */
rgrover1 714:a6130aaa0fd9 135 size_t writeString(const char *str) {
rgrover1 714:a6130aaa0fd9 136 return write(str, strlen(str));
rgrover1 714:a6130aaa0fd9 137 }
rgrover1 714:a6130aaa0fd9 138
rgrover1 714:a6130aaa0fd9 139 /**
rgrover1 714:a6130aaa0fd9 140 * Override for Stream::_putc()
rgrover1 714:a6130aaa0fd9 141 * @param c
rgrover1 714:a6130aaa0fd9 142 * This function writes the character c, cast to an unsigned char, to stream.
rgrover1 714:a6130aaa0fd9 143 * @return
rgrover1 714:a6130aaa0fd9 144 * The character written as an unsigned char cast to an int or EOF on error.
rgrover1 714:a6130aaa0fd9 145 */
rgrover1 714:a6130aaa0fd9 146 int _putc(int c) {
rgrover1 714:a6130aaa0fd9 147 return (write(&c, 1) == 1) ? 1 : EOF;
rgrover1 714:a6130aaa0fd9 148 }
rgrover1 714:a6130aaa0fd9 149
rgrover1 714:a6130aaa0fd9 150 /**
rgrover1 714:a6130aaa0fd9 151 * Override for Stream::_getc()
rgrover1 714:a6130aaa0fd9 152 * @return
rgrover1 714:a6130aaa0fd9 153 * The character read.
rgrover1 714:a6130aaa0fd9 154 */
rgrover1 714:a6130aaa0fd9 155 int _getc() {
rgrover1 714:a6130aaa0fd9 156 if (receiveBufferIndex == numBytesReceived) {
rgrover1 714:a6130aaa0fd9 157 return EOF;
rgrover1 714:a6130aaa0fd9 158 }
rgrover1 714:a6130aaa0fd9 159
rgrover1 714:a6130aaa0fd9 160 return receiveBuffer[receiveBufferIndex++];
rgrover1 714:a6130aaa0fd9 161 }
rgrover1 714:a6130aaa0fd9 162
rgrover1 714:a6130aaa0fd9 163 private:
rgrover1 714:a6130aaa0fd9 164 /**
rgrover1 714:a6130aaa0fd9 165 * This callback allows the UART service to receive updates to the
rgrover1 714:a6130aaa0fd9 166 * txCharacteristic. The application should forward the call to this
rgrover1 714:a6130aaa0fd9 167 * function from the global onDataWritten() callback handler; or if that's
rgrover1 714:a6130aaa0fd9 168 * not used, this method can be used as a callback directly.
rgrover1 714:a6130aaa0fd9 169 */
rgrover1 714:a6130aaa0fd9 170 void onDataWritten(const GattCharacteristicWriteCBParams *params) {
rgrover1 714:a6130aaa0fd9 171 if (params->charHandle == getTXCharacteristicHandle()) {
rgrover1 714:a6130aaa0fd9 172 uint16_t bytesRead = params->len;
rgrover1 714:a6130aaa0fd9 173 if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) {
rgrover1 714:a6130aaa0fd9 174 numBytesReceived = bytesRead;
rgrover1 714:a6130aaa0fd9 175 receiveBufferIndex = 0;
rgrover1 714:a6130aaa0fd9 176 memcpy(receiveBuffer, params->data, numBytesReceived);
rgrover1 714:a6130aaa0fd9 177 }
rgrover1 714:a6130aaa0fd9 178 }
rgrover1 714:a6130aaa0fd9 179 }
rgrover1 714:a6130aaa0fd9 180
rgrover1 714:a6130aaa0fd9 181 private:
rgrover1 714:a6130aaa0fd9 182 BLEDevice &ble;
rgrover1 714:a6130aaa0fd9 183
rgrover1 714:a6130aaa0fd9 184 uint8_t receiveBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which we receive
rgrover1 714:a6130aaa0fd9 185 * inbound data before forwarding it to the
rgrover1 714:a6130aaa0fd9 186 * application. */
rgrover1 714:a6130aaa0fd9 187
rgrover1 714:a6130aaa0fd9 188 uint8_t sendBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which outbound data is
rgrover1 714:a6130aaa0fd9 189 * accumulated before being pushed to the
rgrover1 714:a6130aaa0fd9 190 * rxCharacteristic. */
rgrover1 714:a6130aaa0fd9 191 uint8_t sendBufferIndex;
rgrover1 714:a6130aaa0fd9 192 uint8_t numBytesReceived;
rgrover1 714:a6130aaa0fd9 193 uint8_t receiveBufferIndex;
rgrover1 714:a6130aaa0fd9 194
rgrover1 714:a6130aaa0fd9 195 GattCharacteristic txCharacteristic; /**< From the point of view of the external client, this is the characteristic
rgrover1 714:a6130aaa0fd9 196 * they'd write into in order to communicate with this application. */
rgrover1 714:a6130aaa0fd9 197 GattCharacteristic rxCharacteristic; /**< From the point of view of the external client, this is the characteristic
rgrover1 714:a6130aaa0fd9 198 * they'd read from in order to receive the bytes transmitted by this
rgrover1 714:a6130aaa0fd9 199 * application. */
rgrover1 714:a6130aaa0fd9 200 };
rgrover1 714:a6130aaa0fd9 201
rgrover1 714:a6130aaa0fd9 202 #endif /* #ifndef __BLE_UART_SERVICE_H__*/