|
@@ -3,7 +3,6 @@
|
3
|
3
|
*
|
4
|
4
|
* https://github.com/raspberrypi/pico-examples/blob/master/pico_w/bt/standalone/client.c
|
5
|
5
|
* https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html
|
6
|
|
- * https://github.com/bluekitchen/btstack/blob/master/example/gap_inquiry.c
|
7
|
6
|
*
|
8
|
7
|
* Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
|
9
|
8
|
*
|
|
@@ -27,8 +26,6 @@
|
27
|
26
|
#include "util.h"
|
28
|
27
|
#include "ble.h"
|
29
|
28
|
|
30
|
|
-#define GAP_INQUIRY_INTERVAL 5 // *1.28s
|
31
|
|
-
|
32
|
29
|
enum ble_state {
|
33
|
30
|
TC_OFF = 0,
|
34
|
31
|
TC_IDLE,
|
|
@@ -46,9 +43,7 @@ static struct ble_scan_result scans[BLE_MAX_SCAN_RESULTS] = {0};
|
46
|
43
|
|
47
|
44
|
// TODO scan result entries are not aging out
|
48
|
45
|
|
49
|
|
-static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type,
|
50
|
|
- int8_t rssi, uint8_t scan_mode,
|
51
|
|
- uint16_t clock_offset, uint32_t class) {
|
|
46
|
+static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type, int8_t rssi) {
|
52
|
47
|
int unused = -1;
|
53
|
48
|
|
54
|
49
|
for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
|
|
@@ -60,23 +55,8 @@ static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type,
|
60
|
55
|
}
|
61
|
56
|
|
62
|
57
|
if (memcmp(addr, scans[i].addr, sizeof(bd_addr_t)) == 0) {
|
63
|
|
- // already in list, just update changed values
|
|
58
|
+ // already in list, just update time for aging
|
64
|
59
|
scans[i].time = to_ms_since_boot(get_absolute_time());
|
65
|
|
- if (scans[i].type == 0) {
|
66
|
|
- scans[i].type = type;
|
67
|
|
- }
|
68
|
|
- if (scans[i].rssi == 0) {
|
69
|
|
- scans[i].rssi = rssi;
|
70
|
|
- }
|
71
|
|
- if (scans[i].page_scan_repetition_mode == 0) {
|
72
|
|
- scans[i].page_scan_repetition_mode = scan_mode;
|
73
|
|
- }
|
74
|
|
- if (scans[i].clock_offset == 0) {
|
75
|
|
- scans[i].clock_offset = clock_offset;
|
76
|
|
- }
|
77
|
|
- if (scans[i].class == 0) {
|
78
|
|
- scans[i].class = class;
|
79
|
|
- }
|
80
|
60
|
return;
|
81
|
61
|
}
|
82
|
62
|
}
|
|
@@ -89,13 +69,9 @@ static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type,
|
89
|
69
|
debug("new device with addr %s", bd_addr_to_str(addr));
|
90
|
70
|
scans[unused].set = true;
|
91
|
71
|
scans[unused].time = to_ms_since_boot(get_absolute_time());
|
92
|
|
- scans[unused].state = BLE_NAME_REQUEST;
|
93
|
72
|
memcpy(scans[unused].addr, addr, sizeof(bd_addr_t));
|
94
|
73
|
scans[unused].type = type;
|
95
|
74
|
scans[unused].rssi = rssi;
|
96
|
|
- scans[unused].page_scan_repetition_mode = scan_mode;
|
97
|
|
- scans[unused].clock_offset = clock_offset;
|
98
|
|
- scans[unused].class = class;
|
99
|
75
|
scans[unused].name[0] = '\0';
|
100
|
76
|
}
|
101
|
77
|
|
|
@@ -121,27 +97,6 @@ static void hci_scan_result_add_name(bd_addr_t addr, const uint8_t *data, uint8_
|
121
|
97
|
debug("no matching entry for %s to add name '%.*s' to", bd_addr_to_str(addr), data_size, data);
|
122
|
98
|
}
|
123
|
99
|
|
124
|
|
-static void hci_continue_name_requests(void) {
|
125
|
|
- for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
|
126
|
|
- if (!scans[i].set) {
|
127
|
|
- continue;
|
128
|
|
- }
|
129
|
|
-
|
130
|
|
- if (scans[i].state == BLE_NAME_REQUEST) {
|
131
|
|
- scans[i].state = BLE_NAME_INQUIRED;
|
132
|
|
- debug("Inquire remote name of %s", bd_addr_to_str(scans[i].addr));
|
133
|
|
- gap_remote_name_request(scans[i].addr,
|
134
|
|
- scans[i].page_scan_repetition_mode,
|
135
|
|
- scans[i].clock_offset | 0x8000);
|
136
|
|
- return;
|
137
|
|
- }
|
138
|
|
- }
|
139
|
|
-
|
140
|
|
- if (state == TC_W4_SCAN_RESULT) {
|
141
|
|
- gap_inquiry_start(GAP_INQUIRY_INTERVAL);
|
142
|
|
- }
|
143
|
|
-}
|
144
|
|
-
|
145
|
100
|
static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
|
146
|
101
|
UNUSED(size);
|
147
|
102
|
UNUSED(channel);
|
|
@@ -188,7 +143,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
|
188
|
143
|
rssi = (int8_t)gap_event_advertising_report_get_rssi(packet);
|
189
|
144
|
|
190
|
145
|
// add data received so far
|
191
|
|
- hci_add_scan_result(addr, type, rssi, 0, 0, 0);
|
|
146
|
+ hci_add_scan_result(addr, type, rssi);
|
192
|
147
|
|
193
|
148
|
// get advertisement from report event
|
194
|
149
|
const uint8_t *adv_data = gap_event_advertising_report_get_data(packet);
|
|
@@ -205,11 +160,11 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
|
205
|
160
|
switch (data_type) {
|
206
|
161
|
case BLUETOOTH_DATA_TYPE_SHORTENED_LOCAL_NAME:
|
207
|
162
|
case BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME:
|
208
|
|
- // unfortunately not the name we're interested in for our targets...
|
209
|
163
|
hci_scan_result_add_name(addr, data, data_size);
|
210
|
164
|
break;
|
211
|
165
|
|
212
|
166
|
case BLUETOOTH_DATA_TYPE_FLAGS:
|
|
167
|
+ case BLUETOOTH_DATA_TYPE_TX_POWER_LEVEL:
|
213
|
168
|
case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS:
|
214
|
169
|
case BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID:
|
215
|
170
|
case BLUETOOTH_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
|
|
@@ -225,82 +180,6 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
|
225
|
180
|
break;
|
226
|
181
|
}
|
227
|
182
|
|
228
|
|
- case GAP_EVENT_INQUIRY_RESULT: {
|
229
|
|
- bd_addr_t addr;
|
230
|
|
- gap_event_inquiry_result_get_bd_addr(packet, addr);
|
231
|
|
-
|
232
|
|
- uint8_t scan_mode;
|
233
|
|
- scan_mode = gap_event_inquiry_result_get_page_scan_repetition_mode(packet);
|
234
|
|
-
|
235
|
|
- uint16_t clock_offset;
|
236
|
|
- clock_offset = gap_event_inquiry_result_get_clock_offset(packet);
|
237
|
|
-
|
238
|
|
- uint32_t class;
|
239
|
|
- class = gap_event_inquiry_result_get_class_of_device(packet);
|
240
|
|
-
|
241
|
|
- int8_t rssi = 0;
|
242
|
|
- if (gap_event_inquiry_result_get_rssi_available(packet)) {
|
243
|
|
- rssi = (int8_t)gap_event_inquiry_result_get_rssi(packet);
|
244
|
|
- }
|
245
|
|
-
|
246
|
|
- // add data received so far
|
247
|
|
- hci_add_scan_result(addr, 0, rssi, scan_mode, clock_offset, class);
|
248
|
|
-
|
249
|
|
- if (gap_event_inquiry_result_get_name_available(packet)) {
|
250
|
|
- const uint8_t *data = gap_event_inquiry_result_get_name(packet);
|
251
|
|
- uint8_t data_size = gap_event_inquiry_result_get_name_len(packet);
|
252
|
|
- // still not the name we need
|
253
|
|
- hci_scan_result_add_name(addr, data, data_size);
|
254
|
|
- } else {
|
255
|
|
- for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
|
256
|
|
- if (!scans[i].set) {
|
257
|
|
- continue;
|
258
|
|
- }
|
259
|
|
- if (memcmp(addr, scans[i].addr, sizeof(bd_addr_t)) == 0) {
|
260
|
|
- scans[i].state = BLE_NAME_REQUEST;
|
261
|
|
- break;
|
262
|
|
- }
|
263
|
|
- }
|
264
|
|
- }
|
265
|
|
- break;
|
266
|
|
- }
|
267
|
|
-
|
268
|
|
- case HCI_EVENT_EXTENDED_INQUIRY_RESPONSE:
|
269
|
|
- // TODO ?
|
270
|
|
- break;
|
271
|
|
-
|
272
|
|
- case GAP_EVENT_INQUIRY_COMPLETE:
|
273
|
|
- // trigger re-read of all names
|
274
|
|
- for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
|
275
|
|
- if (scans[i].state == BLE_NAME_INQUIRED) {
|
276
|
|
- scans[i].state = BLE_NAME_REQUEST;
|
277
|
|
- }
|
278
|
|
- }
|
279
|
|
- hci_continue_name_requests();
|
280
|
|
- break;
|
281
|
|
-
|
282
|
|
- case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: {
|
283
|
|
- bd_addr_t addr;
|
284
|
|
- reverse_bd_addr(&packet[3], addr);
|
285
|
|
- if (packet[2] != 0) {
|
286
|
|
- debug("page timeout receiving name from %s", bd_addr_to_str(addr));
|
287
|
|
- } else {
|
288
|
|
- for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
|
289
|
|
- if (!scans[i].set) {
|
290
|
|
- continue;
|
291
|
|
- }
|
292
|
|
- if (memcmp(addr, scans[i].addr, sizeof(bd_addr_t)) == 0) {
|
293
|
|
- scans[i].state = BLE_NAME_FETCHED;
|
294
|
|
- // also not the name we are looking for
|
295
|
|
- hci_scan_result_add_name(addr, &packet[9], strlen((char *)&packet[9]));
|
296
|
|
- break;
|
297
|
|
- }
|
298
|
|
- }
|
299
|
|
- }
|
300
|
|
- hci_continue_name_requests();
|
301
|
|
- break;
|
302
|
|
- }
|
303
|
|
-
|
304
|
183
|
case HCI_EVENT_LE_META:
|
305
|
184
|
switch (hci_event_le_meta_get_subevent_code(packet)) {
|
306
|
185
|
case HCI_SUBEVENT_LE_ADVERTISING_REPORT:
|
|
@@ -334,8 +213,6 @@ void ble_init(void) {
|
334
|
213
|
|
335
|
214
|
gatt_client_init();
|
336
|
215
|
|
337
|
|
- hci_set_inquiry_mode(INQUIRY_MODE_RSSI_AND_EIR);
|
338
|
|
-
|
339
|
216
|
hci_event_callback_registration.callback = &hci_event_handler;
|
340
|
217
|
hci_add_event_handler(&hci_event_callback_registration);
|
341
|
218
|
|
|
@@ -350,18 +227,13 @@ void ble_scan(enum ble_scan_mode mode) {
|
350
|
227
|
debug("stopping BLE scan");
|
351
|
228
|
state = TC_IDLE;
|
352
|
229
|
gap_stop_scan();
|
353
|
|
- gap_inquiry_stop();
|
354
|
230
|
break;
|
355
|
231
|
|
356
|
232
|
case BLE_SCAN_ON:
|
357
|
233
|
debug("starting BLE scan");
|
358
|
234
|
state = TC_W4_SCAN_RESULT;
|
359
|
|
-
|
360
|
|
- gap_set_scan_parameters(0,0x0030, 0x0030);
|
|
235
|
+ gap_set_scan_parameters(1, 0x0030, 0x0030);
|
361
|
236
|
gap_start_scan();
|
362
|
|
-
|
363
|
|
- // also start an inquiry scan
|
364
|
|
- gap_inquiry_start(GAP_INQUIRY_INTERVAL);
|
365
|
237
|
break;
|
366
|
238
|
|
367
|
239
|
case BLE_SCAN_TOGGLE:
|