Wallbot_CaaS

Dependencies:   MPU6050 mbed PID

Fork of BLE_MPU6050_test6_challenge_sb by Junichi Katsu

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 "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__*/