Yutaka Yoshida / Mbed 2 deprecated BLE_WallbotBLE_Challenge

Dependencies:   mbed

Fork of BLE_WallbotBLE_Challenge by JKSoft

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UARTService.h Source File

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 protected:
00110     /**
00111      * Override for Stream::write().
00112      *
00113      * We attempt to collect bytes before pushing them to the UART RX
00114      * characteristic--writing to the RX characteristic will then generate
00115      * notifications for the client. Updates made in quick succession to a
00116      * notification-generating characteristic will result in data being buffered
00117      * in the bluetooth stack as notifications are sent out. The stack will have
00118      * its limits for this buffering; typically a small number under 10.
00119      * Collecting data into the sendBuffer buffer helps mitigate the rate of
00120      * updates. But we shouldn't buffer a large amount of data before updating
00121      * the characteristic otherwise the client will need to turn around and make
00122      * a long read request; this is because notifications include only the first
00123      * 20 bytes of the updated data.
00124      *
00125      * @param  buffer The received update
00126      * @param  length Amount of characters to be appended.
00127      * @return        Amount of characters appended to the rxCharacteristic.
00128      */
00129     virtual ssize_t write(const void* _buffer, size_t length) {
00130         size_t origLength     = length;
00131         const uint8_t *buffer = static_cast<const uint8_t *>(_buffer);
00132 
00133         if (ble.getGapState().connected) {
00134             unsigned bufferIndex = 0;
00135             while (length) {
00136                 unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex;
00137                 unsigned bytesToCopy = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer;
00138 
00139                 /* copy bytes into sendBuffer */
00140                 memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy);
00141                 length          -= bytesToCopy;
00142                 sendBufferIndex += bytesToCopy;
00143                 bufferIndex     += bytesToCopy;
00144 
00145                 /* have we collected enough? */
00146                 if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) ||
00147                     // (sendBuffer[sendBufferIndex - 1] == '\r')          ||
00148                     (sendBuffer[sendBufferIndex - 1] == '\n')) {
00149                     ble.updateCharacteristicValue (getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex);
00150                     sendBufferIndex = 0;
00151                 }
00152             }
00153         }
00154 
00155         return origLength;
00156     }
00157 
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