
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/#
original.cpp@4:342b665fb826, 2018-02-09 (annotated)
- Committer:
- kenjiArai
- Date:
- Fri Feb 09 22:31:19 2018 +0000
- Revision:
- 4:342b665fb826
- Parent:
- 2:6fb0b87b041d
Not set mac addr but use device name
Who changed what in which revision?
User | Revision | Line number | New 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 |