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:
715:6d415ac147aa
Parent:
714:a6130aaa0fd9
Synchronized with git rev 69726547
Author: Rohit Grover
Release 0.3.9
=============

A minor patch to fix a build error introduced by the previous
release. This has to do with certain declarations being made members
of class UUID.

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__*/