![](/media/cache/profiles/f0fcf351df4eb6786e9bb6fc4e2dee02.jpg.50x50_q85.jpg)
BLE Client UART function
This is a BLE Client (Central) program for nRF51.
You can communicate with mbed BLE using "BLE_Uart_Server" program as follows.
/users/kenjiArai/code/BLE_Uart_Server/
Please refer following my notebook.
/users/kenjiArai/notebook/ble-client-and-peripheral-using-switch-sience-ty51/#
main.cpp@3:9236f8e65c80, 2017-10-22 (annotated)
- Committer:
- kenjiArai
- Date:
- Sun Oct 22 09:45:44 2017 +0000
- Revision:
- 3:9236f8e65c80
- Parent:
- 2:6fb0b87b041d
- Child:
- 4:342b665fb826
Run on Mbed-os5. Extend pc serial buffer. Delete low power related lib.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:0ef6455cbb4d | 1 | /* |
kenjiArai | 3:9236f8e65c80 | 2 | * ------- BLE Central/Client UART function ----------------------------------- |
kenjiArai | 3:9236f8e65c80 | 3 | * communicate with BLE_UART_Server program |
kenjiArai | 0:0ef6455cbb4d | 4 | * --- Tested on Switch Science mbed TY51822r3 --- |
kenjiArai | 0:0ef6455cbb4d | 5 | * |
kenjiArai | 0:0ef6455cbb4d | 6 | * Modified by Kenji Arai |
kenjiArai | 0:0ef6455cbb4d | 7 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:0ef6455cbb4d | 8 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 0:0ef6455cbb4d | 9 | * |
kenjiArai | 0:0ef6455cbb4d | 10 | * Started: April 8th, 2016 |
kenjiArai | 2:6fb0b87b041d | 11 | * Revised: June 13th, 2016 |
kenjiArai | 3:9236f8e65c80 | 12 | * Revised: October 22nd, 2017 Run on mbed-OS-5.6.2 |
kenjiArai | 0:0ef6455cbb4d | 13 | * |
kenjiArai | 0:0ef6455cbb4d | 14 | * Original program (see original.cpp file): |
kenjiArai | 0:0ef6455cbb4d | 15 | * S130 potential unstability case [closed] by Fabien Comte |
kenjiArai | 3:9236f8e65c80 | 16 | * https://devzone.nordicsemi.com/question/49705/ |
kenjiArai | 3:9236f8e65c80 | 17 | * s130-potential-unstability-case/ |
kenjiArai | 0:0ef6455cbb4d | 18 | * GitHub Q&A by Fabien COMTE |
kenjiArai | 0:0ef6455cbb4d | 19 | * https://github.com/ARMmbed/ble/issues/69 |
kenjiArai | 1:f68a5e55a60e | 20 | * Tested Server Device: |
kenjiArai | 1:f68a5e55a60e | 21 | * BLE_Uart_Server |
kenjiArai | 1:f68a5e55a60e | 22 | * https://developer.mbed.org/users/kenjiArai/code/BLE_Uart_Server/ |
kenjiArai | 0:0ef6455cbb4d | 23 | */ |
kenjiArai | 0:0ef6455cbb4d | 24 | |
kenjiArai | 3:9236f8e65c80 | 25 | // Include -------------------------------------------------------------------- |
kenjiArai | 0:0ef6455cbb4d | 26 | #include "mbed.h" |
kenjiArai | 0:0ef6455cbb4d | 27 | #include "BLE.h" |
kenjiArai | 0:0ef6455cbb4d | 28 | #include "UARTService.h" |
kenjiArai | 0:0ef6455cbb4d | 29 | #include "ble/DiscoveredCharacteristic.h" |
kenjiArai | 0:0ef6455cbb4d | 30 | #include "ble/DiscoveredService.h" |
kenjiArai | 3:9236f8e65c80 | 31 | #include "RingBuffer.h" |
kenjiArai | 0:0ef6455cbb4d | 32 | |
kenjiArai | 3:9236f8e65c80 | 33 | // Definition ----------------------------------------------------------------- |
kenjiArai | 3:9236f8e65c80 | 34 | #define NUM_ONCE 20 |
kenjiArai | 3:9236f8e65c80 | 35 | #define BFSIZE (NUM_ONCE+4) |
kenjiArai | 0:0ef6455cbb4d | 36 | |
kenjiArai | 3:9236f8e65c80 | 37 | //#define USE_DEBUG_MODE |
kenjiArai | 3:9236f8e65c80 | 38 | #ifdef USE_DEBUG_MODE |
kenjiArai | 3:9236f8e65c80 | 39 | #define DBG(...) { pc.printf(__VA_ARGS__); } |
kenjiArai | 0:0ef6455cbb4d | 40 | #else |
kenjiArai | 3:9236f8e65c80 | 41 | #define DBG(...) |
kenjiArai | 2:6fb0b87b041d | 42 | #endif |
kenjiArai | 2:6fb0b87b041d | 43 | |
kenjiArai | 0:0ef6455cbb4d | 44 | #define SOFT_DEVICE_FATHER_HANDLE 3 |
kenjiArai | 0:0ef6455cbb4d | 45 | |
kenjiArai | 3:9236f8e65c80 | 46 | // Object --------------------------------------------------------------------- |
kenjiArai | 3:9236f8e65c80 | 47 | BLE ble; |
kenjiArai | 3:9236f8e65c80 | 48 | DigitalOut alivenessLED(LED1, 1); |
kenjiArai | 3:9236f8e65c80 | 49 | DigitalOut connectedLED(D10, 0); |
kenjiArai | 3:9236f8e65c80 | 50 | Serial pc(USBTX, USBRX, 115200); |
kenjiArai | 3:9236f8e65c80 | 51 | //Serial pc(P0_3, P0_1, 115200); // for another board |
kenjiArai | 3:9236f8e65c80 | 52 | Ticker ticker; |
kenjiArai | 3:9236f8e65c80 | 53 | RingBuffer ser_bf(1536); |
kenjiArai | 3:9236f8e65c80 | 54 | Thread tsk; |
kenjiArai | 0:0ef6455cbb4d | 55 | |
kenjiArai | 3:9236f8e65c80 | 56 | // ROM / Constant data -------------------------------------------------------- |
kenjiArai | 0:0ef6455cbb4d | 57 | #warning "You need to modify below value based on your board." |
kenjiArai | 3:9236f8e65c80 | 58 | const Gap::Address_t mac_board_0 = {0x50, 0x2b, 0xea, 0x14, 0x95, 0xd2}; |
kenjiArai | 3:9236f8e65c80 | 59 | const Gap::Address_t mac_board_1 = {0x59, 0x2c, 0xa8, 0x0e, 0xe2, 0xef}; |
kenjiArai | 2:6fb0b87b041d | 60 | const Gap::Address_t mac_board_2 = {0x0f, 0x72, 0xbf, 0x43, 0xbc, 0xd0}; |
kenjiArai | 3:9236f8e65c80 | 61 | const Gap::Address_t mac_board_3 = {0x83, 0xc9, 0x1a, 0x90, 0xdf, 0xd6}; |
kenjiArai | 3:9236f8e65c80 | 62 | const Gap::Address_t mac_board_4 = {0x43, 0xa4, 0x36, 0x11, 0x5b, 0xeb}; |
kenjiArai | 0:0ef6455cbb4d | 63 | |
kenjiArai | 3:9236f8e65c80 | 64 | // RAM ------------------------------------------------------------------------ |
kenjiArai | 3:9236f8e65c80 | 65 | Gap::Handle_t connectionHandle = 0xFFFF; |
kenjiArai | 0:0ef6455cbb4d | 66 | DiscoveredCharacteristic uartTXCharacteristic; |
kenjiArai | 0:0ef6455cbb4d | 67 | DiscoveredCharacteristic uartRXCharacteristic; |
kenjiArai | 0:0ef6455cbb4d | 68 | bool foundUartRXCharacteristic = false; |
kenjiArai | 3:9236f8e65c80 | 69 | bool connected2server = false; |
kenjiArai | 3:9236f8e65c80 | 70 | bool connection_tx = false; |
kenjiArai | 3:9236f8e65c80 | 71 | bool connection_rx = false; |
kenjiArai | 3:9236f8e65c80 | 72 | UARTService * uartServicePtr = NULL; |
kenjiArai | 0:0ef6455cbb4d | 73 | Gap::Address_t my_mac; |
kenjiArai | 3:9236f8e65c80 | 74 | int my_board_index = -1; |
kenjiArai | 3:9236f8e65c80 | 75 | bool received_uart_dat = false; |
kenjiArai | 3:9236f8e65c80 | 76 | int8_t uart_buffer[BFSIZE]; |
kenjiArai | 3:9236f8e65c80 | 77 | uint8_t uart_bf_len; |
kenjiArai | 3:9236f8e65c80 | 78 | volatile bool rx_isr_busy = false; |
kenjiArai | 0:0ef6455cbb4d | 79 | |
kenjiArai | 3:9236f8e65c80 | 80 | // Function prototypes -------------------------------------------------------- |
kenjiArai | 0:0ef6455cbb4d | 81 | // BLE |
kenjiArai | 3:9236f8e65c80 | 82 | void advertisementCallback(const Gap::AdvertisementCallbackParams_t *); |
kenjiArai | 3:9236f8e65c80 | 83 | void serviceDiscoveryCallback(const DiscoveredService *); |
kenjiArai | 3:9236f8e65c80 | 84 | void characteristicDiscoveryCallback(const DiscoveredCharacteristic *); |
kenjiArai | 3:9236f8e65c80 | 85 | void discoveryTerminationCallback(Gap::Handle_t ); |
kenjiArai | 3:9236f8e65c80 | 86 | void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *); |
kenjiArai | 3:9236f8e65c80 | 87 | void connectionCallback(const Gap::ConnectionCallbackParams_t *); |
kenjiArai | 3:9236f8e65c80 | 88 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *); |
kenjiArai | 0:0ef6455cbb4d | 89 | // Interrupt related |
kenjiArai | 0:0ef6455cbb4d | 90 | void periodicCallback(void); |
kenjiArai | 0:0ef6455cbb4d | 91 | void serialRxCallback(void); |
kenjiArai | 3:9236f8e65c80 | 92 | // serial receiving |
kenjiArai | 3:9236f8e65c80 | 93 | void pc_ser_rx(void); |
kenjiArai | 3:9236f8e65c80 | 94 | void preparation_sending_data(void); |
kenjiArai | 0:0ef6455cbb4d | 95 | // Pre-check |
kenjiArai | 3:9236f8e65c80 | 96 | bool mac_equals(const Gap::Address_t, const Gap::Address_t); |
kenjiArai | 3:9236f8e65c80 | 97 | int get_board_index(const Gap::Address_t); |
kenjiArai | 3:9236f8e65c80 | 98 | void adjust_line(uint8_t *); |
kenjiArai | 0:0ef6455cbb4d | 99 | |
kenjiArai | 3:9236f8e65c80 | 100 | //------------------------------------------------------------------------------ |
kenjiArai | 0:0ef6455cbb4d | 101 | // Control Program |
kenjiArai | 3:9236f8e65c80 | 102 | //------------------------------------------------------------------------------ |
kenjiArai | 3:9236f8e65c80 | 103 | int main(void) |
kenjiArai | 3:9236f8e65c80 | 104 | { |
kenjiArai | 0:0ef6455cbb4d | 105 | alivenessLED = 0; |
kenjiArai | 3:9236f8e65c80 | 106 | pc.attach(&serialRxCallback, Serial::RxIrq); |
kenjiArai | 0:0ef6455cbb4d | 107 | ticker.attach(periodicCallback, 1); |
kenjiArai | 3:9236f8e65c80 | 108 | tsk.start(pc_ser_rx); |
kenjiArai | 3:9236f8e65c80 | 109 | // clear terminal output |
kenjiArai | 3:9236f8e65c80 | 110 | for (int k = 0; k < 5; k++) { pc.printf("\r\n");} |
kenjiArai | 3:9236f8e65c80 | 111 | // opening message |
kenjiArai | 3:9236f8e65c80 | 112 | pc.printf("UART Communication / Client(Central) side\r\n"); |
kenjiArai | 3:9236f8e65c80 | 113 | pc.printf(" need Sever module (run BLE_Uart_Sever program)\r\n"); |
kenjiArai | 3:9236f8e65c80 | 114 | // Mixed role ************************************************************** |
kenjiArai | 0:0ef6455cbb4d | 115 | ble.init(); |
kenjiArai | 0:0ef6455cbb4d | 116 | ble.gap().onConnection(connectionCallback); |
kenjiArai | 0:0ef6455cbb4d | 117 | ble.gap().onDisconnection(disconnectionCallback); |
kenjiArai | 3:9236f8e65c80 | 118 | // Client(Central) role **************************************************** |
kenjiArai | 0:0ef6455cbb4d | 119 | ble.gattClient().onHVX(onReceivedDataFromDeviceCallback); |
kenjiArai | 0:0ef6455cbb4d | 120 | ble.gap().setScanParams(500, 450); |
kenjiArai | 0:0ef6455cbb4d | 121 | ble.gap().startScan(advertisementCallback); |
kenjiArai | 0:0ef6455cbb4d | 122 | while(true) { |
kenjiArai | 1:f68a5e55a60e | 123 | // allow notifications from Server(Peripheral) |
kenjiArai | 3:9236f8e65c80 | 124 | if (foundUartRXCharacteristic && |
kenjiArai | 3:9236f8e65c80 | 125 | !ble.gattClient().isServiceDiscoveryActive()) |
kenjiArai | 3:9236f8e65c80 | 126 | { |
kenjiArai | 3:9236f8e65c80 | 127 | // need to do the following only once |
kenjiArai | 3:9236f8e65c80 | 128 | foundUartRXCharacteristic = false; |
kenjiArai | 0:0ef6455cbb4d | 129 | uint16_t value = BLE_HVX_NOTIFICATION; |
kenjiArai | 0:0ef6455cbb4d | 130 | ble.gattClient().write( |
kenjiArai | 0:0ef6455cbb4d | 131 | GattClient::GATT_OP_WRITE_REQ, |
kenjiArai | 0:0ef6455cbb4d | 132 | connectionHandle, |
kenjiArai | 0:0ef6455cbb4d | 133 | uartRXCharacteristic.getValueHandle() + 1, |
kenjiArai | 0:0ef6455cbb4d | 134 | sizeof(uint16_t), |
kenjiArai | 0:0ef6455cbb4d | 135 | reinterpret_cast<const uint8_t *>(&value) |
kenjiArai | 0:0ef6455cbb4d | 136 | ); |
kenjiArai | 0:0ef6455cbb4d | 137 | } |
kenjiArai | 3:9236f8e65c80 | 138 | if (received_uart_dat == true){ |
kenjiArai | 3:9236f8e65c80 | 139 | received_uart_dat = false; |
kenjiArai | 3:9236f8e65c80 | 140 | for(int i = 0; i < uart_bf_len; i++){ |
kenjiArai | 3:9236f8e65c80 | 141 | //pc.printf("%c", uart_buffer[i]); |
kenjiArai | 3:9236f8e65c80 | 142 | pc.putc(uart_buffer[i]); |
kenjiArai | 0:0ef6455cbb4d | 143 | } |
kenjiArai | 0:0ef6455cbb4d | 144 | } |
kenjiArai | 3:9236f8e65c80 | 145 | ble.waitForEvent(); |
kenjiArai | 3:9236f8e65c80 | 146 | } |
kenjiArai | 3:9236f8e65c80 | 147 | } |
kenjiArai | 3:9236f8e65c80 | 148 | |
kenjiArai | 3:9236f8e65c80 | 149 | void periodicCallback(void) |
kenjiArai | 3:9236f8e65c80 | 150 | { |
kenjiArai | 3:9236f8e65c80 | 151 | // Do blinky on alivenessLED to indicate system aliveness |
kenjiArai | 3:9236f8e65c80 | 152 | alivenessLED = !alivenessLED; |
kenjiArai | 3:9236f8e65c80 | 153 | if (connected2server){ |
kenjiArai | 3:9236f8e65c80 | 154 | connectedLED = 1; |
kenjiArai | 3:9236f8e65c80 | 155 | } else { |
kenjiArai | 3:9236f8e65c80 | 156 | connectedLED = 0; |
kenjiArai | 3:9236f8e65c80 | 157 | } |
kenjiArai | 3:9236f8e65c80 | 158 | if (rx_isr_busy == true){ |
kenjiArai | 3:9236f8e65c80 | 159 | rx_isr_busy = false; |
kenjiArai | 3:9236f8e65c80 | 160 | } else { |
kenjiArai | 3:9236f8e65c80 | 161 | tsk.signal_set(0x01); |
kenjiArai | 0:0ef6455cbb4d | 162 | } |
kenjiArai | 0:0ef6455cbb4d | 163 | } |
kenjiArai | 0:0ef6455cbb4d | 164 | |
kenjiArai | 3:9236f8e65c80 | 165 | void serialRxCallback() |
kenjiArai | 3:9236f8e65c80 | 166 | { |
kenjiArai | 3:9236f8e65c80 | 167 | ser_bf.save(pc.getc()); |
kenjiArai | 3:9236f8e65c80 | 168 | rx_isr_busy = true; |
kenjiArai | 3:9236f8e65c80 | 169 | tsk.signal_set(0x01); |
kenjiArai | 0:0ef6455cbb4d | 170 | } |
kenjiArai | 0:0ef6455cbb4d | 171 | |
kenjiArai | 3:9236f8e65c80 | 172 | void pc_ser_rx() |
kenjiArai | 3:9236f8e65c80 | 173 | { |
kenjiArai | 3:9236f8e65c80 | 174 | static uint8_t linebf_irq[BFSIZE]; |
kenjiArai | 3:9236f8e65c80 | 175 | static volatile uint8_t linebf_irq_len = 0; |
kenjiArai | 0:0ef6455cbb4d | 176 | |
kenjiArai | 3:9236f8e65c80 | 177 | while(true){ |
kenjiArai | 3:9236f8e65c80 | 178 | Thread::signal_wait(0x01); |
kenjiArai | 3:9236f8e65c80 | 179 | if (ser_bf.check() == 0){ |
kenjiArai | 3:9236f8e65c80 | 180 | if (linebf_irq_len != 0){ |
kenjiArai | 3:9236f8e65c80 | 181 | linebf_irq[linebf_irq_len] = 0; |
kenjiArai | 3:9236f8e65c80 | 182 | adjust_line(linebf_irq); |
kenjiArai | 3:9236f8e65c80 | 183 | linebf_irq_len = 0; |
kenjiArai | 3:9236f8e65c80 | 184 | uartTXCharacteristic.write(NUM_ONCE, linebf_irq); |
kenjiArai | 3:9236f8e65c80 | 185 | } |
kenjiArai | 0:0ef6455cbb4d | 186 | } |
kenjiArai | 3:9236f8e65c80 | 187 | while(ser_bf.check() != 0){ |
kenjiArai | 3:9236f8e65c80 | 188 | char c = ser_bf.read(); |
kenjiArai | 3:9236f8e65c80 | 189 | if (c == '\b'){ |
kenjiArai | 3:9236f8e65c80 | 190 | linebf_irq_len--; |
kenjiArai | 3:9236f8e65c80 | 191 | pc.putc(c); |
kenjiArai | 3:9236f8e65c80 | 192 | pc.putc(' '); |
kenjiArai | 3:9236f8e65c80 | 193 | pc.putc(c); |
kenjiArai | 3:9236f8e65c80 | 194 | } else if ((c >= ' ') || (c == '\r') || (c == '\n')){ |
kenjiArai | 3:9236f8e65c80 | 195 | bool overflow = false; |
kenjiArai | 3:9236f8e65c80 | 196 | if ((c == '\r') || (c == '\n')) { |
kenjiArai | 3:9236f8e65c80 | 197 | if (linebf_irq_len == NUM_ONCE - 1){// remain only 1 buffer |
kenjiArai | 3:9236f8e65c80 | 198 | overflow = true; |
kenjiArai | 3:9236f8e65c80 | 199 | linebf_irq[linebf_irq_len++] = '\r'; |
kenjiArai | 3:9236f8e65c80 | 200 | pc.putc('\r'); |
kenjiArai | 3:9236f8e65c80 | 201 | } else { |
kenjiArai | 3:9236f8e65c80 | 202 | overflow = false; |
kenjiArai | 3:9236f8e65c80 | 203 | linebf_irq[linebf_irq_len++] = '\r'; |
kenjiArai | 3:9236f8e65c80 | 204 | linebf_irq[linebf_irq_len++] = '\n'; |
kenjiArai | 3:9236f8e65c80 | 205 | pc.printf("\r\n"); |
kenjiArai | 3:9236f8e65c80 | 206 | } |
kenjiArai | 3:9236f8e65c80 | 207 | } else { |
kenjiArai | 3:9236f8e65c80 | 208 | linebf_irq[linebf_irq_len++] = c; |
kenjiArai | 3:9236f8e65c80 | 209 | pc.putc(c); |
kenjiArai | 3:9236f8e65c80 | 210 | } |
kenjiArai | 3:9236f8e65c80 | 211 | if (linebf_irq_len >= NUM_ONCE ){ |
kenjiArai | 3:9236f8e65c80 | 212 | linebf_irq[linebf_irq_len] = 0; |
kenjiArai | 3:9236f8e65c80 | 213 | uartTXCharacteristic.write(linebf_irq_len, linebf_irq); |
kenjiArai | 3:9236f8e65c80 | 214 | linebf_irq_len = 0; |
kenjiArai | 3:9236f8e65c80 | 215 | if (overflow == true){ |
kenjiArai | 3:9236f8e65c80 | 216 | overflow = false; |
kenjiArai | 3:9236f8e65c80 | 217 | linebf_irq[linebf_irq_len++] = '\n'; |
kenjiArai | 3:9236f8e65c80 | 218 | pc.putc('\n'); |
kenjiArai | 3:9236f8e65c80 | 219 | } |
kenjiArai | 3:9236f8e65c80 | 220 | } |
kenjiArai | 3:9236f8e65c80 | 221 | } |
kenjiArai | 0:0ef6455cbb4d | 222 | } |
kenjiArai | 0:0ef6455cbb4d | 223 | } |
kenjiArai | 0:0ef6455cbb4d | 224 | } |
kenjiArai | 0:0ef6455cbb4d | 225 | |
kenjiArai | 3:9236f8e65c80 | 226 | void adjust_line(uint8_t *bf) |
kenjiArai | 3:9236f8e65c80 | 227 | { |
kenjiArai | 3:9236f8e65c80 | 228 | uint8_t i, c; |
kenjiArai | 3:9236f8e65c80 | 229 | |
kenjiArai | 3:9236f8e65c80 | 230 | for (i = 0; i <NUM_ONCE; bf++, i++){ |
kenjiArai | 3:9236f8e65c80 | 231 | c = *bf; |
kenjiArai | 3:9236f8e65c80 | 232 | if (c == 0){ break;} |
kenjiArai | 3:9236f8e65c80 | 233 | } |
kenjiArai | 3:9236f8e65c80 | 234 | for (; i < NUM_ONCE; bf++, i++){ *bf = 0x11;} |
kenjiArai | 3:9236f8e65c80 | 235 | *(bf + 1) = 0; |
kenjiArai | 3:9236f8e65c80 | 236 | } |
kenjiArai | 3:9236f8e65c80 | 237 | |
kenjiArai | 3:9236f8e65c80 | 238 | void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *params) |
kenjiArai | 3:9236f8e65c80 | 239 | { |
kenjiArai | 3:9236f8e65c80 | 240 | DBG( |
kenjiArai | 0:0ef6455cbb4d | 241 | "received HVX callback for handle %u; type %s\r\r\n", |
kenjiArai | 0:0ef6455cbb4d | 242 | params->handle, |
kenjiArai | 0:0ef6455cbb4d | 243 | (params->type == BLE_HVX_NOTIFICATION) ? "notification" : "indication" |
kenjiArai | 0:0ef6455cbb4d | 244 | ); |
kenjiArai | 0:0ef6455cbb4d | 245 | if (params->type == BLE_HVX_NOTIFICATION){ |
kenjiArai | 0:0ef6455cbb4d | 246 | if ((params->handle |
kenjiArai | 0:0ef6455cbb4d | 247 | == uartRXCharacteristic.getValueHandle()) && (params->len > 0)) |
kenjiArai | 0:0ef6455cbb4d | 248 | { |
kenjiArai | 3:9236f8e65c80 | 249 | uart_bf_len = params->len; |
kenjiArai | 3:9236f8e65c80 | 250 | strcpy((char *)uart_buffer, (char *)params->data); |
kenjiArai | 3:9236f8e65c80 | 251 | received_uart_dat = true; |
kenjiArai | 0:0ef6455cbb4d | 252 | } |
kenjiArai | 0:0ef6455cbb4d | 253 | } |
kenjiArai | 0:0ef6455cbb4d | 254 | } |
kenjiArai | 0:0ef6455cbb4d | 255 | |
kenjiArai | 3:9236f8e65c80 | 256 | bool mac_equals(const Gap::Address_t mac_1, const Gap::Address_t mac_2) |
kenjiArai | 3:9236f8e65c80 | 257 | { |
kenjiArai | 3:9236f8e65c80 | 258 | DBG("Address: "); |
kenjiArai | 3:9236f8e65c80 | 259 | for (int i = 0; i < 6; i++){ |
kenjiArai | 3:9236f8e65c80 | 260 | DBG("0x%02x ", mac_1[i]); |
kenjiArai | 0:0ef6455cbb4d | 261 | } |
kenjiArai | 3:9236f8e65c80 | 262 | DBG("\r\n"); |
kenjiArai | 0:0ef6455cbb4d | 263 | for (int i = 0; i < 6; i++){ |
kenjiArai | 0:0ef6455cbb4d | 264 | if (mac_1[i] != mac_2[i]){ |
kenjiArai | 3:9236f8e65c80 | 265 | DBG("0x%02x != 0x%02x at %d\r\n", mac_1[i], mac_2[i], i); |
kenjiArai | 0:0ef6455cbb4d | 266 | return false; |
kenjiArai | 0:0ef6455cbb4d | 267 | } else { |
kenjiArai | 3:9236f8e65c80 | 268 | DBG("0x%02x == 0x%02x at %d\r\n", mac_1[i], mac_2[i], i); |
kenjiArai | 0:0ef6455cbb4d | 269 | } |
kenjiArai | 0:0ef6455cbb4d | 270 | } |
kenjiArai | 0:0ef6455cbb4d | 271 | return true; |
kenjiArai | 0:0ef6455cbb4d | 272 | } |
kenjiArai | 0:0ef6455cbb4d | 273 | |
kenjiArai | 3:9236f8e65c80 | 274 | int get_board_index(const Gap::Address_t mac) |
kenjiArai | 3:9236f8e65c80 | 275 | { |
kenjiArai | 3:9236f8e65c80 | 276 | if (mac_equals(mac, mac_board_0)) { return 0;} |
kenjiArai | 3:9236f8e65c80 | 277 | if (mac_equals(mac, mac_board_1)) { return 1;} |
kenjiArai | 3:9236f8e65c80 | 278 | if (mac_equals(mac, mac_board_2)) { return 2;} |
kenjiArai | 3:9236f8e65c80 | 279 | if (mac_equals(mac, mac_board_3)) { return 3;} |
kenjiArai | 3:9236f8e65c80 | 280 | if (mac_equals(mac, mac_board_4)) { return 4;} |
kenjiArai | 0:0ef6455cbb4d | 281 | return -1; |
kenjiArai | 0:0ef6455cbb4d | 282 | } |
kenjiArai | 0:0ef6455cbb4d | 283 | |
kenjiArai | 3:9236f8e65c80 | 284 | // Client(Central) role ******************************************************** |
kenjiArai | 3:9236f8e65c80 | 285 | void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) |
kenjiArai | 3:9236f8e65c80 | 286 | { |
kenjiArai | 0:0ef6455cbb4d | 287 | // connections |
kenjiArai | 0:0ef6455cbb4d | 288 | int peer_board_index = get_board_index(params->peerAddr); |
kenjiArai | 0:0ef6455cbb4d | 289 | if (peer_board_index != -1){ |
kenjiArai | 3:9236f8e65c80 | 290 | pc.printf(""); |
kenjiArai | 3:9236f8e65c80 | 291 | pc.printf( |
kenjiArai | 3:9236f8e65c80 | 292 | "adv peerAddr [%02x %02x %02x %02x %02x %02x]\r\n", |
kenjiArai | 0:0ef6455cbb4d | 293 | params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], |
kenjiArai | 3:9236f8e65c80 | 294 | params->peerAddr[2], params->peerAddr[1], params->peerAddr[0] |
kenjiArai | 0:0ef6455cbb4d | 295 | ); |
kenjiArai | 3:9236f8e65c80 | 296 | pc.printf( |
kenjiArai | 3:9236f8e65c80 | 297 | "rssi=%+4d, isScanResponse %u, AdvertisementType %u\r\n", |
kenjiArai | 3:9236f8e65c80 | 298 | params->rssi, params->isScanResponse, params->type |
kenjiArai | 3:9236f8e65c80 | 299 | ); |
kenjiArai | 3:9236f8e65c80 | 300 | ble.gap().connect( |
kenjiArai | 3:9236f8e65c80 | 301 | params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); |
kenjiArai | 0:0ef6455cbb4d | 302 | } |
kenjiArai | 0:0ef6455cbb4d | 303 | } |
kenjiArai | 0:0ef6455cbb4d | 304 | |
kenjiArai | 3:9236f8e65c80 | 305 | void serviceDiscoveryCallback(const DiscoveredService *service) |
kenjiArai | 3:9236f8e65c80 | 306 | { |
kenjiArai | 3:9236f8e65c80 | 307 | DBG("service found...\r\n"); |
kenjiArai | 3:9236f8e65c80 | 308 | if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT){ |
kenjiArai | 3:9236f8e65c80 | 309 | DBG( |
kenjiArai | 0:0ef6455cbb4d | 310 | "Service UUID-%x attrs[%u %u]\r\n", |
kenjiArai | 0:0ef6455cbb4d | 311 | service->getUUID().getShortUUID(), |
kenjiArai | 0:0ef6455cbb4d | 312 | service->getStartHandle(), |
kenjiArai | 0:0ef6455cbb4d | 313 | service->getEndHandle() |
kenjiArai | 0:0ef6455cbb4d | 314 | ); |
kenjiArai | 0:0ef6455cbb4d | 315 | } else { |
kenjiArai | 3:9236f8e65c80 | 316 | DBG("Service UUID-"); |
kenjiArai | 0:0ef6455cbb4d | 317 | const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); |
kenjiArai | 0:0ef6455cbb4d | 318 | for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { |
kenjiArai | 3:9236f8e65c80 | 319 | DBG("%02x", longUUIDBytes[i]); |
kenjiArai | 0:0ef6455cbb4d | 320 | } |
kenjiArai | 3:9236f8e65c80 | 321 | DBG(" attrs[%u %u]\r\n", |
kenjiArai | 3:9236f8e65c80 | 322 | service->getStartHandle(), service->getEndHandle()); |
kenjiArai | 0:0ef6455cbb4d | 323 | } |
kenjiArai | 0:0ef6455cbb4d | 324 | } |
kenjiArai | 0:0ef6455cbb4d | 325 | |
kenjiArai | 3:9236f8e65c80 | 326 | void characteristicDiscoveryCallback( |
kenjiArai | 3:9236f8e65c80 | 327 | const DiscoveredCharacteristic *characteristicP) |
kenjiArai | 3:9236f8e65c80 | 328 | { |
kenjiArai | 3:9236f8e65c80 | 329 | DBG( |
kenjiArai | 0:0ef6455cbb4d | 330 | " C UUID-%x valueAttr[%u] props[%x]\r\n", |
kenjiArai | 0:0ef6455cbb4d | 331 | characteristicP->getUUID().getShortUUID(), |
kenjiArai | 0:0ef6455cbb4d | 332 | characteristicP->getValueHandle(), |
kenjiArai | 0:0ef6455cbb4d | 333 | (uint8_t)characteristicP->getProperties().broadcast() |
kenjiArai | 0:0ef6455cbb4d | 334 | ); |
kenjiArai | 0:0ef6455cbb4d | 335 | if (characteristicP->getUUID().getShortUUID() |
kenjiArai | 0:0ef6455cbb4d | 336 | == UARTServiceTXCharacteristicShortUUID) |
kenjiArai | 0:0ef6455cbb4d | 337 | { |
kenjiArai | 3:9236f8e65c80 | 338 | DBG("Sevice TX 0x%04x\r\n", UARTServiceTXCharacteristicShortUUID); |
kenjiArai | 0:0ef6455cbb4d | 339 | uartTXCharacteristic = *characteristicP; |
kenjiArai | 2:6fb0b87b041d | 340 | connection_tx = true; |
kenjiArai | 0:0ef6455cbb4d | 341 | } else if (characteristicP->getUUID().getShortUUID() |
kenjiArai | 0:0ef6455cbb4d | 342 | == UARTServiceRXCharacteristicShortUUID) |
kenjiArai | 0:0ef6455cbb4d | 343 | { |
kenjiArai | 3:9236f8e65c80 | 344 | DBG("Sevice RX 0x%04x\r\n", UARTServiceRXCharacteristicShortUUID); |
kenjiArai | 0:0ef6455cbb4d | 345 | uartRXCharacteristic = *characteristicP; |
kenjiArai | 0:0ef6455cbb4d | 346 | foundUartRXCharacteristic = true; |
kenjiArai | 2:6fb0b87b041d | 347 | connection_rx = true; |
kenjiArai | 0:0ef6455cbb4d | 348 | } |
kenjiArai | 0:0ef6455cbb4d | 349 | } |
kenjiArai | 0:0ef6455cbb4d | 350 | |
kenjiArai | 3:9236f8e65c80 | 351 | void discoveryTerminationCallback(Gap::Handle_t connectionHandle) |
kenjiArai | 3:9236f8e65c80 | 352 | { |
kenjiArai | 3:9236f8e65c80 | 353 | DBG("terminated SD for handle=%u\r\n", connectionHandle); |
kenjiArai | 0:0ef6455cbb4d | 354 | } |
kenjiArai | 0:0ef6455cbb4d | 355 | |
kenjiArai | 3:9236f8e65c80 | 356 | // Mixed role ****************************************************************** |
kenjiArai | 3:9236f8e65c80 | 357 | void connectionCallback(const Gap::ConnectionCallbackParams_t *params) |
kenjiArai | 3:9236f8e65c80 | 358 | { |
kenjiArai | 0:0ef6455cbb4d | 359 | if (params->role == Gap::CENTRAL) { |
kenjiArai | 3:9236f8e65c80 | 360 | pc.printf("connected as Client(Central) (handle = %d)\r\n\r", |
kenjiArai | 3:9236f8e65c80 | 361 | params->handle); |
kenjiArai | 1:f68a5e55a60e | 362 | connected2server = true; |
kenjiArai | 0:0ef6455cbb4d | 363 | connectionHandle = params->handle; |
kenjiArai | 3:9236f8e65c80 | 364 | ble.gattClient().onServiceDiscoveryTermination( |
kenjiArai | 3:9236f8e65c80 | 365 | discoveryTerminationCallback); |
kenjiArai | 0:0ef6455cbb4d | 366 | ble.gattClient().launchServiceDiscovery( |
kenjiArai | 0:0ef6455cbb4d | 367 | params->handle, |
kenjiArai | 0:0ef6455cbb4d | 368 | serviceDiscoveryCallback, |
kenjiArai | 3:9236f8e65c80 | 369 | characteristicDiscoveryCallback |
kenjiArai | 0:0ef6455cbb4d | 370 | ); |
kenjiArai | 0:0ef6455cbb4d | 371 | } |
kenjiArai | 3:9236f8e65c80 | 372 | pc.printf( |
kenjiArai | 3:9236f8e65c80 | 373 | "Client(Central/Myself) %02x:%02x:%02x:%02x:%02x:%02x\r\n", |
kenjiArai | 0:0ef6455cbb4d | 374 | params->ownAddr[5], params->ownAddr[4], params->ownAddr[3], |
kenjiArai | 3:9236f8e65c80 | 375 | params->ownAddr[2], params->ownAddr[1], params->ownAddr[0] |
kenjiArai | 3:9236f8e65c80 | 376 | ); |
kenjiArai | 3:9236f8e65c80 | 377 | pc.printf( |
kenjiArai | 3:9236f8e65c80 | 378 | "Connected Sever(peripheral) %02x:%02x:%02x:%02x:%02x:%02x\r\n", |
kenjiArai | 0:0ef6455cbb4d | 379 | params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], |
kenjiArai | 3:9236f8e65c80 | 380 | params->peerAddr[2], params->peerAddr[1], params->peerAddr[0] |
kenjiArai | 0:0ef6455cbb4d | 381 | ); |
kenjiArai | 0:0ef6455cbb4d | 382 | } |
kenjiArai | 0:0ef6455cbb4d | 383 | |
kenjiArai | 3:9236f8e65c80 | 384 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
kenjiArai | 3:9236f8e65c80 | 385 | { |
kenjiArai | 3:9236f8e65c80 | 386 | DBG("handle = %d ", params->handle); |
kenjiArai | 3:9236f8e65c80 | 387 | pc.printf(" -> disconnected\r\n", params->handle); |
kenjiArai | 1:f68a5e55a60e | 388 | connected2server = false; |
kenjiArai | 3:9236f8e65c80 | 389 | // connection_1st = false; |
kenjiArai | 2:6fb0b87b041d | 390 | connection_tx = false; |
kenjiArai | 2:6fb0b87b041d | 391 | connection_rx = false; |
kenjiArai | 0:0ef6455cbb4d | 392 | if (params->handle == SOFT_DEVICE_FATHER_HANDLE) { |
kenjiArai | 0:0ef6455cbb4d | 393 | ble.startAdvertising(); // restart advertising |
kenjiArai | 0:0ef6455cbb4d | 394 | } else { |
kenjiArai | 0:0ef6455cbb4d | 395 | ble.gap().startScan(advertisementCallback); // restart scan |
kenjiArai | 0:0ef6455cbb4d | 396 | } |
kenjiArai | 0:0ef6455cbb4d | 397 | } |