use UART Service to loopback anything received on the TX characteristic onto the RX.

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Committer:
dragosIQ
Date:
Wed Apr 15 14:00:45 2015 +0000
Revision:
12:bf690d81b1ea
Parent:
10:633cec718bf4
c

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:e910d9bb040f 1 /* mbed Microcontroller Library
yihui 0:e910d9bb040f 2 * Copyright (c) 2006-2013 ARM Limited
yihui 0:e910d9bb040f 3 *
yihui 0:e910d9bb040f 4 * Licensed under the Apache License, Version 2.0 (the "License");
yihui 0:e910d9bb040f 5 * you may not use this file except in compliance with the License.
yihui 0:e910d9bb040f 6 * You may obtain a copy of the License at
yihui 0:e910d9bb040f 7 *
yihui 0:e910d9bb040f 8 * http://www.apache.org/licenses/LICENSE-2.0
yihui 0:e910d9bb040f 9 *
yihui 0:e910d9bb040f 10 * Unless required by applicable law or agreed to in writing, software
yihui 0:e910d9bb040f 11 * distributed under the License is distributed on an "AS IS" BASIS,
yihui 0:e910d9bb040f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
yihui 0:e910d9bb040f 13 * See the License for the specific language governing permissions and
yihui 0:e910d9bb040f 14 * limitations under the License.
yihui 0:e910d9bb040f 15 */
yihui 0:e910d9bb040f 16
yihui 0:e910d9bb040f 17 #include "mbed.h"
Rohit Grover 2:e060367b9024 18 #include "BLEDevice.h"
yihui 0:e910d9bb040f 19
dragosIQ 12:bf690d81b1ea 20 #define BLE_UUID_TXRX_SERVICE 0x0000 /**< The UUID of the Nordic UART Service. */
dragosIQ 12:bf690d81b1ea 21 #define BLE_UUID_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */
dragosIQ 12:bf690d81b1ea 22 #define BLE_UUIDS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */
yihui 0:e910d9bb040f 23
dragosIQ 12:bf690d81b1ea 24 #define TXRX_BUF_LEN 20
dragosIQ 12:bf690d81b1ea 25
yihui 0:e910d9bb040f 26
Rohit Grover 2:e060367b9024 27 BLEDevice ble;
Rohit Grover 2:e060367b9024 28 DigitalOut led1(LED1);
yihui 0:e910d9bb040f 29
dragosIQ 12:bf690d81b1ea 30 // The Nordic UART Service
dragosIQ 12:bf690d81b1ea 31 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
dragosIQ 12:bf690d81b1ea 32 static const uint8_t uart_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
dragosIQ 12:bf690d81b1ea 33 static const uint8_t uart_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
dragosIQ 12:bf690d81b1ea 34 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
dragosIQ 12:bf690d81b1ea 35
dragosIQ 12:bf690d81b1ea 36
dragosIQ 12:bf690d81b1ea 37 uint8_t txPayload[TXRX_BUF_LEN] = {0,};
dragosIQ 12:bf690d81b1ea 38 uint8_t rxPayload[TXRX_BUF_LEN] = {0,};
dragosIQ 12:bf690d81b1ea 39
dragosIQ 12:bf690d81b1ea 40 GattCharacteristic txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN,
dragosIQ 12:bf690d81b1ea 41 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
dragosIQ 12:bf690d81b1ea 42
dragosIQ 12:bf690d81b1ea 43 GattCharacteristic rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN,
dragosIQ 12:bf690d81b1ea 44 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
dragosIQ 12:bf690d81b1ea 45
dragosIQ 12:bf690d81b1ea 46 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
dragosIQ 12:bf690d81b1ea 47
dragosIQ 12:bf690d81b1ea 48 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
dragosIQ 12:bf690d81b1ea 49
yihui 0:e910d9bb040f 50
rgrover1 5:4bc41267a03a 51 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
yihui 0:e910d9bb040f 52 {
Rohit Grover 2:e060367b9024 53 ble.startAdvertising();
Rohit Grover 2:e060367b9024 54 }
yihui 0:e910d9bb040f 55
dragosIQ 12:bf690d81b1ea 56 void onDataWritten(const GattCharacteristicWriteCBParams *Handler)
yihui 0:e910d9bb040f 57 {
dragosIQ 12:bf690d81b1ea 58
dragosIQ 12:bf690d81b1ea 59 uint8_t buf[TXRX_BUF_LEN];
dragosIQ 12:bf690d81b1ea 60 uint16_t bytesRead;
dragosIQ 12:bf690d81b1ea 61
dragosIQ 12:bf690d81b1ea 62 if (Handler->charHandle == txCharacteristic.getValueAttribute().getHandle())
dragosIQ 12:bf690d81b1ea 63 {
dragosIQ 12:bf690d81b1ea 64 ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead);
dragosIQ 12:bf690d81b1ea 65 memset(txPayload, 0, TXRX_BUF_LEN);
dragosIQ 12:bf690d81b1ea 66 memcpy(txPayload, buf, TXRX_BUF_LEN);
dragosIQ 12:bf690d81b1ea 67
dragosIQ 12:bf690d81b1ea 68
yihui 0:e910d9bb040f 69 }
dragosIQ 12:bf690d81b1ea 70
Rohit Grover 2:e060367b9024 71 }
yihui 0:e910d9bb040f 72
dragosIQ 12:bf690d81b1ea 73 void switch_LED(void)
Rohit Grover 2:e060367b9024 74 {
rgrover1 6:e0fc9072e853 75 led1 = !led1;
dragosIQ 12:bf690d81b1ea 76 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), (const uint8_t *)"Salam de Sibiu!\n", sizeof("Salam de Sibiu!\n")-1);
dragosIQ 12:bf690d81b1ea 77
Rohit Grover 2:e060367b9024 78 }
yihui 0:e910d9bb040f 79
yihui 0:e910d9bb040f 80 int main(void)
yihui 0:e910d9bb040f 81 {
dragosIQ 12:bf690d81b1ea 82
Rohit Grover 2:e060367b9024 83 Ticker ticker;
dragosIQ 12:bf690d81b1ea 84 ticker.attach_us(switch_LED, 2000000);
dragosIQ 12:bf690d81b1ea 85
Rohit Grover 2:e060367b9024 86 ble.init();
Rohit Grover 2:e060367b9024 87 ble.onDisconnection(disconnectionCallback);
Rohit Grover 2:e060367b9024 88 ble.onDataWritten(onDataWritten);
yihui 0:e910d9bb040f 89
dragosIQ 12:bf690d81b1ea 90
dragosIQ 12:bf690d81b1ea 91 // setup advertising
Rohit Grover 2:e060367b9024 92 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
Rohit Grover 2:e060367b9024 93 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
Rohit Grover 2:e060367b9024 94 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
dragosIQ 12:bf690d81b1ea 95 (const uint8_t *)"sBeacon", sizeof("sBeacon") - 1);
Rohit Grover 2:e060367b9024 96 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
dragosIQ 12:bf690d81b1ea 97 (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
dragosIQ 12:bf690d81b1ea 98 // 100ms; in multiples of 0.625ms.
rgrover1 10:633cec718bf4 99 ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000));
yihui 0:e910d9bb040f 100
dragosIQ 12:bf690d81b1ea 101 ble.addService(uartService);
dragosIQ 12:bf690d81b1ea 102
dragosIQ 12:bf690d81b1ea 103 ble.startAdvertising();
yihui 0:e910d9bb040f 104
dragosIQ 12:bf690d81b1ea 105 led1 = 1;
dragosIQ 12:bf690d81b1ea 106
Rohit Grover 2:e060367b9024 107 while (true) {
Rohit Grover 2:e060367b9024 108 ble.waitForEvent();
yihui 0:e910d9bb040f 109 }
yihui 0:e910d9bb040f 110 }