jgh

Dependents:   Migration

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Wed Dec 02 10:29:45 2015 +0000
Revision:
1001:9977b508cea8
Parent:
1000:409fdc9db5f8
Child:
1006:76ae9bbf173f
Synchronized with git rev 23690e78
Author: Rohit Grover
Merge pull request #125 from iriark01/patch-8

Edit

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 extern const uint8_t UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID];
rgrover1 712:b04b5db36865 38
rgrover1 712:b04b5db36865 39 extern const uint8_t UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
rgrover1 712:b04b5db36865 40 extern const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
rgrover1 712:b04b5db36865 41
rgrover1 712:b04b5db36865 42 /**
rgrover1 1001:9977b508cea8 43 * @class UARTService.
rgrover1 1001:9977b508cea8 44 * @brief BLE Service to enable UART over BLE.
rgrover1 712:b04b5db36865 45 */
rgrover1 712:b04b5db36865 46 class UARTService {
rgrover1 712:b04b5db36865 47 public:
rgrover1 1001:9977b508cea8 48 /**< Maximum length of data (in bytes) that the UART service module can transmit to the peer. */
rgrover1 728:997ba5e7b3b6 49 static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (BLE_GATT_MTU_SIZE_DEFAULT - 3);
rgrover1 712:b04b5db36865 50
rgrover1 712:b04b5db36865 51 public:
rgrover1 712:b04b5db36865 52
rgrover1 712:b04b5db36865 53 /**
rgrover1 712:b04b5db36865 54 * @param[ref] ble
rgrover1 712:b04b5db36865 55 * BLE object for the underlying controller.
rgrover1 712:b04b5db36865 56 */
rgrover1 712:b04b5db36865 57 UARTService(BLE &_ble) :
rgrover1 712:b04b5db36865 58 ble(_ble),
rgrover1 712:b04b5db36865 59 receiveBuffer(),
rgrover1 712:b04b5db36865 60 sendBuffer(),
rgrover1 712:b04b5db36865 61 sendBufferIndex(0),
rgrover1 712:b04b5db36865 62 numBytesReceived(0),
rgrover1 712:b04b5db36865 63 receiveBufferIndex(0),
rgrover1 712:b04b5db36865 64 txCharacteristic(UARTServiceTXCharacteristicUUID, receiveBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN,
rgrover1 712:b04b5db36865 65 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
rgrover1 712:b04b5db36865 66 rxCharacteristic(UARTServiceRXCharacteristicUUID, sendBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) {
rgrover1 712:b04b5db36865 67 GattCharacteristic *charTable[] = {&txCharacteristic, &rxCharacteristic};
rgrover1 712:b04b5db36865 68 GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
rgrover1 712:b04b5db36865 69
rgrover1 712:b04b5db36865 70 ble.addService(uartService);
rgrover1 712:b04b5db36865 71 ble.onDataWritten(this, &UARTService::onDataWritten);
rgrover1 712:b04b5db36865 72 }
rgrover1 712:b04b5db36865 73
rgrover1 712:b04b5db36865 74 /**
rgrover1 712:b04b5db36865 75 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
rgrover1 712:b04b5db36865 76 */
rgrover1 712:b04b5db36865 77 uint16_t getTXCharacteristicHandle() {
rgrover1 712:b04b5db36865 78 return txCharacteristic.getValueAttribute().getHandle();
rgrover1 712:b04b5db36865 79 }
rgrover1 712:b04b5db36865 80
rgrover1 712:b04b5db36865 81 /**
rgrover1 712:b04b5db36865 82 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
rgrover1 712:b04b5db36865 83 */
rgrover1 712:b04b5db36865 84 uint16_t getRXCharacteristicHandle() {
rgrover1 712:b04b5db36865 85 return rxCharacteristic.getValueAttribute().getHandle();
rgrover1 712:b04b5db36865 86 }
rgrover1 712:b04b5db36865 87
rgrover1 712:b04b5db36865 88 /**
rgrover1 712:b04b5db36865 89 * We attempt to collect bytes before pushing them to the UART RX
rgrover1 1001:9977b508cea8 90 * characteristic; writing to the RX characteristic then generates
rgrover1 712:b04b5db36865 91 * notifications for the client. Updates made in quick succession to a
rgrover1 1001:9977b508cea8 92 * notification-generating characteristic result in data being buffered
rgrover1 1001:9977b508cea8 93 * in the Bluetooth stack as notifications are sent out. The stack has
rgrover1 1001:9977b508cea8 94 * its limits for this buffering - typically a small number under 10.
rgrover1 712:b04b5db36865 95 * Collecting data into the sendBuffer buffer helps mitigate the rate of
rgrover1 712:b04b5db36865 96 * updates. But we shouldn't buffer a large amount of data before updating
rgrover1 1001:9977b508cea8 97 * the characteristic, otherwise the client needs to turn around and make
rgrover1 712:b04b5db36865 98 * a long read request; this is because notifications include only the first
rgrover1 712:b04b5db36865 99 * 20 bytes of the updated data.
rgrover1 712:b04b5db36865 100 *
rgrover1 1001:9977b508cea8 101 * @param buffer The received update.
rgrover1 1001:9977b508cea8 102 * @param length Number of characters to be appended.
rgrover1 1001:9977b508cea8 103 * @return Number of characters appended to the rxCharacteristic.
rgrover1 712:b04b5db36865 104 */
rgrover1 712:b04b5db36865 105 size_t write(const void *_buffer, size_t length) {
rgrover1 712:b04b5db36865 106 size_t origLength = length;
rgrover1 712:b04b5db36865 107 const uint8_t *buffer = static_cast<const uint8_t *>(_buffer);
rgrover1 712:b04b5db36865 108
rgrover1 712:b04b5db36865 109 if (ble.getGapState().connected) {
rgrover1 712:b04b5db36865 110 unsigned bufferIndex = 0;
rgrover1 712:b04b5db36865 111 while (length) {
rgrover1 712:b04b5db36865 112 unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex;
rgrover1 712:b04b5db36865 113 unsigned bytesToCopy = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer;
rgrover1 712:b04b5db36865 114
rgrover1 1001:9977b508cea8 115 /* Copy bytes into sendBuffer. */
rgrover1 712:b04b5db36865 116 memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy);
rgrover1 712:b04b5db36865 117 length -= bytesToCopy;
rgrover1 712:b04b5db36865 118 sendBufferIndex += bytesToCopy;
rgrover1 712:b04b5db36865 119 bufferIndex += bytesToCopy;
rgrover1 712:b04b5db36865 120
rgrover1 1001:9977b508cea8 121 /* Have we collected enough? */
rgrover1 712:b04b5db36865 122 if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) ||
rgrover1 712:b04b5db36865 123 // (sendBuffer[sendBufferIndex - 1] == '\r') ||
rgrover1 712:b04b5db36865 124 (sendBuffer[sendBufferIndex - 1] == '\n')) {
rgrover1 728:997ba5e7b3b6 125 ble.gattServer().write(getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex);
rgrover1 712:b04b5db36865 126 sendBufferIndex = 0;
rgrover1 712:b04b5db36865 127 }
rgrover1 712:b04b5db36865 128 }
rgrover1 712:b04b5db36865 129 }
rgrover1 712:b04b5db36865 130
rgrover1 712:b04b5db36865 131 return origLength;
rgrover1 712:b04b5db36865 132 }
rgrover1 712:b04b5db36865 133
rgrover1 712:b04b5db36865 134 /**
rgrover1 712:b04b5db36865 135 * Helper function to write out strings.
rgrover1 712:b04b5db36865 136 * @param str The received string.
rgrover1 1001:9977b508cea8 137 * @return Number of characters appended to the rxCharacteristic.
rgrover1 712:b04b5db36865 138 */
rgrover1 712:b04b5db36865 139 size_t writeString(const char *str) {
rgrover1 712:b04b5db36865 140 return write(str, strlen(str));
rgrover1 712:b04b5db36865 141 }
rgrover1 712:b04b5db36865 142
rgrover1 712:b04b5db36865 143 /**
rgrover1 1001:9977b508cea8 144 * Override for Stream::_putc().
rgrover1 712:b04b5db36865 145 * @param c
rgrover1 712:b04b5db36865 146 * This function writes the character c, cast to an unsigned char, to stream.
rgrover1 712:b04b5db36865 147 * @return
rgrover1 712:b04b5db36865 148 * The character written as an unsigned char cast to an int or EOF on error.
rgrover1 712:b04b5db36865 149 */
rgrover1 712:b04b5db36865 150 int _putc(int c) {
rgrover1 712:b04b5db36865 151 return (write(&c, 1) == 1) ? 1 : EOF;
rgrover1 712:b04b5db36865 152 }
rgrover1 712:b04b5db36865 153
rgrover1 712:b04b5db36865 154 /**
rgrover1 1001:9977b508cea8 155 * Override for Stream::_getc().
rgrover1 712:b04b5db36865 156 * @return
rgrover1 712:b04b5db36865 157 * The character read.
rgrover1 712:b04b5db36865 158 */
rgrover1 712:b04b5db36865 159 int _getc() {
rgrover1 712:b04b5db36865 160 if (receiveBufferIndex == numBytesReceived) {
rgrover1 712:b04b5db36865 161 return EOF;
rgrover1 712:b04b5db36865 162 }
rgrover1 712:b04b5db36865 163
rgrover1 712:b04b5db36865 164 return receiveBuffer[receiveBufferIndex++];
rgrover1 712:b04b5db36865 165 }
rgrover1 712:b04b5db36865 166
rgrover1 728:997ba5e7b3b6 167 protected:
rgrover1 712:b04b5db36865 168 /**
rgrover1 712:b04b5db36865 169 * This callback allows the UART service to receive updates to the
rgrover1 712:b04b5db36865 170 * txCharacteristic. The application should forward the call to this
rgrover1 1001:9977b508cea8 171 * function from the global onDataWritten() callback handler; if that's
rgrover1 712:b04b5db36865 172 * not used, this method can be used as a callback directly.
rgrover1 712:b04b5db36865 173 */
rgrover1 712:b04b5db36865 174 void onDataWritten(const GattWriteCallbackParams *params) {
rgrover1 712:b04b5db36865 175 if (params->handle == getTXCharacteristicHandle()) {
rgrover1 712:b04b5db36865 176 uint16_t bytesRead = params->len;
rgrover1 712:b04b5db36865 177 if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) {
rgrover1 712:b04b5db36865 178 numBytesReceived = bytesRead;
rgrover1 712:b04b5db36865 179 receiveBufferIndex = 0;
rgrover1 712:b04b5db36865 180 memcpy(receiveBuffer, params->data, numBytesReceived);
rgrover1 712:b04b5db36865 181 }
rgrover1 712:b04b5db36865 182 }
rgrover1 712:b04b5db36865 183 }
rgrover1 712:b04b5db36865 184
rgrover1 728:997ba5e7b3b6 185 protected:
rgrover1 712:b04b5db36865 186 BLE &ble;
rgrover1 712:b04b5db36865 187
rgrover1 712:b04b5db36865 188 uint8_t receiveBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which we receive
rgrover1 712:b04b5db36865 189 * inbound data before forwarding it to the
rgrover1 712:b04b5db36865 190 * application. */
rgrover1 712:b04b5db36865 191
rgrover1 712:b04b5db36865 192 uint8_t sendBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which outbound data is
rgrover1 712:b04b5db36865 193 * accumulated before being pushed to the
rgrover1 712:b04b5db36865 194 * rxCharacteristic. */
rgrover1 712:b04b5db36865 195 uint8_t sendBufferIndex;
rgrover1 712:b04b5db36865 196 uint8_t numBytesReceived;
rgrover1 712:b04b5db36865 197 uint8_t receiveBufferIndex;
rgrover1 712:b04b5db36865 198
rgrover1 712:b04b5db36865 199 GattCharacteristic txCharacteristic; /**< From the point of view of the external client, this is the characteristic
rgrover1 712:b04b5db36865 200 * they'd write into in order to communicate with this application. */
rgrover1 712:b04b5db36865 201 GattCharacteristic rxCharacteristic; /**< From the point of view of the external client, this is the characteristic
rgrover1 712:b04b5db36865 202 * they'd read from in order to receive the bytes transmitted by this
rgrover1 712:b04b5db36865 203 * application. */
rgrover1 712:b04b5db36865 204 };
rgrover1 712:b04b5db36865 205
rgrover1 712:b04b5db36865 206 #endif /* #ifndef __BLE_UART_SERVICE_H__*/