abc

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Fri Nov 21 09:23:25 2014 +0000
Revision:
145:a7ded9ad83c8
Parent:
140:407d134c179d
Child:
146:543877bb1f52
Synchronized with git rev 80f44173
Author: Rohit Grover
Release 0.2.4
=============

Features
~~~~~~~~

* Introduce GattServer::initializeGattDatabase(). This populates the GATT
server with added services.

* Add helper funcs: Gap::MSEC_TO_GAP_DURATION_UNITS() to ease setting up of
connection parameters.

* Enhance connectionEventCallback() to take in peer addr information.

* Minor cleanup of a few public API classes and removal of unnecessary header-file includes.

Bugfixes
~~~~~~~~

* Increase GAP_ADV_PARAMS_INTERVAL_MAX to 0x4000. This addresses mbedmicro/BLE_API/issues/2.

Compatibility
~~~~~~~~~~~~~

One new API has been added (GattServer::initializeGattDatabase()) and
Gap::ConnectionEventCallback_t has been extended. Applications depending on
these should be updated.

Who changed what in which revision?

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