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

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.