Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 17 23:23:45 2019 +0000
Revision:
0:5b88d5760320
mbed-os5 only for TYBLE16

Who changed what in which revision?

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