Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:54:50 2016 +0000
Revision:
1:d96dbedaebdb
Parent:
0:6c56fb4bc5f0
Removed extra directories for other platforms

Who changed what in which revision?

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