BLE Client UART function

Dependencies:   RingBuffer

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/#

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?

UserRevisionLine numberNew 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 }