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