|
@@ -33,7 +33,9 @@ enum ble_state {
|
33
|
33
|
TC_IDLE,
|
34
|
34
|
TC_W4_SCAN,
|
35
|
35
|
TC_W4_CONNECT,
|
36
|
|
- TC_READY
|
|
36
|
+ TC_READY,
|
|
37
|
+ TC_W4_READ,
|
|
38
|
+ TC_READ_COMPLETE,
|
37
|
39
|
};
|
38
|
40
|
|
39
|
41
|
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
|
@@ -41,6 +43,8 @@ static hci_con_handle_t connection_handle;
|
41
|
43
|
|
42
|
44
|
static enum ble_state state = TC_OFF;
|
43
|
45
|
static struct ble_scan_result scans[BLE_MAX_SCAN_RESULTS] = {0};
|
|
46
|
+static uint16_t read_len = 0;
|
|
47
|
+static uint8_t read_buff[BLE_MAX_VALUE_LEN] = {0};
|
44
|
48
|
|
45
|
49
|
static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type, int8_t rssi) {
|
46
|
50
|
int unused = -1;
|
|
@@ -101,6 +105,9 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
|
101
|
105
|
UNUSED(size);
|
102
|
106
|
UNUSED(channel);
|
103
|
107
|
|
|
108
|
+ //debug("type=0x%02X size=%d", packet_type, size);
|
|
109
|
+ //hexdump(packet, size);
|
|
110
|
+
|
104
|
111
|
if (packet_type != HCI_EVENT_PACKET) {
|
105
|
112
|
//debug("unexpected packet 0x%02X", packet_type);
|
106
|
113
|
return;
|
|
@@ -187,6 +194,30 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
|
187
|
194
|
state = TC_IDLE;
|
188
|
195
|
break;
|
189
|
196
|
|
|
197
|
+ case GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT:
|
|
198
|
+ if (state != TC_W4_READ) {
|
|
199
|
+ debug("gatt query result in invalid state %d", state);
|
|
200
|
+ return;
|
|
201
|
+ }
|
|
202
|
+ uint16_t len = gatt_event_characteristic_value_query_result_get_value_length(packet);
|
|
203
|
+ if ((read_len + len) > BLE_MAX_VALUE_LEN) {
|
|
204
|
+ debug("not enough space for value (%d + %d > %d)", read_len, len, BLE_MAX_VALUE_LEN);
|
|
205
|
+ return;
|
|
206
|
+ }
|
|
207
|
+ memcpy(read_buff + read_len,
|
|
208
|
+ gatt_event_characteristic_value_query_result_get_value(packet),
|
|
209
|
+ len);
|
|
210
|
+ read_len += len;
|
|
211
|
+ break;
|
|
212
|
+
|
|
213
|
+ case GATT_EVENT_QUERY_COMPLETE:
|
|
214
|
+ if (state != TC_W4_READ) {
|
|
215
|
+ debug("gatt query complete in invalid state %d", state);
|
|
216
|
+ return;
|
|
217
|
+ }
|
|
218
|
+ state = TC_READ_COMPLETE;
|
|
219
|
+ break;
|
|
220
|
+
|
190
|
221
|
default:
|
191
|
222
|
//debug("unexpected event 0x%02X", hci_event_packet_get_type(packet));
|
192
|
223
|
break;
|
|
@@ -272,7 +303,7 @@ void ble_scan(enum ble_scan_mode mode) {
|
272
|
303
|
cyw43_thread_exit();
|
273
|
304
|
}
|
274
|
305
|
|
275
|
|
-int ble_get_scan_results(struct ble_scan_result *buf, uint len) {
|
|
306
|
+int32_t ble_get_scan_results(struct ble_scan_result *buf, uint16_t len) {
|
276
|
307
|
if (!buf || (len <= 0)) {
|
277
|
308
|
return -1;
|
278
|
309
|
}
|
|
@@ -284,8 +315,8 @@ int ble_get_scan_results(struct ble_scan_result *buf, uint len) {
|
284
|
315
|
return -1;
|
285
|
316
|
}
|
286
|
317
|
|
287
|
|
- uint pos = 0;
|
288
|
|
- for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
|
|
318
|
+ uint16_t pos = 0;
|
|
319
|
+ for (uint16_t i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
|
289
|
320
|
if (!scans[i].set) {
|
290
|
321
|
continue;
|
291
|
322
|
}
|
|
@@ -337,6 +368,17 @@ void ble_connect(bd_addr_t addr, bd_addr_type_t type) {
|
337
|
368
|
cyw43_thread_exit();
|
338
|
369
|
}
|
339
|
370
|
|
|
371
|
+bool ble_is_connected(void) {
|
|
372
|
+ cyw43_thread_enter();
|
|
373
|
+
|
|
374
|
+ bool v = (state == TC_READY)
|
|
375
|
+ || (state == TC_W4_READ)
|
|
376
|
+ || (state == TC_READ_COMPLETE);
|
|
377
|
+
|
|
378
|
+ cyw43_thread_exit();
|
|
379
|
+ return v;
|
|
380
|
+}
|
|
381
|
+
|
340
|
382
|
void ble_disconnect(void) {
|
341
|
383
|
cyw43_thread_enter();
|
342
|
384
|
|
|
@@ -346,3 +388,62 @@ void ble_disconnect(void) {
|
346
|
388
|
|
347
|
389
|
cyw43_thread_exit();
|
348
|
390
|
}
|
|
391
|
+
|
|
392
|
+int32_t ble_read(const uint8_t *uuid, uint8_t *buff, uint16_t buff_len) {
|
|
393
|
+ cyw43_thread_enter();
|
|
394
|
+
|
|
395
|
+ if (state != TC_READY) {
|
|
396
|
+ cyw43_thread_exit();
|
|
397
|
+ debug("invalid state for read (%d)", state);
|
|
398
|
+ return -1;
|
|
399
|
+ }
|
|
400
|
+
|
|
401
|
+ uint8_t r = gatt_client_read_value_of_characteristics_by_uuid128(hci_event_handler,
|
|
402
|
+ connection_handle,
|
|
403
|
+ 0x0001, 0xFFFF, uuid);
|
|
404
|
+ if (r != ERROR_CODE_SUCCESS) {
|
|
405
|
+ cyw43_thread_exit();
|
|
406
|
+ debug("gatt read failed %d", r);
|
|
407
|
+ return -2;
|
|
408
|
+ }
|
|
409
|
+
|
|
410
|
+ state = TC_W4_READ;
|
|
411
|
+ read_len = 0;
|
|
412
|
+ cyw43_thread_exit();
|
|
413
|
+
|
|
414
|
+ while (1) {
|
|
415
|
+ sleep_ms(1);
|
|
416
|
+
|
|
417
|
+ // TODO timeout
|
|
418
|
+
|
|
419
|
+ cyw43_thread_enter();
|
|
420
|
+ enum ble_state state_cached = state;
|
|
421
|
+ cyw43_thread_exit();
|
|
422
|
+
|
|
423
|
+ if (state_cached == TC_READ_COMPLETE) {
|
|
424
|
+ break;
|
|
425
|
+ }
|
|
426
|
+ }
|
|
427
|
+
|
|
428
|
+ cyw43_thread_enter();
|
|
429
|
+
|
|
430
|
+ state = TC_READY;
|
|
431
|
+
|
|
432
|
+ if (read_len > buff_len) {
|
|
433
|
+ debug("buffer too short (%d < %d)", buff_len, read_len);
|
|
434
|
+ cyw43_thread_exit();
|
|
435
|
+ return -3;
|
|
436
|
+ }
|
|
437
|
+
|
|
438
|
+ memcpy(buff, read_buff, read_len);
|
|
439
|
+
|
|
440
|
+ cyw43_thread_exit();
|
|
441
|
+ return read_len;
|
|
442
|
+}
|
|
443
|
+
|
|
444
|
+int32_t ble_write(const uint8_t *uuid, uint8_t *buff, uint16_t buff_len) {
|
|
445
|
+ UNUSED(uuid);
|
|
446
|
+ UNUSED(buff);
|
|
447
|
+ UNUSED(buff_len);
|
|
448
|
+ return -1;
|
|
449
|
+}
|