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 Feb 11 02:04:44 2018 +0000
Revision:
5:e90d7b6f83cb
Parent:
4:342b665fb826
use Mbed-os5 dedicated class "CircularBuffer"

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:0ef6455cbb4d 1 #if 0
kenjiArai 0:0ef6455cbb4d 2 //-------------------------------------------------------------------------------------------------
kenjiArai 0:0ef6455cbb4d 3 // ORIGINAL PROGRAM
kenjiArai 0:0ef6455cbb4d 4 // S130 potential unstability case [closed] by Fabien Comte
kenjiArai 0:0ef6455cbb4d 5 // https://devzone.nordicsemi.com/question/49705/s130-potential-unstability-case/
kenjiArai 0:0ef6455cbb4d 6 //
kenjiArai 0:0ef6455cbb4d 7 #include "mbed.h"
kenjiArai 0:0ef6455cbb4d 8 #include "BLE.h"
kenjiArai 0:0ef6455cbb4d 9 #include "UARTService.h"
kenjiArai 0:0ef6455cbb4d 10 #include "ble/DiscoveredCharacteristic.h"
kenjiArai 0:0ef6455cbb4d 11 #include "ble/DiscoveredService.h"
kenjiArai 4:342b665fb826 12 #include "ble/service/UARTService.h"
kenjiArai 0:0ef6455cbb4d 13
kenjiArai 0:0ef6455cbb4d 14 #define SOFT_DEVICE_FATHER_HANDLE 3
kenjiArai 0:0ef6455cbb4d 15
kenjiArai 0:0ef6455cbb4d 16 #define BOARDS_COUNT 3
kenjiArai 0:0ef6455cbb4d 17
kenjiArai 0:0ef6455cbb4d 18 const Gap::Address_t mac_board_0 = {0xb8, 0xac, 0x4e, 0x8d, 0x8b, 0xeb};
kenjiArai 0:0ef6455cbb4d 19 const Gap::Address_t mac_board_1 = {0x9c, 0x43, 0x62, 0x30, 0xaf, 0xd2};
kenjiArai 0:0ef6455cbb4d 20 const Gap::Address_t mac_board_2 = {0x5f, 0x1a, 0x9e, 0x6a, 0x63, 0xdd};
kenjiArai 0:0ef6455cbb4d 21
kenjiArai 0:0ef6455cbb4d 22
kenjiArai 0:0ef6455cbb4d 23 // tiny ble board
kenjiArai 0:0ef6455cbb4d 24 #define LED_GREEN p21
kenjiArai 0:0ef6455cbb4d 25 #define LED_RED p22
kenjiArai 0:0ef6455cbb4d 26 #define LED_BLUE p23
kenjiArai 0:0ef6455cbb4d 27 #define BUTTON_PIN p17
kenjiArai 0:0ef6455cbb4d 28 #define BATTERY_PIN p1
kenjiArai 0:0ef6455cbb4d 29
kenjiArai 0:0ef6455cbb4d 30 #define MPU6050_SDA p12
kenjiArai 0:0ef6455cbb4d 31 #define MPU6050_SCL p13
kenjiArai 0:0ef6455cbb4d 32
kenjiArai 0:0ef6455cbb4d 33 #define UART_TX p9
kenjiArai 0:0ef6455cbb4d 34 #define UART_RX p11
kenjiArai 0:0ef6455cbb4d 35 #define UART_CTS p8
kenjiArai 0:0ef6455cbb4d 36 #define UART_RTS p10
kenjiArai 0:0ef6455cbb4d 37
kenjiArai 0:0ef6455cbb4d 38 DigitalOut led(LED_RED);
kenjiArai 0:0ef6455cbb4d 39 DigitalOut alivenessLED(LED_GREEN);
kenjiArai 0:0ef6455cbb4d 40 InterruptIn button(BUTTON_PIN);
kenjiArai 0:0ef6455cbb4d 41 AnalogIn battery(BATTERY_PIN);
kenjiArai 0:0ef6455cbb4d 42 Serial pc(UART_TX, UART_RX);
kenjiArai 0:0ef6455cbb4d 43
kenjiArai 0:0ef6455cbb4d 44 bool mac_equals(const Gap::Address_t mac_1, const Gap::Address_t mac_2)
kenjiArai 0:0ef6455cbb4d 45 {
kenjiArai 0:0ef6455cbb4d 46 #if 0
kenjiArai 0:0ef6455cbb4d 47 if (mac_1[0] != mac_2[0])
kenjiArai 0:0ef6455cbb4d 48 {
kenjiArai 0:0ef6455cbb4d 49 return false;
kenjiArai 0:0ef6455cbb4d 50 }
kenjiArai 0:0ef6455cbb4d 51 if (mac_1[1] != mac_2[1])
kenjiArai 0:0ef6455cbb4d 52 {
kenjiArai 0:0ef6455cbb4d 53 return false;
kenjiArai 0:0ef6455cbb4d 54 }
kenjiArai 0:0ef6455cbb4d 55 if (mac_1[2] != mac_2[2])
kenjiArai 0:0ef6455cbb4d 56 {
kenjiArai 0:0ef6455cbb4d 57 return false;
kenjiArai 0:0ef6455cbb4d 58 }
kenjiArai 0:0ef6455cbb4d 59 if (mac_1[3] != mac_2[3])
kenjiArai 0:0ef6455cbb4d 60 {
kenjiArai 0:0ef6455cbb4d 61 return false;
kenjiArai 0:0ef6455cbb4d 62 }
kenjiArai 0:0ef6455cbb4d 63 if (mac_1[4] != mac_2[4])
kenjiArai 0:0ef6455cbb4d 64 {
kenjiArai 0:0ef6455cbb4d 65 return false;
kenjiArai 0:0ef6455cbb4d 66 }
kenjiArai 0:0ef6455cbb4d 67 if (mac_1[5] != mac_2[5])
kenjiArai 0:0ef6455cbb4d 68 {
kenjiArai 0:0ef6455cbb4d 69 return false;
kenjiArai 0:0ef6455cbb4d 70 }
kenjiArai 0:0ef6455cbb4d 71 #else
kenjiArai 0:0ef6455cbb4d 72 for (int i = 0; i < 6; i++)
kenjiArai 0:0ef6455cbb4d 73 {
kenjiArai 0:0ef6455cbb4d 74 if (mac_1[i] != mac_2[i])
kenjiArai 0:0ef6455cbb4d 75 {
kenjiArai 0:0ef6455cbb4d 76 //pc.printf("0x%02x != 0x%02x at %d\r\n", mac_1[i], mac_2[i], i);
kenjiArai 0:0ef6455cbb4d 77 return false;
kenjiArai 0:0ef6455cbb4d 78 }
kenjiArai 0:0ef6455cbb4d 79 else
kenjiArai 0:0ef6455cbb4d 80 {
kenjiArai 0:0ef6455cbb4d 81 //pc.printf("0x%02x == 0x%02x at %d\r\n", mac_1[i], mac_2[i], i);
kenjiArai 0:0ef6455cbb4d 82 }
kenjiArai 0:0ef6455cbb4d 83 }
kenjiArai 0:0ef6455cbb4d 84 #endif
kenjiArai 0:0ef6455cbb4d 85 return true;
kenjiArai 0:0ef6455cbb4d 86 }
kenjiArai 0:0ef6455cbb4d 87
kenjiArai 0:0ef6455cbb4d 88 int get_board_index(const Gap::Address_t mac)
kenjiArai 0:0ef6455cbb4d 89 {
kenjiArai 0:0ef6455cbb4d 90 if (mac_equals(mac, mac_board_0))
kenjiArai 0:0ef6455cbb4d 91 {
kenjiArai 0:0ef6455cbb4d 92 return 0;
kenjiArai 0:0ef6455cbb4d 93 }
kenjiArai 0:0ef6455cbb4d 94 if (mac_equals(mac, mac_board_1))
kenjiArai 0:0ef6455cbb4d 95 {
kenjiArai 0:0ef6455cbb4d 96 return 1;
kenjiArai 0:0ef6455cbb4d 97 }
kenjiArai 0:0ef6455cbb4d 98 if (mac_equals(mac, mac_board_2))
kenjiArai 0:0ef6455cbb4d 99 {
kenjiArai 0:0ef6455cbb4d 100 return 2;
kenjiArai 0:0ef6455cbb4d 101 }
kenjiArai 0:0ef6455cbb4d 102
kenjiArai 0:0ef6455cbb4d 103 return -1;
kenjiArai 0:0ef6455cbb4d 104 }
kenjiArai 0:0ef6455cbb4d 105
kenjiArai 0:0ef6455cbb4d 106 void periodicCallback(void)
kenjiArai 0:0ef6455cbb4d 107 {
kenjiArai 0:0ef6455cbb4d 108 alivenessLED = !alivenessLED; /* do blinky on alivenessLED while we're waiting for BLE events */
kenjiArai 0:0ef6455cbb4d 109 }
kenjiArai 0:0ef6455cbb4d 110
kenjiArai 0:0ef6455cbb4d 111
kenjiArai 0:0ef6455cbb4d 112 // Mixed role ****************************************************
kenjiArai 0:0ef6455cbb4d 113 BLE ble;
kenjiArai 0:0ef6455cbb4d 114 Gap::Address_t my_mac;
kenjiArai 0:0ef6455cbb4d 115 int my_board_index = -1;
kenjiArai 0:0ef6455cbb4d 116
kenjiArai 0:0ef6455cbb4d 117 // Device role ****************************************************
kenjiArai 0:0ef6455cbb4d 118 UARTService * uartServicePtr = NULL;
kenjiArai 0:0ef6455cbb4d 119 const static char DEVICE_NAME[] = "ChangeMe!!"; // change this
kenjiArai 0:0ef6455cbb4d 120 static const uint16_t uuid16_list[] = {UARTServiceShortUUID};
kenjiArai 0:0ef6455cbb4d 121 volatile int central_handle = -1;
kenjiArai 0:0ef6455cbb4d 122
kenjiArai 0:0ef6455cbb4d 123
kenjiArai 0:0ef6455cbb4d 124 // Central role ****************************************************
kenjiArai 0:0ef6455cbb4d 125 Gap::Handle_t connectionHandle = 0xFFFF;
kenjiArai 0:0ef6455cbb4d 126 DiscoveredCharacteristic uartTXCharacteristic;
kenjiArai 0:0ef6455cbb4d 127 DiscoveredCharacteristic uartRXCharacteristic;
kenjiArai 0:0ef6455cbb4d 128 bool foundUartRXCharacteristic = false;
kenjiArai 0:0ef6455cbb4d 129 volatile int device_handle = -1;
kenjiArai 0:0ef6455cbb4d 130
kenjiArai 0:0ef6455cbb4d 131
kenjiArai 0:0ef6455cbb4d 132 // Device role ****************************************************
kenjiArai 0:0ef6455cbb4d 133 void onReceivedDataFromCentralCallback(const GattWriteCallbackParams *params)
kenjiArai 0:0ef6455cbb4d 134 {
kenjiArai 0:0ef6455cbb4d 135 if (uartServicePtr != NULL)
kenjiArai 0:0ef6455cbb4d 136 {
kenjiArai 0:0ef6455cbb4d 137 if ((params->handle == uartServicePtr->getTXCharacteristicHandle()) && (params->len >= 1))
kenjiArai 0:0ef6455cbb4d 138 {
kenjiArai 0:0ef6455cbb4d 139 if (params->data[0] != '0')
kenjiArai 0:0ef6455cbb4d 140 {
kenjiArai 0:0ef6455cbb4d 141 led = 1;
kenjiArai 0:0ef6455cbb4d 142 }
kenjiArai 0:0ef6455cbb4d 143 else
kenjiArai 0:0ef6455cbb4d 144 {
kenjiArai 0:0ef6455cbb4d 145 led = 0;
kenjiArai 0:0ef6455cbb4d 146 }
kenjiArai 0:0ef6455cbb4d 147
kenjiArai 0:0ef6455cbb4d 148 for(int i = 0; i < params->len; i++)
kenjiArai 0:0ef6455cbb4d 149 {
kenjiArai 0:0ef6455cbb4d 150 pc.printf("%c", params->data[i]);
kenjiArai 0:0ef6455cbb4d 151 }
kenjiArai 0:0ef6455cbb4d 152
kenjiArai 0:0ef6455cbb4d 153 pc.printf(" (%d, %d)\r\n", params->handle, params->connHandle);
kenjiArai 0:0ef6455cbb4d 154 }
kenjiArai 0:0ef6455cbb4d 155 }
kenjiArai 0:0ef6455cbb4d 156 }
kenjiArai 0:0ef6455cbb4d 157
kenjiArai 0:0ef6455cbb4d 158 // Central role ****************************************************
kenjiArai 0:0ef6455cbb4d 159 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
kenjiArai 0:0ef6455cbb4d 160 {
kenjiArai 0:0ef6455cbb4d 161 // do connections like a triangle
kenjiArai 0:0ef6455cbb4d 162 int peer_board_index = get_board_index(params->peerAddr);
kenjiArai 0:0ef6455cbb4d 163
kenjiArai 0:0ef6455cbb4d 164 int next_board_index = my_board_index + 1;
kenjiArai 0:0ef6455cbb4d 165 if (next_board_index >= BOARDS_COUNT)
kenjiArai 0:0ef6455cbb4d 166 {
kenjiArai 0:0ef6455cbb4d 167 next_board_index = 0;
kenjiArai 0:0ef6455cbb4d 168 }
kenjiArai 0:0ef6455cbb4d 169
kenjiArai 0:0ef6455cbb4d 170 //pc.printf("adv %d, %d, %d\r\n", peer_board_index, my_board_index, next_board_index);
kenjiArai 0:0ef6455cbb4d 171
kenjiArai 0:0ef6455cbb4d 172 // force order
kenjiArai 0:0ef6455cbb4d 173 if ((central_handle != -1) || (peer_board_index == 0))
kenjiArai 0:0ef6455cbb4d 174 {
kenjiArai 0:0ef6455cbb4d 175 if (peer_board_index == next_board_index)
kenjiArai 0:0ef6455cbb4d 176 {
kenjiArai 0:0ef6455cbb4d 177 //pc.printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
kenjiArai 0:0ef6455cbb4d 178 // params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
kenjiArai 0:0ef6455cbb4d 179 // params->rssi, params->isScanResponse, params->type);
kenjiArai 0:0ef6455cbb4d 180
kenjiArai 0:0ef6455cbb4d 181 ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
kenjiArai 0:0ef6455cbb4d 182 }
kenjiArai 0:0ef6455cbb4d 183 }
kenjiArai 0:0ef6455cbb4d 184 }
kenjiArai 0:0ef6455cbb4d 185
kenjiArai 0:0ef6455cbb4d 186 void serviceDiscoveryCallback(const DiscoveredService *service)
kenjiArai 0:0ef6455cbb4d 187 {
kenjiArai 0:0ef6455cbb4d 188 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT)
kenjiArai 0:0ef6455cbb4d 189 {
kenjiArai 0:0ef6455cbb4d 190 pc.printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
kenjiArai 0:0ef6455cbb4d 191 }
kenjiArai 0:0ef6455cbb4d 192 else
kenjiArai 0:0ef6455cbb4d 193 {
kenjiArai 0:0ef6455cbb4d 194 //pc.printf("S UUID-");
kenjiArai 0:0ef6455cbb4d 195 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
kenjiArai 0:0ef6455cbb4d 196 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++)
kenjiArai 0:0ef6455cbb4d 197 {
kenjiArai 0:0ef6455cbb4d 198 pc.printf("%02x", longUUIDBytes[i]);
kenjiArai 0:0ef6455cbb4d 199 }
kenjiArai 0:0ef6455cbb4d 200 pc.printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
kenjiArai 0:0ef6455cbb4d 201 }
kenjiArai 0:0ef6455cbb4d 202 }
kenjiArai 0:0ef6455cbb4d 203
kenjiArai 0:0ef6455cbb4d 204 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP)
kenjiArai 0:0ef6455cbb4d 205 {
kenjiArai 0:0ef6455cbb4d 206 //pc.printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
kenjiArai 0:0ef6455cbb4d 207 if (characteristicP->getUUID().getShortUUID() == UARTServiceTXCharacteristicShortUUID)
kenjiArai 0:0ef6455cbb4d 208 {
kenjiArai 0:0ef6455cbb4d 209 pc.printf("fit TX 0x%04x\r\n", UARTServiceTXCharacteristicShortUUID);
kenjiArai 0:0ef6455cbb4d 210 /* !ALERT! Alter this filter to suit your device. */
kenjiArai 0:0ef6455cbb4d 211 uartTXCharacteristic = *characteristicP;
kenjiArai 0:0ef6455cbb4d 212 }
kenjiArai 0:0ef6455cbb4d 213 else if (characteristicP->getUUID().getShortUUID() == UARTServiceRXCharacteristicShortUUID)
kenjiArai 0:0ef6455cbb4d 214 {
kenjiArai 0:0ef6455cbb4d 215 pc.printf("fit RX 0x%04x\r\n", UARTServiceRXCharacteristicShortUUID);
kenjiArai 0:0ef6455cbb4d 216 /* !ALERT! Alter this filter to suit your device. */
kenjiArai 0:0ef6455cbb4d 217 uartRXCharacteristic = *characteristicP;
kenjiArai 0:0ef6455cbb4d 218 foundUartRXCharacteristic = true;
kenjiArai 0:0ef6455cbb4d 219 }
kenjiArai 0:0ef6455cbb4d 220 }
kenjiArai 0:0ef6455cbb4d 221
kenjiArai 0:0ef6455cbb4d 222 void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
kenjiArai 0:0ef6455cbb4d 223 {
kenjiArai 0:0ef6455cbb4d 224 pc.printf("terminated SD for handle %u\r\n", connectionHandle);
kenjiArai 0:0ef6455cbb4d 225 }
kenjiArai 0:0ef6455cbb4d 226
kenjiArai 0:0ef6455cbb4d 227 void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *params)
kenjiArai 0:0ef6455cbb4d 228 {
kenjiArai 0:0ef6455cbb4d 229 //pc.printf("received HVX callback for handle %u; type %s\r\r\n", params->handle, (params->type == BLE_HVX_NOTIFICATION) ? "notification" : "indication");
kenjiArai 0:0ef6455cbb4d 230 if (params->type == BLE_HVX_NOTIFICATION)
kenjiArai 0:0ef6455cbb4d 231 {
kenjiArai 0:0ef6455cbb4d 232 if ((params->handle == uartRXCharacteristic.getValueHandle()) && (params->len > 0))
kenjiArai 0:0ef6455cbb4d 233 {
kenjiArai 0:0ef6455cbb4d 234 for (int i = 0; i < params->len; i++)
kenjiArai 0:0ef6455cbb4d 235 {
kenjiArai 0:0ef6455cbb4d 236 pc.printf("%c", params->data[i]);
kenjiArai 0:0ef6455cbb4d 237 }
kenjiArai 0:0ef6455cbb4d 238
kenjiArai 0:0ef6455cbb4d 239 pc.printf(" (%d, %d)\r\n", params->handle, params->connHandle);
kenjiArai 0:0ef6455cbb4d 240 }
kenjiArai 0:0ef6455cbb4d 241 }
kenjiArai 0:0ef6455cbb4d 242 else
kenjiArai 0:0ef6455cbb4d 243 {
kenjiArai 0:0ef6455cbb4d 244 pc.printf("%d\r\n", params->type);
kenjiArai 0:0ef6455cbb4d 245 }
kenjiArai 0:0ef6455cbb4d 246 }
kenjiArai 0:0ef6455cbb4d 247
kenjiArai 0:0ef6455cbb4d 248 // Mixed role ****************************************************
kenjiArai 0:0ef6455cbb4d 249 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
kenjiArai 0:0ef6455cbb4d 250 {
kenjiArai 0:0ef6455cbb4d 251 if (params->role == Gap::CENTRAL)
kenjiArai 0:0ef6455cbb4d 252 {
kenjiArai 0:0ef6455cbb4d 253 if (central_handle == -1)
kenjiArai 0:0ef6455cbb4d 254 {
kenjiArai 0:0ef6455cbb4d 255 ble.stopAdvertising(); // stop advertising during discovery, incoming connection breaks discovery
kenjiArai 0:0ef6455cbb4d 256 }
kenjiArai 0:0ef6455cbb4d 257
kenjiArai 0:0ef6455cbb4d 258 device_handle = params->handle;
kenjiArai 0:0ef6455cbb4d 259 pc.printf("connected as central (handle = %d)\r\n\r", params->handle);
kenjiArai 0:0ef6455cbb4d 260 connectionHandle = params->handle;
kenjiArai 0:0ef6455cbb4d 261 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
kenjiArai 0:0ef6455cbb4d 262 int ret = ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, UARTServiceShortUUID/*, 0xa001*/);
kenjiArai 0:0ef6455cbb4d 263
kenjiArai 0:0ef6455cbb4d 264 if (ret != BLE_ERROR_NONE)
kenjiArai 0:0ef6455cbb4d 265 {
kenjiArai 0:0ef6455cbb4d 266 pc.printf("launchServiceDiscovery failed error = %d\r\n\r", ret);
kenjiArai 0:0ef6455cbb4d 267 }
kenjiArai 0:0ef6455cbb4d 268 }
kenjiArai 0:0ef6455cbb4d 269 else
kenjiArai 0:0ef6455cbb4d 270 {
kenjiArai 0:0ef6455cbb4d 271 central_handle = params->handle;
kenjiArai 0:0ef6455cbb4d 272 pc.printf("connected as device (handle = %d)\r\n\r", params->handle);
kenjiArai 0:0ef6455cbb4d 273
kenjiArai 0:0ef6455cbb4d 274 //pc.printf("Conn. params => min=%d, max=%d, slave=%d, supervision=%d\r\n", params->connectionParams->minConnectionInterval, params->connectionParams->maxConnectionInterval, params->connectionParams->slaveLatency, params->connectionParams->connectionSupervisionTimeout);
kenjiArai 0:0ef6455cbb4d 275 /*
kenjiArai 0:0ef6455cbb4d 276 Gap::ConnectionParams_t connectionParams;
kenjiArai 0:0ef6455cbb4d 277 connectionParams.minConnectionInterval = 6;
kenjiArai 0:0ef6455cbb4d 278 connectionParams.maxConnectionInterval = 12;
kenjiArai 0:0ef6455cbb4d 279 connectionParams.slaveLatency = 40;
kenjiArai 0:0ef6455cbb4d 280 connectionParams.connectionSupervisionTimeout = 500;
kenjiArai 0:0ef6455cbb4d 281
kenjiArai 0:0ef6455cbb4d 282 int ret = ble.updateConnectionParams(params->handle, &connectionParams);
kenjiArai 0:0ef6455cbb4d 283 if (ret != BLE_ERROR_NONE)
kenjiArai 0:0ef6455cbb4d 284 {
kenjiArai 0:0ef6455cbb4d 285 pc.printf("failed to update connection parameter\r\n");
kenjiArai 0:0ef6455cbb4d 286 }
kenjiArai 0:0ef6455cbb4d 287 */
kenjiArai 0:0ef6455cbb4d 288 }
kenjiArai 0:0ef6455cbb4d 289 pc.printf("own %02x:%02x:%02x:%02x:%02x:%02x (%s), peer %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n", params->ownAddr[5], params->ownAddr[4], params->ownAddr[3], params->ownAddr[2], params->ownAddr[1], params->ownAddr[0], (params->ownAddrType == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random", params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0], (params->peerAddrType == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random");
kenjiArai 0:0ef6455cbb4d 290 }
kenjiArai 0:0ef6455cbb4d 291
kenjiArai 0:0ef6455cbb4d 292 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
kenjiArai 0:0ef6455cbb4d 293 {
kenjiArai 0:0ef6455cbb4d 294 char * ascii_reason = "?";
kenjiArai 0:0ef6455cbb4d 295 switch (reason)
kenjiArai 0:0ef6455cbb4d 296 {
kenjiArai 0:0ef6455cbb4d 297 case Gap::CONNECTION_TIMEOUT:
kenjiArai 0:0ef6455cbb4d 298 ascii_reason = "connection timeout";
kenjiArai 0:0ef6455cbb4d 299 break;
kenjiArai 0:0ef6455cbb4d 300 case Gap::REMOTE_USER_TERMINATED_CONNECTION:
kenjiArai 0:0ef6455cbb4d 301 ascii_reason = "user terminated connection";
kenjiArai 0:0ef6455cbb4d 302 break;
kenjiArai 0:0ef6455cbb4d 303 case Gap::REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES:
kenjiArai 0:0ef6455cbb4d 304 ascii_reason = "low resources";
kenjiArai 0:0ef6455cbb4d 305 break;
kenjiArai 0:0ef6455cbb4d 306 case Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF:
kenjiArai 0:0ef6455cbb4d 307 ascii_reason = "power off";
kenjiArai 0:0ef6455cbb4d 308 break;
kenjiArai 0:0ef6455cbb4d 309 case Gap::LOCAL_HOST_TERMINATED_CONNECTION:
kenjiArai 0:0ef6455cbb4d 310 ascii_reason = "host terminated connection";
kenjiArai 0:0ef6455cbb4d 311 break;
kenjiArai 0:0ef6455cbb4d 312 case Gap::CONN_INTERVAL_UNACCEPTABLE:
kenjiArai 0:0ef6455cbb4d 313 ascii_reason = "interval unacceptable";
kenjiArai 0:0ef6455cbb4d 314 break;
kenjiArai 0:0ef6455cbb4d 315 default:
kenjiArai 0:0ef6455cbb4d 316 ascii_reason = "unknown";
kenjiArai 0:0ef6455cbb4d 317 break;
kenjiArai 0:0ef6455cbb4d 318 }
kenjiArai 0:0ef6455cbb4d 319
kenjiArai 0:0ef6455cbb4d 320 pc.printf("disconnected (reason = %s, handle = %d)\r\n", ascii_reason, handle);
kenjiArai 0:0ef6455cbb4d 321
kenjiArai 0:0ef6455cbb4d 322
kenjiArai 0:0ef6455cbb4d 323 if (handle == SOFT_DEVICE_FATHER_HANDLE)
kenjiArai 0:0ef6455cbb4d 324 {
kenjiArai 0:0ef6455cbb4d 325 central_handle = -1;
kenjiArai 0:0ef6455cbb4d 326 // restart advertising
kenjiArai 0:0ef6455cbb4d 327 ble.startAdvertising();
kenjiArai 0:0ef6455cbb4d 328 }
kenjiArai 0:0ef6455cbb4d 329 else
kenjiArai 0:0ef6455cbb4d 330 {
kenjiArai 0:0ef6455cbb4d 331 device_handle = -1;
kenjiArai 0:0ef6455cbb4d 332 // restart scan
kenjiArai 0:0ef6455cbb4d 333 ble.gap().startScan(advertisementCallback);
kenjiArai 0:0ef6455cbb4d 334 }
kenjiArai 0:0ef6455cbb4d 335 }
kenjiArai 0:0ef6455cbb4d 336
kenjiArai 0:0ef6455cbb4d 337
kenjiArai 0:0ef6455cbb4d 338
kenjiArai 0:0ef6455cbb4d 339 void serialTxCallback()
kenjiArai 0:0ef6455cbb4d 340 {
kenjiArai 0:0ef6455cbb4d 341
kenjiArai 0:0ef6455cbb4d 342 }
kenjiArai 0:0ef6455cbb4d 343
kenjiArai 0:0ef6455cbb4d 344 int rx_char = -1;
kenjiArai 0:0ef6455cbb4d 345 void serialRxCallback()
kenjiArai 0:0ef6455cbb4d 346 {
kenjiArai 0:0ef6455cbb4d 347 if (rx_char != -1)
kenjiArai 0:0ef6455cbb4d 348 {
kenjiArai 0:0ef6455cbb4d 349 pc.printf("overflow\r\n");
kenjiArai 0:0ef6455cbb4d 350 }
kenjiArai 0:0ef6455cbb4d 351
kenjiArai 0:0ef6455cbb4d 352 //computer.putc(computer.getc());
kenjiArai 0:0ef6455cbb4d 353 rx_char = pc.getc();
kenjiArai 0:0ef6455cbb4d 354 }
kenjiArai 0:0ef6455cbb4d 355
kenjiArai 0:0ef6455cbb4d 356 /*
kenjiArai 0:0ef6455cbb4d 357 void gattServerOnDataSent(unsigned count)
kenjiArai 0:0ef6455cbb4d 358 {
kenjiArai 0:0ef6455cbb4d 359
kenjiArai 0:0ef6455cbb4d 360 }
kenjiArai 0:0ef6455cbb4d 361 */
kenjiArai 0:0ef6455cbb4d 362
kenjiArai 0:0ef6455cbb4d 363
kenjiArai 0:0ef6455cbb4d 364 int main(void)
kenjiArai 0:0ef6455cbb4d 365 {
kenjiArai 0:0ef6455cbb4d 366 alivenessLED = 0;
kenjiArai 0:0ef6455cbb4d 367
kenjiArai 0:0ef6455cbb4d 368 pc.baud(115200);
kenjiArai 0:0ef6455cbb4d 369 //pc.attach(&serialTxCallback, Serial::TxIrq);
kenjiArai 0:0ef6455cbb4d 370 pc.attach(&serialRxCallback, Serial::RxIrq);
kenjiArai 0:0ef6455cbb4d 371
kenjiArai 0:0ef6455cbb4d 372 // clear terminal output
kenjiArai 0:0ef6455cbb4d 373 for (int k = 0; k < 32; k++)
kenjiArai 0:0ef6455cbb4d 374 {
kenjiArai 0:0ef6455cbb4d 375 pc.printf("\r\n");
kenjiArai 0:0ef6455cbb4d 376 }
kenjiArai 0:0ef6455cbb4d 377
kenjiArai 0:0ef6455cbb4d 378 pc.printf("Central and device\r\n");
kenjiArai 0:0ef6455cbb4d 379
kenjiArai 0:0ef6455cbb4d 380 Ticker ticker;
kenjiArai 0:0ef6455cbb4d 381 ticker.attach(periodicCallback, 1);
kenjiArai 0:0ef6455cbb4d 382
kenjiArai 0:0ef6455cbb4d 383
kenjiArai 0:0ef6455cbb4d 384 // Mixed role ****************************************************
kenjiArai 0:0ef6455cbb4d 385 ble.init();
kenjiArai 0:0ef6455cbb4d 386
kenjiArai 0:0ef6455cbb4d 387 Gap::AddressType_t my_mac_type;
kenjiArai 0:0ef6455cbb4d 388 ble.gap().getAddress(&my_mac_type, my_mac);
kenjiArai 0:0ef6455cbb4d 389 my_board_index = get_board_index(my_mac);
kenjiArai 0:0ef6455cbb4d 390 pc.printf("me %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n", my_mac[5], my_mac[4], my_mac[3], my_mac[2], my_mac[1], my_mac[0], (my_mac_type == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random");
kenjiArai 0:0ef6455cbb4d 391
kenjiArai 0:0ef6455cbb4d 392
kenjiArai 0:0ef6455cbb4d 393 // try to speed up but looks like if it was ignored
kenjiArai 0:0ef6455cbb4d 394 Gap::ConnectionParams_t fast;
kenjiArai 0:0ef6455cbb4d 395 if (ble.getPreferredConnectionParams(&fast) != BLE_ERROR_NONE)
kenjiArai 0:0ef6455cbb4d 396 {
kenjiArai 0:0ef6455cbb4d 397 pc.printf("getPreferredConnectionParams failed\r\n");
kenjiArai 0:0ef6455cbb4d 398 }
kenjiArai 0:0ef6455cbb4d 399 else
kenjiArai 0:0ef6455cbb4d 400 {
kenjiArai 0:0ef6455cbb4d 401 fast.minConnectionInterval = 16; // 20 ms
kenjiArai 0:0ef6455cbb4d 402 fast.maxConnectionInterval = 32; // 40 ms
kenjiArai 0:0ef6455cbb4d 403 fast.slaveLatency = 0;
kenjiArai 0:0ef6455cbb4d 404 if (ble.gap().setPreferredConnectionParams(&fast) != BLE_ERROR_NONE)
kenjiArai 0:0ef6455cbb4d 405 {
kenjiArai 0:0ef6455cbb4d 406 pc.printf("setPreferredConnectionParams failed\r\n");
kenjiArai 0:0ef6455cbb4d 407 }
kenjiArai 0:0ef6455cbb4d 408 }
kenjiArai 0:0ef6455cbb4d 409 ble.gap().onConnection(connectionCallback);
kenjiArai 0:0ef6455cbb4d 410 ble.gap().onDisconnection(disconnectionCallback);
kenjiArai 0:0ef6455cbb4d 411
kenjiArai 0:0ef6455cbb4d 412 // Device role ****************************************************
kenjiArai 0:0ef6455cbb4d 413 ble.gattServer().onDataWritten(onReceivedDataFromCentralCallback);
kenjiArai 0:0ef6455cbb4d 414 //ble.gattServer().onDataSent(gattServerOnDataSent);
kenjiArai 0:0ef6455cbb4d 415
kenjiArai 0:0ef6455cbb4d 416 UARTService uartService(ble);
kenjiArai 0:0ef6455cbb4d 417 uartServicePtr = &uartService;
kenjiArai 0:0ef6455cbb4d 418
kenjiArai 0:0ef6455cbb4d 419 // setup advertising
kenjiArai 0:0ef6455cbb4d 420 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT
kenjiArai 0:0ef6455cbb4d 421 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name
kenjiArai 0:0ef6455cbb4d 422 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet
kenjiArai 0:0ef6455cbb4d 423 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type
kenjiArai 0:0ef6455cbb4d 424 ble.setAdvertisingInterval(100);
kenjiArai 0:0ef6455cbb4d 425
kenjiArai 0:0ef6455cbb4d 426 // Central role ****************************************************
kenjiArai 0:0ef6455cbb4d 427 ble.gattClient().onHVX(onReceivedDataFromDeviceCallback);
kenjiArai 0:0ef6455cbb4d 428 ble.gap().setScanParams(500, 450);
kenjiArai 0:0ef6455cbb4d 429
kenjiArai 0:0ef6455cbb4d 430
kenjiArai 0:0ef6455cbb4d 431 // start advertising and scan
kenjiArai 0:0ef6455cbb4d 432 ble.startAdvertising();
kenjiArai 0:0ef6455cbb4d 433 ble.gap().startScan(advertisementCallback);
kenjiArai 0:0ef6455cbb4d 434
kenjiArai 0:0ef6455cbb4d 435 while (true)
kenjiArai 0:0ef6455cbb4d 436 {
kenjiArai 0:0ef6455cbb4d 437 // allow notifications from device
kenjiArai 0:0ef6455cbb4d 438 if (foundUartRXCharacteristic && !ble.gattClient().isServiceDiscoveryActive())
kenjiArai 0:0ef6455cbb4d 439 {
kenjiArai 0:0ef6455cbb4d 440 foundUartRXCharacteristic = false; /* need to do the following only once */
kenjiArai 0:0ef6455cbb4d 441
kenjiArai 0:0ef6455cbb4d 442 uint16_t value = BLE_HVX_NOTIFICATION;
kenjiArai 0:0ef6455cbb4d 443 int ret = ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
kenjiArai 0:0ef6455cbb4d 444 connectionHandle,
kenjiArai 0:0ef6455cbb4d 445 uartRXCharacteristic.getValueHandle() + 1, /* HACK Alert. We're assuming that CCCD descriptor immediately follows the value attribute. */
kenjiArai 0:0ef6455cbb4d 446 sizeof(uint16_t), /* HACK Alert! size should be made into a BLE_API constant. */
kenjiArai 0:0ef6455cbb4d 447 reinterpret_cast<const uint8_t *>(&value));
kenjiArai 0:0ef6455cbb4d 448
kenjiArai 0:0ef6455cbb4d 449 if (ret == BLE_ERROR_NONE)
kenjiArai 0:0ef6455cbb4d 450 {
kenjiArai 0:0ef6455cbb4d 451 pc.printf("\r\ndevice notifications enabled\r\n");
kenjiArai 0:0ef6455cbb4d 452 }
kenjiArai 0:0ef6455cbb4d 453 else
kenjiArai 0:0ef6455cbb4d 454 {
kenjiArai 0:0ef6455cbb4d 455 switch (ret)
kenjiArai 0:0ef6455cbb4d 456 {
kenjiArai 0:0ef6455cbb4d 457 case BLE_STACK_BUSY:
kenjiArai 0:0ef6455cbb4d 458 foundUartRXCharacteristic = true; // retry later
kenjiArai 0:0ef6455cbb4d 459 break;
kenjiArai 0:0ef6455cbb4d 460 case BLE_ERROR_NO_MEM:
kenjiArai 0:0ef6455cbb4d 461 foundUartRXCharacteristic = true; // retry later
kenjiArai 0:0ef6455cbb4d 462 break;
kenjiArai 0:0ef6455cbb4d 463 case BLE_ERROR_INVALID_STATE:
kenjiArai 0:0ef6455cbb4d 464 pc.printf("\r\ndevice notifications enable failed\r\n");
kenjiArai 0:0ef6455cbb4d 465 break;
kenjiArai 0:0ef6455cbb4d 466 default:
kenjiArai 0:0ef6455cbb4d 467 break;
kenjiArai 0:0ef6455cbb4d 468 }
kenjiArai 0:0ef6455cbb4d 469 }
kenjiArai 0:0ef6455cbb4d 470
kenjiArai 0:0ef6455cbb4d 471 if (!foundUartRXCharacteristic)
kenjiArai 0:0ef6455cbb4d 472 {
kenjiArai 0:0ef6455cbb4d 473 if (central_handle == -1)
kenjiArai 0:0ef6455cbb4d 474 {
kenjiArai 0:0ef6455cbb4d 475 ble.startAdvertising();
kenjiArai 0:0ef6455cbb4d 476 }
kenjiArai 0:0ef6455cbb4d 477 }
kenjiArai 0:0ef6455cbb4d 478 }
kenjiArai 0:0ef6455cbb4d 479
kenjiArai 0:0ef6455cbb4d 480 // while a new char from computer is available
kenjiArai 0:0ef6455cbb4d 481 while (rx_char != -1)
kenjiArai 0:0ef6455cbb4d 482 {
kenjiArai 0:0ef6455cbb4d 483 uint8_t temp[20];
kenjiArai 0:0ef6455cbb4d 484 int length = 1;
kenjiArai 0:0ef6455cbb4d 485
kenjiArai 0:0ef6455cbb4d 486 uint8_t command = rx_char;
kenjiArai 0:0ef6455cbb4d 487 rx_char = -1;
kenjiArai 0:0ef6455cbb4d 488
kenjiArai 0:0ef6455cbb4d 489 // if special char to test a 20 bytes frame
kenjiArai 0:0ef6455cbb4d 490 /*
kenjiArai 0:0ef6455cbb4d 491 if (command == '*')
kenjiArai 0:0ef6455cbb4d 492 {
kenjiArai 0:0ef6455cbb4d 493 pc.printf("20 chars\r\n");
kenjiArai 0:0ef6455cbb4d 494
kenjiArai 0:0ef6455cbb4d 495 int c = 0;
kenjiArai 0:0ef6455cbb4d 496 for (c = 0; c < 20; c++)
kenjiArai 0:0ef6455cbb4d 497 {
kenjiArai 0:0ef6455cbb4d 498 temp[c] = 'a' + c;
kenjiArai 0:0ef6455cbb4d 499 }
kenjiArai 0:0ef6455cbb4d 500 length = 20;
kenjiArai 0:0ef6455cbb4d 501 }
kenjiArai 0:0ef6455cbb4d 502 else
kenjiArai 0:0ef6455cbb4d 503 {
kenjiArai 0:0ef6455cbb4d 504 temp[0] = command;
kenjiArai 0:0ef6455cbb4d 505 }
kenjiArai 0:0ef6455cbb4d 506 */
kenjiArai 0:0ef6455cbb4d 507 temp[0] = command;
kenjiArai 0:0ef6455cbb4d 508
kenjiArai 0:0ef6455cbb4d 509 // to central
kenjiArai 0:0ef6455cbb4d 510 //if (command == '1')
kenjiArai 0:0ef6455cbb4d 511 {
kenjiArai 0:0ef6455cbb4d 512 if (central_handle != -1)
kenjiArai 0:0ef6455cbb4d 513 {
kenjiArai 0:0ef6455cbb4d 514 // device to central
kenjiArai 0:0ef6455cbb4d 515 while (1)
kenjiArai 0:0ef6455cbb4d 516 {
kenjiArai 0:0ef6455cbb4d 517 if (central_handle == -1)
kenjiArai 0:0ef6455cbb4d 518 {
kenjiArai 0:0ef6455cbb4d 519 pc.printf("\r\ndisconnected 1 (to central)\r\n");
kenjiArai 0:0ef6455cbb4d 520 break;
kenjiArai 0:0ef6455cbb4d 521 }
kenjiArai 0:0ef6455cbb4d 522 if (!ble.gap().getState().connected)
kenjiArai 0:0ef6455cbb4d 523 {
kenjiArai 0:0ef6455cbb4d 524 pc.printf("\r\ndisconnected 2 (to central)\r\n");
kenjiArai 0:0ef6455cbb4d 525 break;
kenjiArai 0:0ef6455cbb4d 526 }
kenjiArai 0:0ef6455cbb4d 527 int ret = ble.gattServer().write(uartServicePtr->getRXCharacteristicHandle(), temp, length);
kenjiArai 0:0ef6455cbb4d 528
kenjiArai 0:0ef6455cbb4d 529 if (ret == BLE_ERROR_NONE)
kenjiArai 0:0ef6455cbb4d 530 {
kenjiArai 0:0ef6455cbb4d 531 //pc.printf("\r\nok (to central)\r\n");
kenjiArai 0:0ef6455cbb4d 532 break;
kenjiArai 0:0ef6455cbb4d 533 }
kenjiArai 0:0ef6455cbb4d 534 else if (ret == BLE_STACK_BUSY)
kenjiArai 0:0ef6455cbb4d 535 {
kenjiArai 0:0ef6455cbb4d 536 //pc.printf("\r\nbusy (to central)\r\n");
kenjiArai 0:0ef6455cbb4d 537 //break;
kenjiArai 0:0ef6455cbb4d 538 }
kenjiArai 0:0ef6455cbb4d 539 else if (ret == BLE_ERROR_OPERATION_NOT_PERMITTED)
kenjiArai 0:0ef6455cbb4d 540 {
kenjiArai 0:0ef6455cbb4d 541 pc.printf("\r\nnot permitted (to central)\r\n");
kenjiArai 0:0ef6455cbb4d 542 break;
kenjiArai 0:0ef6455cbb4d 543 }
kenjiArai 0:0ef6455cbb4d 544 else if (ret == BLE_ERROR_INVALID_STATE)
kenjiArai 0:0ef6455cbb4d 545 {
kenjiArai 0:0ef6455cbb4d 546 pc.printf("\r\ninvalid state (to central)\r\n");
kenjiArai 0:0ef6455cbb4d 547 break;
kenjiArai 0:0ef6455cbb4d 548 }
kenjiArai 0:0ef6455cbb4d 549 else
kenjiArai 0:0ef6455cbb4d 550 {
kenjiArai 0:0ef6455cbb4d 551 pc.printf("\r\ncode %d (to central)\r\n", ret);
kenjiArai 0:0ef6455cbb4d 552 break;
kenjiArai 0:0ef6455cbb4d 553 }
kenjiArai 0:0ef6455cbb4d 554 }
kenjiArai 0:0ef6455cbb4d 555 }
kenjiArai 0:0ef6455cbb4d 556 else
kenjiArai 0:0ef6455cbb4d 557 {
kenjiArai 0:0ef6455cbb4d 558 pc.printf("\r\nnot connected with central\r\n");
kenjiArai 0:0ef6455cbb4d 559 }
kenjiArai 0:0ef6455cbb4d 560 }
kenjiArai 0:0ef6455cbb4d 561
kenjiArai 0:0ef6455cbb4d 562 // to device
kenjiArai 0:0ef6455cbb4d 563 //if (command == '2')
kenjiArai 0:0ef6455cbb4d 564 {
kenjiArai 0:0ef6455cbb4d 565 if (device_handle != -1)
kenjiArai 0:0ef6455cbb4d 566 {
kenjiArai 0:0ef6455cbb4d 567 // central to device
kenjiArai 0:0ef6455cbb4d 568 while (1)
kenjiArai 0:0ef6455cbb4d 569 {
kenjiArai 0:0ef6455cbb4d 570 if (device_handle == -1)
kenjiArai 0:0ef6455cbb4d 571 {
kenjiArai 0:0ef6455cbb4d 572 pc.printf("\r\ndisconnected (to device)\r\n");
kenjiArai 0:0ef6455cbb4d 573 break;
kenjiArai 0:0ef6455cbb4d 574 }
kenjiArai 0:0ef6455cbb4d 575 int ret = uartTXCharacteristic.write(length, temp);
kenjiArai 0:0ef6455cbb4d 576 if (ret == BLE_ERROR_NONE)
kenjiArai 0:0ef6455cbb4d 577 {
kenjiArai 0:0ef6455cbb4d 578 //pc.printf("\r\nok (to device)\r\n");
kenjiArai 0:0ef6455cbb4d 579 break;
kenjiArai 0:0ef6455cbb4d 580 }
kenjiArai 0:0ef6455cbb4d 581 else if (ret == BLE_STACK_BUSY)
kenjiArai 0:0ef6455cbb4d 582 {
kenjiArai 0:0ef6455cbb4d 583 //pc.printf("\r\nbusy (to device)\r\n");
kenjiArai 0:0ef6455cbb4d 584 //break;
kenjiArai 0:0ef6455cbb4d 585 }
kenjiArai 0:0ef6455cbb4d 586 else if (ret == BLE_ERROR_OPERATION_NOT_PERMITTED)
kenjiArai 0:0ef6455cbb4d 587 {
kenjiArai 0:0ef6455cbb4d 588 pc.printf("\r\nnot permitted (to device)\r\n");
kenjiArai 0:0ef6455cbb4d 589 break;
kenjiArai 0:0ef6455cbb4d 590 }
kenjiArai 0:0ef6455cbb4d 591 else if (ret == BLE_ERROR_INVALID_STATE)
kenjiArai 0:0ef6455cbb4d 592 {
kenjiArai 0:0ef6455cbb4d 593 pc.printf("\r\ninvalid state (to device)\r\n");
kenjiArai 0:0ef6455cbb4d 594 break;
kenjiArai 0:0ef6455cbb4d 595 }
kenjiArai 0:0ef6455cbb4d 596 else
kenjiArai 0:0ef6455cbb4d 597 {
kenjiArai 0:0ef6455cbb4d 598 pc.printf("\r\ncode %d (to device)\r\n", ret);
kenjiArai 0:0ef6455cbb4d 599 break;
kenjiArai 0:0ef6455cbb4d 600 }
kenjiArai 0:0ef6455cbb4d 601 }
kenjiArai 0:0ef6455cbb4d 602 }
kenjiArai 0:0ef6455cbb4d 603 else
kenjiArai 0:0ef6455cbb4d 604 {
kenjiArai 0:0ef6455cbb4d 605 pc.printf("\r\nnot connected with device\r\n");
kenjiArai 0:0ef6455cbb4d 606 }
kenjiArai 0:0ef6455cbb4d 607 }
kenjiArai 0:0ef6455cbb4d 608 }
kenjiArai 0:0ef6455cbb4d 609
kenjiArai 0:0ef6455cbb4d 610 ble.waitForEvent(); // save power
kenjiArai 0:0ef6455cbb4d 611 }
kenjiArai 0:0ef6455cbb4d 612 }
kenjiArai 2:6fb0b87b041d 613
kenjiArai 0:0ef6455cbb4d 614 #endif