Lancaster University's fork of the mbed BLE API. Lives on github, https://github.com/lancaster-university/BLE_API

Dependents:   microbit-dal microbit-dal microbit-ble-open microbit-dal ... more

Fork of BLE_API by Bluetooth Low Energy

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