Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
UARTService.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __BLE_UART_SERVICE_H__ 00018 #define __BLE_UART_SERVICE_H__ 00019 00020 #ifdef YOTTA_CFG_MBED_OS 00021 #include "mbed-drivers/mbed.h" 00022 #include "mbed-drivers/Stream.h" 00023 #else 00024 #include "mbed.h" 00025 #include "Stream.h" 00026 #endif 00027 00028 #include "ble/UUID.h " 00029 #include "ble/BLE.h" 00030 00031 extern const uint8_t UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID]; 00032 extern const uint16_t UARTServiceShortUUID; 00033 extern const uint16_t UARTServiceTXCharacteristicShortUUID; 00034 extern const uint16_t UARTServiceRXCharacteristicShortUUID; 00035 00036 extern const uint8_t UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID]; 00037 extern const uint8_t UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID]; 00038 00039 extern const uint8_t UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; 00040 extern const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; 00041 00042 /** 00043 * @class UARTService. 00044 * @brief BLE Service to enable UART over BLE. 00045 */ 00046 class UARTService { 00047 public: 00048 /** Maximum length of data (in bytes) that the UART service module can transmit to the peer. */ 00049 static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (BLE_GATT_MTU_SIZE_DEFAULT - 3); 00050 00051 public: 00052 00053 /** 00054 * @param _ble 00055 * BLE object for the underlying controller. 00056 */ 00057 UARTService (BLE &_ble) : 00058 ble(_ble), 00059 receiveBuffer(), 00060 sendBuffer(), 00061 sendBufferIndex(0), 00062 numBytesReceived(0), 00063 receiveBufferIndex(0), 00064 txCharacteristic(UARTServiceTXCharacteristicUUID, receiveBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, 00065 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), 00066 rxCharacteristic(UARTServiceRXCharacteristicUUID, sendBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { 00067 GattCharacteristic *charTable[] = {&txCharacteristic, &rxCharacteristic}; 00068 GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00069 00070 ble.addService(uartService); 00071 ble.onDataWritten(this, &UARTService::onDataWritten); 00072 } 00073 00074 /** 00075 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service. 00076 */ 00077 uint16_t getTXCharacteristicHandle() { 00078 return txCharacteristic.getValueAttribute().getHandle(); 00079 } 00080 00081 /** 00082 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service. 00083 */ 00084 uint16_t getRXCharacteristicHandle() { 00085 return rxCharacteristic.getValueAttribute().getHandle(); 00086 } 00087 00088 /** 00089 * We attempt to collect bytes before pushing them to the UART RX 00090 * characteristic; writing to the RX characteristic then generates 00091 * notifications for the client. Updates made in quick succession to a 00092 * notification-generating characteristic result in data being buffered 00093 * in the Bluetooth stack as notifications are sent out. The stack has 00094 * its limits for this buffering - typically a small number under 10. 00095 * Collecting data into the sendBuffer buffer helps mitigate the rate of 00096 * updates. But we shouldn't buffer a large amount of data before updating 00097 * the characteristic, otherwise the client needs to turn around and make 00098 * a long read request; this is because notifications include only the first 00099 * 20 bytes of the updated data. 00100 * 00101 * @param _buffer The received update. 00102 * @param length Number of characters to be appended. 00103 * @return Number of characters appended to the rxCharacteristic. 00104 */ 00105 size_t write(const void *_buffer, size_t length) { 00106 size_t origLength = length; 00107 const uint8_t *buffer = static_cast<const uint8_t *>(_buffer); 00108 00109 if (ble.getGapState().connected) { 00110 unsigned bufferIndex = 0; 00111 while (length) { 00112 unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex; 00113 unsigned bytesToCopy = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer; 00114 00115 /* Copy bytes into sendBuffer. */ 00116 memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy); 00117 length -= bytesToCopy; 00118 sendBufferIndex += bytesToCopy; 00119 bufferIndex += bytesToCopy; 00120 00121 /* Have we collected enough? */ 00122 if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) || 00123 // (sendBuffer[sendBufferIndex - 1] == '\r') || 00124 (sendBuffer[sendBufferIndex - 1] == '\n')) { 00125 ble.gattServer().write(getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex); 00126 sendBufferIndex = 0; 00127 } 00128 } 00129 } 00130 00131 return origLength; 00132 } 00133 00134 /** 00135 * Helper function to write out strings. 00136 * @param str The received string. 00137 * @return Number of characters appended to the rxCharacteristic. 00138 */ 00139 size_t writeString(const char *str) { 00140 return write(str, strlen(str)); 00141 } 00142 00143 /** 00144 * Flush sendBuffer, i.e., forcefully write its contents to the UART RX 00145 * characteristic even if the buffer is not full. 00146 */ 00147 void flush() { 00148 if (ble.getGapState().connected) { 00149 if (sendBufferIndex != 0) { 00150 ble.gattServer().write(getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex); 00151 sendBufferIndex = 0; 00152 } 00153 } 00154 } 00155 00156 /** 00157 * Override for Stream::_putc(). 00158 * @param c 00159 * This function writes the character c, cast to an unsigned char, to stream. 00160 * @return 00161 * The character written as an unsigned char cast to an int or EOF on error. 00162 */ 00163 int _putc(int c) { 00164 return (write(&c, 1) == 1) ? 1 : EOF; 00165 } 00166 00167 /** 00168 * Override for Stream::_getc(). 00169 * @return 00170 * The character read. 00171 */ 00172 int _getc() { 00173 if (receiveBufferIndex == numBytesReceived) { 00174 return EOF; 00175 } 00176 00177 return receiveBuffer[receiveBufferIndex++]; 00178 } 00179 00180 protected: 00181 /** 00182 * This callback allows the UART service to receive updates to the 00183 * txCharacteristic. The application should forward the call to this 00184 * function from the global onDataWritten() callback handler; if that's 00185 * not used, this method can be used as a callback directly. 00186 */ 00187 void onDataWritten(const GattWriteCallbackParams *params) { 00188 if (params->handle == getTXCharacteristicHandle()) { 00189 uint16_t bytesRead = params->len; 00190 if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) { 00191 numBytesReceived = bytesRead; 00192 receiveBufferIndex = 0; 00193 memcpy(receiveBuffer, params->data, numBytesReceived); 00194 } 00195 } 00196 } 00197 00198 protected: 00199 BLE &ble; 00200 00201 uint8_t receiveBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which we receive 00202 * inbound data before forwarding it to the 00203 * application. */ 00204 00205 uint8_t sendBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which outbound data is 00206 * accumulated before being pushed to the 00207 * rxCharacteristic. */ 00208 uint8_t sendBufferIndex; 00209 uint8_t numBytesReceived; 00210 uint8_t receiveBufferIndex; 00211 00212 GattCharacteristic txCharacteristic; /**< From the point of view of the external client, this is the characteristic 00213 * they'd write into in order to communicate with this application. */ 00214 GattCharacteristic rxCharacteristic; /**< From the point of view of the external client, this is the characteristic 00215 * they'd read from in order to receive the bytes transmitted by this 00216 * application. */ 00217 }; 00218 00219 #endif /* #ifndef __BLE_UART_SERVICE_H__*/
Generated on Tue Jul 12 2022 14:25:06 by
