TYBLE16 on os5 sample programs

Dependencies:   BME280 TextLCD nRF51_Vdd

Fork of TYBLE16_mbedlized_os5_BASE by Kenji Arai

Please refer following notebook.
/users/kenjiArai/notebook/tyble16-module-as-mbed-os-5-board-mbedlization/

Committer:
kenjiArai
Date:
Sat Apr 14 04:56:34 2018 +0000
Revision:
1:9011c83e4178
added samples

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 1:9011c83e4178 1 /*
kenjiArai 1:9011c83e4178 2 * ------- BLE Central/Client UART function -----------------------------------
kenjiArai 1:9011c83e4178 3 * communicate with BLE_UART_Server program
kenjiArai 1:9011c83e4178 4 * --- Tested on Switch Science mbed TY51822r3 ---
kenjiArai 1:9011c83e4178 5 *
kenjiArai 1:9011c83e4178 6 * Modified by Kenji Arai
kenjiArai 1:9011c83e4178 7 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 1:9011c83e4178 8 * https://os.mbed.com/users/kenjiArai/
kenjiArai 1:9011c83e4178 9 *
kenjiArai 1:9011c83e4178 10 * Started: April 8th, 2016
kenjiArai 1:9011c83e4178 11 * Revised: June 13th, 2016
kenjiArai 1:9011c83e4178 12 * Revised: Feburary 10th, 2018 Not set mac addr but use device name
kenjiArai 1:9011c83e4178 13 * Revised: Feburary 11th, 2018 use mbed-os5.7.4 with CircularBuffer
kenjiArai 1:9011c83e4178 14 * Revised: April 14th, 2018 only for TYBLE16
kenjiArai 1:9011c83e4178 15 *
kenjiArai 1:9011c83e4178 16 * Original program (see original.cpp file):
kenjiArai 1:9011c83e4178 17 * S130 potential unstability case [closed] by Fabien Comte
kenjiArai 1:9011c83e4178 18 * https://devzone.nordicsemi.com/question/49705/
kenjiArai 1:9011c83e4178 19 * s130-potential-unstability-case/
kenjiArai 1:9011c83e4178 20 * GitHub Q&A by Fabien COMTE
kenjiArai 1:9011c83e4178 21 * https://github.com/ARMmbed/ble/issues/69
kenjiArai 1:9011c83e4178 22 * Reference program:
kenjiArai 1:9011c83e4178 23 * BLE_Central_test by noboru koshinaka
kenjiArai 1:9011c83e4178 24 * https://os.mbed.com/users/noboruk/code/BLE_Central_test/
kenjiArai 1:9011c83e4178 25 * Tested Server Device:
kenjiArai 1:9011c83e4178 26 * BLE_Uart_Server
kenjiArai 1:9011c83e4178 27 * https://os.mbed.com/users/kenjiArai/code/BLE_Uart_Server/
kenjiArai 1:9011c83e4178 28 */
kenjiArai 1:9011c83e4178 29
kenjiArai 1:9011c83e4178 30 //#define EXAMPLE_7_UART_CLIENT
kenjiArai 1:9011c83e4178 31 #ifdef EXAMPLE_7_UART_CLIENT
kenjiArai 1:9011c83e4178 32
kenjiArai 1:9011c83e4178 33 // Include --------------------------------------------------------------------
kenjiArai 1:9011c83e4178 34 #include "mbed.h"
kenjiArai 1:9011c83e4178 35 #include "BLE.h"
kenjiArai 1:9011c83e4178 36 #include "DiscoveredCharacteristic.h"
kenjiArai 1:9011c83e4178 37 #include "DiscoveredService.h"
kenjiArai 1:9011c83e4178 38 #include "UARTService.h"
kenjiArai 1:9011c83e4178 39 #include "CircularBuffer.h"
kenjiArai 1:9011c83e4178 40
kenjiArai 1:9011c83e4178 41 // Definition -----------------------------------------------------------------
kenjiArai 1:9011c83e4178 42 //#define USE_MAC // if you use mac address, please define it
kenjiArai 1:9011c83e4178 43
kenjiArai 1:9011c83e4178 44 #define NUM_ONCE 20
kenjiArai 1:9011c83e4178 45 #define BFSIZE (NUM_ONCE+4)
kenjiArai 1:9011c83e4178 46
kenjiArai 1:9011c83e4178 47 //#define USE_DEBUG_MODE
kenjiArai 1:9011c83e4178 48 #ifdef USE_DEBUG_MODE
kenjiArai 1:9011c83e4178 49 #define DBG(...) { pc.printf(__VA_ARGS__); }
kenjiArai 1:9011c83e4178 50 #else
kenjiArai 1:9011c83e4178 51 #define DBG(...)
kenjiArai 1:9011c83e4178 52 #endif
kenjiArai 1:9011c83e4178 53
kenjiArai 1:9011c83e4178 54 #define SOFT_DEVICE_FATHER_HANDLE 3
kenjiArai 1:9011c83e4178 55
kenjiArai 1:9011c83e4178 56 // Object ---------------------------------------------------------------------
kenjiArai 1:9011c83e4178 57 BLE& ble_uart = BLE::Instance();
kenjiArai 1:9011c83e4178 58 DigitalOut alivenessLED(LED1, 1);
kenjiArai 1:9011c83e4178 59 DigitalOut connectedLED(D0, 0);
kenjiArai 1:9011c83e4178 60 Serial pc(USBTX, USBRX, 115200);
kenjiArai 1:9011c83e4178 61 //Serial pc(P0_3, P0_1, 115200); // for another board
kenjiArai 1:9011c83e4178 62 Ticker ticker;
kenjiArai 1:9011c83e4178 63 CircularBuffer<char, 1536> ser_bf;
kenjiArai 1:9011c83e4178 64 Thread tsk;
kenjiArai 1:9011c83e4178 65
kenjiArai 1:9011c83e4178 66 // ROM / Constant data --------------------------------------------------------
kenjiArai 1:9011c83e4178 67 #ifdef USE_MAC
kenjiArai 1:9011c83e4178 68 #warning "You need to modify below value based on your board."
kenjiArai 1:9011c83e4178 69 const Gap::Address_t mac_board_0 = {0x50, 0x2b, 0xea, 0x14, 0x95, 0xd2};
kenjiArai 1:9011c83e4178 70 const Gap::Address_t mac_board_1 = {0x59, 0x2c, 0xa8, 0x0e, 0xe2, 0xef};
kenjiArai 1:9011c83e4178 71 const Gap::Address_t mac_board_2 = {0x0f, 0x72, 0xbf, 0x43, 0xbc, 0xd0};
kenjiArai 1:9011c83e4178 72 const Gap::Address_t mac_board_3 = {0x83, 0xc9, 0x1a, 0x90, 0xdf, 0xd6};
kenjiArai 1:9011c83e4178 73 const Gap::Address_t mac_board_4 = {0x43, 0xa4, 0x36, 0x11, 0x5b, 0xeb};
kenjiArai 1:9011c83e4178 74 #else
kenjiArai 1:9011c83e4178 75 const char PEER_NAME[] = "UART_PJL";
kenjiArai 1:9011c83e4178 76 #endif
kenjiArai 1:9011c83e4178 77
kenjiArai 1:9011c83e4178 78 // RAM ------------------------------------------------------------------------
kenjiArai 1:9011c83e4178 79 Gap::Handle_t connectionHandle = 0xFFFF;
kenjiArai 1:9011c83e4178 80 DiscoveredCharacteristic uartTXCharacteristic;
kenjiArai 1:9011c83e4178 81 DiscoveredCharacteristic uartRXCharacteristic;
kenjiArai 1:9011c83e4178 82 bool foundUartRXCharacteristic = false;
kenjiArai 1:9011c83e4178 83 bool connected2server = false;
kenjiArai 1:9011c83e4178 84 bool connection_tx = false;
kenjiArai 1:9011c83e4178 85 bool connection_rx = false;
kenjiArai 1:9011c83e4178 86 UARTService * uartServicePtr = NULL;
kenjiArai 1:9011c83e4178 87 Gap::Address_t my_mac;
kenjiArai 1:9011c83e4178 88 int my_board_index = -1;
kenjiArai 1:9011c83e4178 89 bool received_uart_dat = false;
kenjiArai 1:9011c83e4178 90 int8_t uart_buffer[BFSIZE];
kenjiArai 1:9011c83e4178 91 uint8_t uart_bf_len;
kenjiArai 1:9011c83e4178 92 volatile bool rx_isr_busy = false;
kenjiArai 1:9011c83e4178 93
kenjiArai 1:9011c83e4178 94 // Function prototypes --------------------------------------------------------
kenjiArai 1:9011c83e4178 95 // BLE
kenjiArai 1:9011c83e4178 96 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *);
kenjiArai 1:9011c83e4178 97 void serviceDiscoveryCallback(const DiscoveredService *);
kenjiArai 1:9011c83e4178 98 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *);
kenjiArai 1:9011c83e4178 99 void discoveryTerminationCallback(Gap::Handle_t );
kenjiArai 1:9011c83e4178 100 void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *);
kenjiArai 1:9011c83e4178 101 void connectionCallback(const Gap::ConnectionCallbackParams_t *);
kenjiArai 1:9011c83e4178 102 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *);
kenjiArai 1:9011c83e4178 103 // Interrupt related
kenjiArai 1:9011c83e4178 104 void periodicCallback(void);
kenjiArai 1:9011c83e4178 105 void serialRxCallback(void);
kenjiArai 1:9011c83e4178 106 // serial receiving
kenjiArai 1:9011c83e4178 107 void pc_ser_rx(void);
kenjiArai 1:9011c83e4178 108 void preparation_sending_data(void);
kenjiArai 1:9011c83e4178 109 // Pre-check
kenjiArai 1:9011c83e4178 110 bool mac_equals(const Gap::Address_t, const Gap::Address_t);
kenjiArai 1:9011c83e4178 111 int get_board_index(const Gap::Address_t);
kenjiArai 1:9011c83e4178 112 void adjust_line(uint8_t *);
kenjiArai 1:9011c83e4178 113
kenjiArai 1:9011c83e4178 114 //------------------------------------------------------------------------------
kenjiArai 1:9011c83e4178 115 // Control Program
kenjiArai 1:9011c83e4178 116 //------------------------------------------------------------------------------
kenjiArai 1:9011c83e4178 117 int main(void)
kenjiArai 1:9011c83e4178 118 {
kenjiArai 1:9011c83e4178 119 alivenessLED = 0;
kenjiArai 1:9011c83e4178 120 pc.attach(&serialRxCallback, Serial::RxIrq);
kenjiArai 1:9011c83e4178 121 ticker.attach(periodicCallback, 1);
kenjiArai 1:9011c83e4178 122 tsk.start(pc_ser_rx);
kenjiArai 1:9011c83e4178 123 // clear terminal output
kenjiArai 1:9011c83e4178 124 for (int k = 0; k < 3; k++) {
kenjiArai 1:9011c83e4178 125 pc.printf("\r\n");
kenjiArai 1:9011c83e4178 126 }
kenjiArai 1:9011c83e4178 127 // opening message
kenjiArai 1:9011c83e4178 128 pc.printf("UART Communication / Client(Central) side\r\n");
kenjiArai 1:9011c83e4178 129 pc.printf(" need Server module (run BLE_Uart_Server program)\r\n");
kenjiArai 1:9011c83e4178 130 // Mixed role **************************************************************
kenjiArai 1:9011c83e4178 131 ble_uart.init();
kenjiArai 1:9011c83e4178 132 ble_uart.gap().onConnection(connectionCallback);
kenjiArai 1:9011c83e4178 133 ble_uart.gap().onDisconnection(disconnectionCallback);
kenjiArai 1:9011c83e4178 134 // Client(Central) role ****************************************************
kenjiArai 1:9011c83e4178 135 ble_uart.gattClient().onHVX(onReceivedDataFromDeviceCallback);
kenjiArai 1:9011c83e4178 136 ble_uart.gap().setScanParams(500, 450);
kenjiArai 1:9011c83e4178 137 ble_uart.gap().startScan(advertisementCallback);
kenjiArai 1:9011c83e4178 138 while(true) {
kenjiArai 1:9011c83e4178 139 // allow notifications from Server(Peripheral)
kenjiArai 1:9011c83e4178 140 if (foundUartRXCharacteristic &&
kenjiArai 1:9011c83e4178 141 !ble_uart.gattClient().isServiceDiscoveryActive()) {
kenjiArai 1:9011c83e4178 142 // need to do the following only once
kenjiArai 1:9011c83e4178 143 foundUartRXCharacteristic = false;
kenjiArai 1:9011c83e4178 144 uint16_t value = BLE_HVX_NOTIFICATION;
kenjiArai 1:9011c83e4178 145 ble_uart.gattClient().write(
kenjiArai 1:9011c83e4178 146 GattClient::GATT_OP_WRITE_REQ,
kenjiArai 1:9011c83e4178 147 connectionHandle,
kenjiArai 1:9011c83e4178 148 uartRXCharacteristic.getValueHandle() + 1,
kenjiArai 1:9011c83e4178 149 sizeof(uint16_t),
kenjiArai 1:9011c83e4178 150 reinterpret_cast<const uint8_t *>(&value)
kenjiArai 1:9011c83e4178 151 );
kenjiArai 1:9011c83e4178 152 }
kenjiArai 1:9011c83e4178 153 if (received_uart_dat == true) {
kenjiArai 1:9011c83e4178 154 received_uart_dat = false;
kenjiArai 1:9011c83e4178 155 for(int i = 0; i < uart_bf_len; i++) {
kenjiArai 1:9011c83e4178 156 //pc.printf("%c", uart_buffer[i]);
kenjiArai 1:9011c83e4178 157 pc.putc(uart_buffer[i]);
kenjiArai 1:9011c83e4178 158 }
kenjiArai 1:9011c83e4178 159 }
kenjiArai 1:9011c83e4178 160 ble_uart.waitForEvent();
kenjiArai 1:9011c83e4178 161 }
kenjiArai 1:9011c83e4178 162 }
kenjiArai 1:9011c83e4178 163
kenjiArai 1:9011c83e4178 164 void periodicCallback(void)
kenjiArai 1:9011c83e4178 165 {
kenjiArai 1:9011c83e4178 166 // Do blinky on alivenessLED to indicate system aliveness
kenjiArai 1:9011c83e4178 167 alivenessLED = !alivenessLED;
kenjiArai 1:9011c83e4178 168 if (connected2server) {
kenjiArai 1:9011c83e4178 169 connectedLED = 1;
kenjiArai 1:9011c83e4178 170 } else {
kenjiArai 1:9011c83e4178 171 connectedLED = 0;
kenjiArai 1:9011c83e4178 172 }
kenjiArai 1:9011c83e4178 173 if (rx_isr_busy == true) {
kenjiArai 1:9011c83e4178 174 rx_isr_busy = false;
kenjiArai 1:9011c83e4178 175 } else {
kenjiArai 1:9011c83e4178 176 tsk.signal_set(0x01);
kenjiArai 1:9011c83e4178 177 }
kenjiArai 1:9011c83e4178 178 }
kenjiArai 1:9011c83e4178 179
kenjiArai 1:9011c83e4178 180 void serialRxCallback()
kenjiArai 1:9011c83e4178 181 {
kenjiArai 1:9011c83e4178 182 ser_bf.push(pc.getc());
kenjiArai 1:9011c83e4178 183 rx_isr_busy = true;
kenjiArai 1:9011c83e4178 184 tsk.signal_set(0x01);
kenjiArai 1:9011c83e4178 185 }
kenjiArai 1:9011c83e4178 186
kenjiArai 1:9011c83e4178 187 void pc_ser_rx()
kenjiArai 1:9011c83e4178 188 {
kenjiArai 1:9011c83e4178 189 static uint8_t linebf_irq[BFSIZE];
kenjiArai 1:9011c83e4178 190 static volatile uint8_t linebf_irq_len = 0;
kenjiArai 1:9011c83e4178 191
kenjiArai 1:9011c83e4178 192 while(true) {
kenjiArai 1:9011c83e4178 193 Thread::signal_wait(0x01);
kenjiArai 1:9011c83e4178 194 if (ser_bf.empty()) {
kenjiArai 1:9011c83e4178 195 if (linebf_irq_len != 0) {
kenjiArai 1:9011c83e4178 196 linebf_irq[linebf_irq_len] = 0;
kenjiArai 1:9011c83e4178 197 adjust_line(linebf_irq);
kenjiArai 1:9011c83e4178 198 linebf_irq_len = 0;
kenjiArai 1:9011c83e4178 199 uartTXCharacteristic.write(NUM_ONCE, linebf_irq);
kenjiArai 1:9011c83e4178 200 }
kenjiArai 1:9011c83e4178 201 }
kenjiArai 1:9011c83e4178 202 while(!ser_bf.empty()) {
kenjiArai 1:9011c83e4178 203 char c;
kenjiArai 1:9011c83e4178 204 ser_bf.pop(c);
kenjiArai 1:9011c83e4178 205 if (c == '\b') {
kenjiArai 1:9011c83e4178 206 linebf_irq_len--;
kenjiArai 1:9011c83e4178 207 pc.putc(c);
kenjiArai 1:9011c83e4178 208 pc.putc(' ');
kenjiArai 1:9011c83e4178 209 pc.putc(c);
kenjiArai 1:9011c83e4178 210 } else if ((c >= ' ') || (c == '\r') || (c == '\n')) {
kenjiArai 1:9011c83e4178 211 bool overflow = false;
kenjiArai 1:9011c83e4178 212 if ((c == '\r') || (c == '\n')) {
kenjiArai 1:9011c83e4178 213 if (linebf_irq_len == NUM_ONCE - 1) { // remain only 1 buffer
kenjiArai 1:9011c83e4178 214 overflow = true;
kenjiArai 1:9011c83e4178 215 linebf_irq[linebf_irq_len++] = '\r';
kenjiArai 1:9011c83e4178 216 pc.putc('\r');
kenjiArai 1:9011c83e4178 217 } else {
kenjiArai 1:9011c83e4178 218 overflow = false;
kenjiArai 1:9011c83e4178 219 linebf_irq[linebf_irq_len++] = '\r';
kenjiArai 1:9011c83e4178 220 linebf_irq[linebf_irq_len++] = '\n';
kenjiArai 1:9011c83e4178 221 pc.printf("\r\n");
kenjiArai 1:9011c83e4178 222 }
kenjiArai 1:9011c83e4178 223 } else {
kenjiArai 1:9011c83e4178 224 linebf_irq[linebf_irq_len++] = c;
kenjiArai 1:9011c83e4178 225 pc.putc(c);
kenjiArai 1:9011c83e4178 226 }
kenjiArai 1:9011c83e4178 227 if (linebf_irq_len >= NUM_ONCE ) {
kenjiArai 1:9011c83e4178 228 linebf_irq[linebf_irq_len] = 0;
kenjiArai 1:9011c83e4178 229 uartTXCharacteristic.write(linebf_irq_len, linebf_irq);
kenjiArai 1:9011c83e4178 230 linebf_irq_len = 0;
kenjiArai 1:9011c83e4178 231 if (overflow == true) {
kenjiArai 1:9011c83e4178 232 overflow = false;
kenjiArai 1:9011c83e4178 233 linebf_irq[linebf_irq_len++] = '\n';
kenjiArai 1:9011c83e4178 234 pc.putc('\n');
kenjiArai 1:9011c83e4178 235 }
kenjiArai 1:9011c83e4178 236 }
kenjiArai 1:9011c83e4178 237 }
kenjiArai 1:9011c83e4178 238 }
kenjiArai 1:9011c83e4178 239 }
kenjiArai 1:9011c83e4178 240 }
kenjiArai 1:9011c83e4178 241
kenjiArai 1:9011c83e4178 242 void adjust_line(uint8_t *bf)
kenjiArai 1:9011c83e4178 243 {
kenjiArai 1:9011c83e4178 244 uint8_t i, c;
kenjiArai 1:9011c83e4178 245
kenjiArai 1:9011c83e4178 246 for (i = 0; i <NUM_ONCE; bf++, i++) {
kenjiArai 1:9011c83e4178 247 c = *bf;
kenjiArai 1:9011c83e4178 248 if (c == 0) {
kenjiArai 1:9011c83e4178 249 break;
kenjiArai 1:9011c83e4178 250 }
kenjiArai 1:9011c83e4178 251 }
kenjiArai 1:9011c83e4178 252 for (; i < NUM_ONCE; bf++, i++) {
kenjiArai 1:9011c83e4178 253 *bf = 0x11;
kenjiArai 1:9011c83e4178 254 }
kenjiArai 1:9011c83e4178 255 *(bf + 1) = 0;
kenjiArai 1:9011c83e4178 256 }
kenjiArai 1:9011c83e4178 257
kenjiArai 1:9011c83e4178 258 void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *params)
kenjiArai 1:9011c83e4178 259 {
kenjiArai 1:9011c83e4178 260 DBG(
kenjiArai 1:9011c83e4178 261 "received HVX callback for handle %u; type %s\r\r\n",
kenjiArai 1:9011c83e4178 262 params->handle,
kenjiArai 1:9011c83e4178 263 (params->type == BLE_HVX_NOTIFICATION) ? "notification" : "indication"
kenjiArai 1:9011c83e4178 264 );
kenjiArai 1:9011c83e4178 265 if (params->type == BLE_HVX_NOTIFICATION) {
kenjiArai 1:9011c83e4178 266 if ((params->handle
kenjiArai 1:9011c83e4178 267 == uartRXCharacteristic.getValueHandle()) && (params->len > 0)) {
kenjiArai 1:9011c83e4178 268 uart_bf_len = params->len;
kenjiArai 1:9011c83e4178 269 strcpy((char *)uart_buffer, (char *)params->data);
kenjiArai 1:9011c83e4178 270 received_uart_dat = true;
kenjiArai 1:9011c83e4178 271 }
kenjiArai 1:9011c83e4178 272 }
kenjiArai 1:9011c83e4178 273 }
kenjiArai 1:9011c83e4178 274
kenjiArai 1:9011c83e4178 275 #ifdef USE_MAC
kenjiArai 1:9011c83e4178 276
kenjiArai 1:9011c83e4178 277 bool mac_equals(const Gap::Address_t mac_1, const Gap::Address_t mac_2)
kenjiArai 1:9011c83e4178 278 {
kenjiArai 1:9011c83e4178 279 DBG("Address: ");
kenjiArai 1:9011c83e4178 280 for (int i = 0; i < 6; i++) {
kenjiArai 1:9011c83e4178 281 DBG("0x%02x ", mac_1[i]);
kenjiArai 1:9011c83e4178 282 }
kenjiArai 1:9011c83e4178 283 DBG("\r\n");
kenjiArai 1:9011c83e4178 284 for (int i = 0; i < 6; i++) {
kenjiArai 1:9011c83e4178 285 if (mac_1[i] != mac_2[i]) {
kenjiArai 1:9011c83e4178 286 DBG("0x%02x != 0x%02x at %d\r\n", mac_1[i], mac_2[i], i);
kenjiArai 1:9011c83e4178 287 return false;
kenjiArai 1:9011c83e4178 288 } else {
kenjiArai 1:9011c83e4178 289 DBG("0x%02x == 0x%02x at %d\r\n", mac_1[i], mac_2[i], i);
kenjiArai 1:9011c83e4178 290 }
kenjiArai 1:9011c83e4178 291 }
kenjiArai 1:9011c83e4178 292 return true;
kenjiArai 1:9011c83e4178 293 }
kenjiArai 1:9011c83e4178 294
kenjiArai 1:9011c83e4178 295 int get_board_index(const Gap::Address_t mac)
kenjiArai 1:9011c83e4178 296 {
kenjiArai 1:9011c83e4178 297 if (mac_equals(mac, mac_board_0)) {
kenjiArai 1:9011c83e4178 298 return 0;
kenjiArai 1:9011c83e4178 299 }
kenjiArai 1:9011c83e4178 300 if (mac_equals(mac, mac_board_1)) {
kenjiArai 1:9011c83e4178 301 return 1;
kenjiArai 1:9011c83e4178 302 }
kenjiArai 1:9011c83e4178 303 if (mac_equals(mac, mac_board_2)) {
kenjiArai 1:9011c83e4178 304 return 2;
kenjiArai 1:9011c83e4178 305 }
kenjiArai 1:9011c83e4178 306 if (mac_equals(mac, mac_board_3)) {
kenjiArai 1:9011c83e4178 307 return 3;
kenjiArai 1:9011c83e4178 308 }
kenjiArai 1:9011c83e4178 309 if (mac_equals(mac, mac_board_4)) {
kenjiArai 1:9011c83e4178 310 return 4;
kenjiArai 1:9011c83e4178 311 }
kenjiArai 1:9011c83e4178 312 return -1;
kenjiArai 1:9011c83e4178 313 }
kenjiArai 1:9011c83e4178 314
kenjiArai 1:9011c83e4178 315 // Client(Central) role ********************************************************
kenjiArai 1:9011c83e4178 316 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
kenjiArai 1:9011c83e4178 317 {
kenjiArai 1:9011c83e4178 318 // connections
kenjiArai 1:9011c83e4178 319 int peer_board_index = get_board_index(params->peerAddr);
kenjiArai 1:9011c83e4178 320 if (peer_board_index != -1) {
kenjiArai 1:9011c83e4178 321 pc.printf("");
kenjiArai 1:9011c83e4178 322 pc.printf(
kenjiArai 1:9011c83e4178 323 "adv peerAddr [%02x %02x %02x %02x %02x %02x]\r\n",
kenjiArai 1:9011c83e4178 324 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3],
kenjiArai 1:9011c83e4178 325 params->peerAddr[2], params->peerAddr[1], params->peerAddr[0]
kenjiArai 1:9011c83e4178 326 );
kenjiArai 1:9011c83e4178 327 pc.printf(
kenjiArai 1:9011c83e4178 328 "rssi=%+4d, isScanResponse %u, AdvertisementType %u\r\n",
kenjiArai 1:9011c83e4178 329 params->rssi, params->isScanResponse, params->type
kenjiArai 1:9011c83e4178 330 );
kenjiArai 1:9011c83e4178 331 ble_uart.gap().connect(
kenjiArai 1:9011c83e4178 332 params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
kenjiArai 1:9011c83e4178 333 }
kenjiArai 1:9011c83e4178 334 }
kenjiArai 1:9011c83e4178 335
kenjiArai 1:9011c83e4178 336 #else
kenjiArai 1:9011c83e4178 337
kenjiArai 1:9011c83e4178 338 // Client(Central) role ********************************************************
kenjiArai 1:9011c83e4178 339 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
kenjiArai 1:9011c83e4178 340 {
kenjiArai 1:9011c83e4178 341 bool name_match = false;
kenjiArai 1:9011c83e4178 342
kenjiArai 1:9011c83e4178 343 // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME
kenjiArai 1:9011c83e4178 344 // The advertising payload is a collection of key/value records where
kenjiArai 1:9011c83e4178 345 // byte 0: length of the record excluding this byte
kenjiArai 1:9011c83e4178 346 // byte 1: The key, it is the type of the data
kenjiArai 1:9011c83e4178 347 // byte [2..N] The value. N is equal to byte0 - 1
kenjiArai 1:9011c83e4178 348
kenjiArai 1:9011c83e4178 349 for( uint8_t i = 0; i < params->advertisingDataLen; ++i) {
kenjiArai 1:9011c83e4178 350 const uint8_t record_length = params->advertisingData[i];
kenjiArai 1:9011c83e4178 351 if (record_length == 0) {
kenjiArai 1:9011c83e4178 352 continue;
kenjiArai 1:9011c83e4178 353 }
kenjiArai 1:9011c83e4178 354 const uint8_t type = params->advertisingData[i + 1];
kenjiArai 1:9011c83e4178 355 const uint8_t* value = params->advertisingData + i + 2;
kenjiArai 1:9011c83e4178 356 const uint8_t value_length = record_length - 1;
kenjiArai 1:9011c83e4178 357
kenjiArai 1:9011c83e4178 358 if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
kenjiArai 1:9011c83e4178 359 if ((value_length == sizeof(PEER_NAME))
kenjiArai 1:9011c83e4178 360 && (memcmp(value, PEER_NAME, value_length) == 0)) {
kenjiArai 1:9011c83e4178 361 pc.printf(
kenjiArai 1:9011c83e4178 362 "\r\nadv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, ",
kenjiArai 1:9011c83e4178 363 params->peerAddr[5], params->peerAddr[4],
kenjiArai 1:9011c83e4178 364 params->peerAddr[3], params->peerAddr[2],
kenjiArai 1:9011c83e4178 365 params->peerAddr[1], params->peerAddr[0],
kenjiArai 1:9011c83e4178 366 params->rssi
kenjiArai 1:9011c83e4178 367 );
kenjiArai 1:9011c83e4178 368 pc.printf(
kenjiArai 1:9011c83e4178 369 "isScanResponse %u, AdvertisementType %u\r\n",
kenjiArai 1:9011c83e4178 370 params->isScanResponse, params->type
kenjiArai 1:9011c83e4178 371 );
kenjiArai 1:9011c83e4178 372 name_match = true;
kenjiArai 1:9011c83e4178 373 break;
kenjiArai 1:9011c83e4178 374 }
kenjiArai 1:9011c83e4178 375 }
kenjiArai 1:9011c83e4178 376 i += record_length;
kenjiArai 1:9011c83e4178 377 }
kenjiArai 1:9011c83e4178 378 if( name_match != true ) {
kenjiArai 1:9011c83e4178 379 return;
kenjiArai 1:9011c83e4178 380 }
kenjiArai 1:9011c83e4178 381
kenjiArai 1:9011c83e4178 382 pc.printf("Found device name : %s\r\n",PEER_NAME);
kenjiArai 1:9011c83e4178 383 // connections
kenjiArai 1:9011c83e4178 384 ble_uart.gap().connect(params->peerAddr,
kenjiArai 1:9011c83e4178 385 Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
kenjiArai 1:9011c83e4178 386 }
kenjiArai 1:9011c83e4178 387
kenjiArai 1:9011c83e4178 388 #endif
kenjiArai 1:9011c83e4178 389
kenjiArai 1:9011c83e4178 390 void serviceDiscoveryCallback(const DiscoveredService *service)
kenjiArai 1:9011c83e4178 391 {
kenjiArai 1:9011c83e4178 392 DBG("service found...\r\n");
kenjiArai 1:9011c83e4178 393 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
kenjiArai 1:9011c83e4178 394 DBG(
kenjiArai 1:9011c83e4178 395 "Service UUID-%x attrs[%u %u]\r\n",
kenjiArai 1:9011c83e4178 396 service->getUUID().getShortUUID(),
kenjiArai 1:9011c83e4178 397 service->getStartHandle(),
kenjiArai 1:9011c83e4178 398 service->getEndHandle()
kenjiArai 1:9011c83e4178 399 );
kenjiArai 1:9011c83e4178 400 } else {
kenjiArai 1:9011c83e4178 401 DBG("Service UUID-");
kenjiArai 1:9011c83e4178 402 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
kenjiArai 1:9011c83e4178 403 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
kenjiArai 1:9011c83e4178 404 DBG("%02x", longUUIDBytes[i]);
kenjiArai 1:9011c83e4178 405 }
kenjiArai 1:9011c83e4178 406 DBG(" attrs[%u %u]\r\n",
kenjiArai 1:9011c83e4178 407 service->getStartHandle(), service->getEndHandle());
kenjiArai 1:9011c83e4178 408 }
kenjiArai 1:9011c83e4178 409 }
kenjiArai 1:9011c83e4178 410
kenjiArai 1:9011c83e4178 411 void characteristicDiscoveryCallback(
kenjiArai 1:9011c83e4178 412 const DiscoveredCharacteristic *characteristicP)
kenjiArai 1:9011c83e4178 413 {
kenjiArai 1:9011c83e4178 414 DBG(
kenjiArai 1:9011c83e4178 415 " C UUID-%x valueAttr[%u] props[%x]\r\n",
kenjiArai 1:9011c83e4178 416 characteristicP->getUUID().getShortUUID(),
kenjiArai 1:9011c83e4178 417 characteristicP->getValueHandle(),
kenjiArai 1:9011c83e4178 418 (uint8_t)characteristicP->getProperties().broadcast()
kenjiArai 1:9011c83e4178 419 );
kenjiArai 1:9011c83e4178 420 if (characteristicP->getUUID().getShortUUID()
kenjiArai 1:9011c83e4178 421 == UARTServiceTXCharacteristicShortUUID) {
kenjiArai 1:9011c83e4178 422 DBG("Sevice TX 0x%04x\r\n", UARTServiceTXCharacteristicShortUUID);
kenjiArai 1:9011c83e4178 423 uartTXCharacteristic = *characteristicP;
kenjiArai 1:9011c83e4178 424 connection_tx = true;
kenjiArai 1:9011c83e4178 425 } else if (characteristicP->getUUID().getShortUUID()
kenjiArai 1:9011c83e4178 426 == UARTServiceRXCharacteristicShortUUID) {
kenjiArai 1:9011c83e4178 427 DBG("Sevice RX 0x%04x\r\n", UARTServiceRXCharacteristicShortUUID);
kenjiArai 1:9011c83e4178 428 uartRXCharacteristic = *characteristicP;
kenjiArai 1:9011c83e4178 429 foundUartRXCharacteristic = true;
kenjiArai 1:9011c83e4178 430 connection_rx = true;
kenjiArai 1:9011c83e4178 431 }
kenjiArai 1:9011c83e4178 432 }
kenjiArai 1:9011c83e4178 433
kenjiArai 1:9011c83e4178 434 void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
kenjiArai 1:9011c83e4178 435 {
kenjiArai 1:9011c83e4178 436 DBG("terminated SD for handle=%u\r\n", connectionHandle);
kenjiArai 1:9011c83e4178 437 }
kenjiArai 1:9011c83e4178 438
kenjiArai 1:9011c83e4178 439 // Mixed role ******************************************************************
kenjiArai 1:9011c83e4178 440 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
kenjiArai 1:9011c83e4178 441 {
kenjiArai 1:9011c83e4178 442 if (params->role == Gap::CENTRAL) {
kenjiArai 1:9011c83e4178 443 pc.printf("connected as Client(Central) (handle = %d)\r\n\r",
kenjiArai 1:9011c83e4178 444 params->handle);
kenjiArai 1:9011c83e4178 445 connected2server = true;
kenjiArai 1:9011c83e4178 446 connectionHandle = params->handle;
kenjiArai 1:9011c83e4178 447 ble_uart.gattClient().onServiceDiscoveryTermination(
kenjiArai 1:9011c83e4178 448 discoveryTerminationCallback);
kenjiArai 1:9011c83e4178 449 ble_uart.gattClient().launchServiceDiscovery(
kenjiArai 1:9011c83e4178 450 params->handle,
kenjiArai 1:9011c83e4178 451 serviceDiscoveryCallback,
kenjiArai 1:9011c83e4178 452 characteristicDiscoveryCallback
kenjiArai 1:9011c83e4178 453 );
kenjiArai 1:9011c83e4178 454 }
kenjiArai 1:9011c83e4178 455 pc.printf(
kenjiArai 1:9011c83e4178 456 "Client(Central/Myself) %02x:%02x:%02x:%02x:%02x:%02x\r\n",
kenjiArai 1:9011c83e4178 457 params->ownAddr[5], params->ownAddr[4], params->ownAddr[3],
kenjiArai 1:9011c83e4178 458 params->ownAddr[2], params->ownAddr[1], params->ownAddr[0]
kenjiArai 1:9011c83e4178 459 );
kenjiArai 1:9011c83e4178 460 pc.printf(
kenjiArai 1:9011c83e4178 461 "Connected Server(Peripheral) %02x:%02x:%02x:%02x:%02x:%02x\r\n",
kenjiArai 1:9011c83e4178 462 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3],
kenjiArai 1:9011c83e4178 463 params->peerAddr[2], params->peerAddr[1], params->peerAddr[0]
kenjiArai 1:9011c83e4178 464 );
kenjiArai 1:9011c83e4178 465 }
kenjiArai 1:9011c83e4178 466
kenjiArai 1:9011c83e4178 467 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
kenjiArai 1:9011c83e4178 468 {
kenjiArai 1:9011c83e4178 469 DBG("handle = %d ", params->handle);
kenjiArai 1:9011c83e4178 470 pc.printf(" -> disconnected\r\n", params->handle);
kenjiArai 1:9011c83e4178 471 connected2server = false;
kenjiArai 1:9011c83e4178 472 // connection_1st = false;
kenjiArai 1:9011c83e4178 473 connection_tx = false;
kenjiArai 1:9011c83e4178 474 connection_rx = false;
kenjiArai 1:9011c83e4178 475 if (params->handle == SOFT_DEVICE_FATHER_HANDLE) {
kenjiArai 1:9011c83e4178 476 ble_uart.startAdvertising(); // restart advertising
kenjiArai 1:9011c83e4178 477 } else {
kenjiArai 1:9011c83e4178 478 ble_uart.gap().startScan(advertisementCallback);// restart scan
kenjiArai 1:9011c83e4178 479 }
kenjiArai 1:9011c83e4178 480 }
kenjiArai 1:9011c83e4178 481
kenjiArai 1:9011c83e4178 482 #endif