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.
Fork of Nucleo_BLE_API by
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 #include "Stream.h" 00021 00022 #include "UUID.h" 00023 #include "BLEDevice.h" 00024 00025 extern const uint8_t UARTServiceBaseUUID[LENGTH_OF_LONG_UUID]; 00026 extern const uint16_t UARTServiceShortUUID; 00027 extern const uint16_t UARTServiceTXCharacteristicShortUUID; 00028 extern const uint16_t UARTServiceRXCharacteristicShortUUID; 00029 00030 extern const uint8_t UARTServiceUUID[LENGTH_OF_LONG_UUID]; 00031 extern const uint8_t UARTServiceUUID_reversed[LENGTH_OF_LONG_UUID]; 00032 00033 extern const uint8_t UARTServiceTXCharacteristicUUID[LENGTH_OF_LONG_UUID]; 00034 extern const uint8_t UARTServiceRXCharacteristicUUID[LENGTH_OF_LONG_UUID]; 00035 00036 class UARTService : public Stream { 00037 public: 00038 /**< Maximum length of data (in bytes) that can be transmitted by the UART service module to the peer. */ 00039 static const unsigned GATT_MTU_SIZE_DEFAULT = 23; 00040 static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (GATT_MTU_SIZE_DEFAULT - 3); 00041 00042 public: 00043 UARTService(BLEDevice &_ble) : 00044 Stream("blueart"), 00045 ble(_ble), 00046 receiveBuffer(), 00047 sendBuffer(), 00048 sendBufferIndex(0), 00049 numBytesReceived(0), 00050 receiveBufferIndex(0), 00051 txCharacteristic(UARTServiceTXCharacteristicUUID, receiveBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, 00052 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), 00053 rxCharacteristic(UARTServiceRXCharacteristicUUID, sendBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { 00054 GattCharacteristic *charTable[] = {&txCharacteristic, &rxCharacteristic}; 00055 GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00056 00057 ble.addService(uartService); 00058 ble.onDataWritten(this, &UARTService::onDataWritten); 00059 } 00060 00061 /** 00062 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service. 00063 */ 00064 uint16_t getTXCharacteristicHandle() { 00065 return txCharacteristic.getValueAttribute().getHandle(); 00066 } 00067 00068 /** 00069 * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service. 00070 */ 00071 uint16_t getRXCharacteristicHandle() { 00072 return rxCharacteristic.getValueAttribute().getHandle(); 00073 } 00074 00075 /** 00076 * Following a call to this function, all writes to stdout (such as from 00077 * printf) get redirected to the outbound characteristic of this service. 00078 * This might be very useful when wanting to receive debug messages over BLE. 00079 * 00080 * @Note: debug messages originating from printf() like calls are buffered 00081 * before being sent out. A '\n' in the printf() triggers the buffer update 00082 * to the underlying characteristic. 00083 * 00084 * @Note: long messages need to be chopped up into 20-byte updates so that 00085 * they flow out completely with notifications. The receiver should be 00086 * prepared to stitch these messages back. 00087 */ 00088 void retargetStdout() { 00089 freopen("/blueart", "w", stdout); 00090 } 00091 00092 /** 00093 * This callback allows the UART service to receive updates to the 00094 * txCharacteristic. The application should forward the call to this 00095 * function from the global onDataWritten() callback handler; or if that's 00096 * not used, this method can be used as a callback directly. 00097 */ 00098 virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { 00099 if (params->charHandle == getTXCharacteristicHandle()) { 00100 uint16_t bytesRead = params->len; 00101 if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) { 00102 numBytesReceived = bytesRead; 00103 receiveBufferIndex = 0; 00104 memcpy(receiveBuffer, params->data, numBytesReceived); 00105 } 00106 } 00107 } 00108 00109 /** 00110 * Override for Stream::write(). 00111 * 00112 * We attempt to collect bytes before pushing them to the UART RX 00113 * characteristic--writing to the RX characteristic will then generate 00114 * notifications for the client. Updates made in quick succession to a 00115 * notification-generating characteristic will result in data being buffered 00116 * in the bluetooth stack as notifications are sent out. The stack will have 00117 * its limits for this buffering; typically a small number under 10. 00118 * Collecting data into the sendBuffer buffer helps mitigate the rate of 00119 * updates. But we shouldn't buffer a large amount of data before updating 00120 * the characteristic otherwise the client will need to turn around and make 00121 * a long read request; this is because notifications include only the first 00122 * 20 bytes of the updated data. 00123 * 00124 * @param buffer The received update 00125 * @param length Amount of characters to be appended. 00126 * @return Amount of characters appended to the rxCharacteristic. 00127 */ 00128 virtual ssize_t write(const void* _buffer, size_t length) { 00129 size_t origLength = length; 00130 const uint8_t *buffer = static_cast<const uint8_t *>(_buffer); 00131 00132 if (ble.getGapState().connected) { 00133 unsigned bufferIndex = 0; 00134 while (length) { 00135 unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex; 00136 unsigned bytesToCopy = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer; 00137 00138 /* copy bytes into sendBuffer */ 00139 memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy); 00140 length -= bytesToCopy; 00141 sendBufferIndex += bytesToCopy; 00142 bufferIndex += bytesToCopy; 00143 00144 /* have we collected enough? */ 00145 if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) || 00146 // (sendBuffer[sendBufferIndex - 1] == '\r') || 00147 (sendBuffer[sendBufferIndex - 1] == '\n')) { 00148 ble.updateCharacteristicValue(getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex); 00149 sendBufferIndex = 0; 00150 } 00151 } 00152 } 00153 00154 return origLength; 00155 } 00156 00157 protected: 00158 /** 00159 * Override for Stream::_putc() 00160 * @param c 00161 * This function writes the character c, cast to an unsigned char, to stream. 00162 * @return 00163 * The character written as an unsigned char cast to an int or EOF on error. 00164 */ 00165 virtual int _putc(int c) { 00166 return (write(&c, 1) == 1) ? 1 : EOF; 00167 } 00168 00169 virtual int _getc() { 00170 if (receiveBufferIndex == numBytesReceived) { 00171 return EOF; 00172 } 00173 00174 return receiveBuffer[receiveBufferIndex++]; 00175 } 00176 00177 virtual int isatty() { 00178 return 1; 00179 } 00180 00181 private: 00182 BLEDevice &ble; 00183 00184 uint8_t receiveBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which we receive 00185 * inbound data before forwarding it to the 00186 * application. */ 00187 00188 uint8_t sendBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which outbound data is 00189 * accumulated before being pushed to the 00190 * rxCharacteristic. */ 00191 uint8_t sendBufferIndex; 00192 uint8_t numBytesReceived; 00193 uint8_t receiveBufferIndex; 00194 00195 GattCharacteristic txCharacteristic; /**< From the point of view of the external client, this is the characteristic 00196 * they'd write into in order to communicate with this application. */ 00197 GattCharacteristic rxCharacteristic; /**< From the point of view of the external client, this is the characteristic 00198 * they'd read from in order to receive the bytes transmitted by this 00199 * application. */ 00200 }; 00201 00202 #endif /* #ifndef __BLE_UART_SERVICE_H__*/ 00203
Generated on Tue Jul 12 2022 22:48:24 by
1.7.2
