Browse Source

more work on ble scan. still not finding target device name, even with gap inquiry.

Thomas Buck 1 year ago
parent
commit
8e13f7b0d8
6 changed files with 324 additions and 12 deletions
  1. 4
    0
      CMakeLists.txt
  2. 28
    1
      include/ble.h
  3. 1
    1
      include/util.h
  4. 274
    9
      src/ble.c
  5. 16
    0
      src/console.c
  6. 1
    1
      src/util.c

+ 4
- 0
CMakeLists.txt View File

94
 set_source_files_properties(pico-sdk/lib/btstack/src/ble/sm.c PROPERTIES COMPILE_FLAGS -Wno-unused-parameter)
94
 set_source_files_properties(pico-sdk/lib/btstack/src/ble/sm.c PROPERTIES COMPILE_FLAGS -Wno-unused-parameter)
95
 set_source_files_properties(pico-sdk/lib/btstack/src/btstack_hid_parser.c PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized)
95
 set_source_files_properties(pico-sdk/lib/btstack/src/btstack_hid_parser.c PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized)
96
 set_source_files_properties(pico-sdk/src/rp2_common/pico_cyw43_driver/cyw43_driver.c PROPERTIES COMPILE_FLAGS -Wno-unused-parameter)
96
 set_source_files_properties(pico-sdk/src/rp2_common/pico_cyw43_driver/cyw43_driver.c PROPERTIES COMPILE_FLAGS -Wno-unused-parameter)
97
+set_source_files_properties(pico-sdk/lib/btstack/src/classic/avdtp_util.c PROPERTIES COMPILE_FLAGS -Wno-unused-parameter)
98
+set_source_files_properties(pico-sdk/lib/btstack/src/classic/goep_client.c PROPERTIES COMPILE_FLAGS -Wno-unused-parameter)
99
+set_source_files_properties(pico-sdk/lib/btstack/src/classic/goep_server.c PROPERTIES COMPILE_FLAGS -Wno-unused-parameter)
97
 
100
 
98
 # pull in common dependencies
101
 # pull in common dependencies
99
 target_link_libraries(gadget
102
 target_link_libraries(gadget
106
     hardware_gpio
109
     hardware_gpio
107
     hardware_pwm
110
     hardware_pwm
108
     pico_btstack_ble
111
     pico_btstack_ble
112
+    pico_btstack_classic
109
     pico_btstack_cyw43
113
     pico_btstack_cyw43
110
     pico_cyw43_arch_threadsafe_background
114
     pico_cyw43_arch_threadsafe_background
111
 )
115
 )

+ 28
- 1
include/ble.h View File

19
 #ifndef __BLE_H__
19
 #ifndef __BLE_H__
20
 #define __BLE_H__
20
 #define __BLE_H__
21
 
21
 
22
-void ble_init(void);
22
+#include "btstack.h"
23
+
24
+#define BLE_MAX_NAME_LENGTH 32
25
+#define BLE_MAX_SCAN_RESULTS 32
23
 
26
 
24
 enum ble_scan_mode {
27
 enum ble_scan_mode {
25
     BLE_SCAN_OFF    = 0,
28
     BLE_SCAN_OFF    = 0,
26
     BLE_SCAN_ON     = 1,
29
     BLE_SCAN_ON     = 1,
27
     BLE_SCAN_TOGGLE = 2,
30
     BLE_SCAN_TOGGLE = 2,
28
 };
31
 };
32
+
33
+enum ble_remote_name_state {
34
+    BLE_NAME_REQUEST = 0,
35
+    BLE_NAME_INQUIRED,
36
+    BLE_NAME_FETCHED,
37
+};
38
+
39
+struct ble_scan_result {
40
+    bool set;
41
+    uint32_t time;
42
+    enum ble_remote_name_state state;
43
+
44
+    bd_addr_t addr;
45
+    bd_addr_type_t type;
46
+    int8_t rssi;
47
+    uint8_t page_scan_repetition_mode;
48
+    uint16_t clock_offset;
49
+    uint32_t class;
50
+
51
+    char name[BLE_MAX_NAME_LENGTH + 1];
52
+};
53
+
54
+void ble_init(void);
29
 void ble_scan(enum ble_scan_mode mode);
55
 void ble_scan(enum ble_scan_mode mode);
56
+int ble_get_scan_results(struct ble_scan_result *buf, uint len);
30
 
57
 
31
 #endif // __BLE_H__
58
 #endif // __BLE_H__

+ 1
- 1
include/util.h View File

29
 void reset_to_bootloader(void);
29
 void reset_to_bootloader(void);
30
 void reset_to_main(void);
30
 void reset_to_main(void);
31
 
31
 
32
-void hexdump(uint8_t *buff, size_t len);
32
+void hexdump(const uint8_t *buff, size_t len);
33
 
33
 
34
 float map(float value, float leftMin, float leftMax, float rightMin, float rightMax);
34
 float map(float value, float leftMin, float leftMax, float rightMin, float rightMax);
35
 
35
 

+ 274
- 9
src/ble.c View File

2
  * ble.c
2
  * ble.c
3
  *
3
  *
4
  * https://github.com/raspberrypi/pico-examples/blob/master/pico_w/bt/standalone/client.c
4
  * https://github.com/raspberrypi/pico-examples/blob/master/pico_w/bt/standalone/client.c
5
+ * https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html
6
+ * https://github.com/bluekitchen/btstack/blob/master/example/gap_inquiry.c
5
  *
7
  *
6
  * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
8
  * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
7
  *
9
  *
18
  * See <http://www.gnu.org/licenses/>.
20
  * See <http://www.gnu.org/licenses/>.
19
  */
21
  */
20
 
22
 
21
-#include "btstack.h"
22
 #include "pico/cyw43_arch.h"
23
 #include "pico/cyw43_arch.h"
23
 
24
 
24
 #include "config.h"
25
 #include "config.h"
25
 #include "log.h"
26
 #include "log.h"
27
+#include "util.h"
26
 #include "ble.h"
28
 #include "ble.h"
27
 
29
 
30
+#define GAP_INQUIRY_INTERVAL 5 // *1.28s
31
+
28
 enum ble_state {
32
 enum ble_state {
29
     TC_OFF = 0,
33
     TC_OFF = 0,
30
     TC_IDLE,
34
     TC_IDLE,
38
 
42
 
39
 static btstack_packet_callback_registration_t hci_event_callback_registration;
43
 static btstack_packet_callback_registration_t hci_event_callback_registration;
40
 static enum ble_state state = TC_OFF;
44
 static enum ble_state state = TC_OFF;
45
+static struct ble_scan_result scans[BLE_MAX_SCAN_RESULTS] = {0};
46
+
47
+// TODO scan result entries are not aging out
41
 
48
 
42
-static bd_addr_t server_addr;
43
-static bd_addr_type_t server_addr_type;
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) {
52
+    int unused = -1;
53
+
54
+    for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
55
+        if (!scans[i].set) {
56
+            if (unused < 0) {
57
+                unused = i;
58
+            }
59
+            continue;
60
+        }
61
+
62
+        if (memcmp(addr, scans[i].addr, sizeof(bd_addr_t)) == 0) {
63
+            // already in list, just update changed values
64
+            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
+            return;
81
+        }
82
+    }
83
+
84
+    if (unused < 0) {
85
+        debug("no space in scan results for %s", bd_addr_to_str(addr));
86
+        return;
87
+    }
88
+
89
+    debug("new device with addr %s", bd_addr_to_str(addr));
90
+    scans[unused].set = true;
91
+    scans[unused].time = to_ms_since_boot(get_absolute_time());
92
+    scans[unused].state = BLE_NAME_REQUEST;
93
+    memcpy(scans[unused].addr, addr, sizeof(bd_addr_t));
94
+    scans[unused].type = type;
95
+    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
+    scans[unused].name[0] = '\0';
100
+}
101
+
102
+static void hci_scan_result_add_name(bd_addr_t addr, const uint8_t *data, uint8_t data_size) {
103
+    for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
104
+        if (!scans[i].set) {
105
+            continue;
106
+        }
107
+        if (memcmp(addr, scans[i].addr, sizeof(bd_addr_t)) != 0) {
108
+            continue;
109
+        }
110
+
111
+        uint8_t len = data_size;
112
+        if (len > BLE_MAX_NAME_LENGTH) {
113
+            len = BLE_MAX_NAME_LENGTH;
114
+        }
115
+        memcpy(scans[i].name, data, len);
116
+        scans[i].name[len] = '\0';
117
+        scans[i].time = to_ms_since_boot(get_absolute_time());
118
+        return;
119
+    }
120
+
121
+    debug("no matching entry for %s to add name '%.*s' to", bd_addr_to_str(addr), data_size, data);
122
+}
123
+
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
+}
44
 
144
 
45
 static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
145
 static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
46
     UNUSED(size);
146
     UNUSED(size);
64
             }
164
             }
65
         break;
165
         break;
66
 
166
 
167
+    case HCI_EVENT_INQUIRY_COMPLETE:
168
+    case HCI_EVENT_COMMAND_STATUS:
169
+    case HCI_EVENT_REMOTE_HOST_SUPPORTED_FEATURES:
170
+    case BTSTACK_EVENT_SCAN_MODE_CHANGED:
67
     case HCI_EVENT_COMMAND_COMPLETE:
171
     case HCI_EVENT_COMMAND_COMPLETE:
68
     case HCI_EVENT_TRANSPORT_PACKET_SENT:
172
     case HCI_EVENT_TRANSPORT_PACKET_SENT:
69
         break;
173
         break;
70
 
174
 
71
-    case GAP_EVENT_ADVERTISING_REPORT:
175
+    case GAP_EVENT_ADVERTISING_REPORT: {
72
         if (state != TC_W4_SCAN_RESULT) {
176
         if (state != TC_W4_SCAN_RESULT) {
73
             debug("scan result in invalid state %d", state);
177
             debug("scan result in invalid state %d", state);
74
             return;
178
             return;
75
         }
179
         }
76
 
180
 
77
-        gap_event_advertising_report_get_address(packet, server_addr);
78
-        server_addr_type = gap_event_advertising_report_get_address_type(packet);
79
-        debug("Found device with addr %s", bd_addr_to_str(server_addr));
181
+        bd_addr_t addr;
182
+        gap_event_advertising_report_get_address(packet, addr);
183
+
184
+        bd_addr_type_t type;
185
+        type = gap_event_advertising_report_get_address_type(packet);
186
+
187
+        int8_t rssi;
188
+        rssi = (int8_t)gap_event_advertising_report_get_rssi(packet);
189
+
190
+        // add data received so far
191
+        hci_add_scan_result(addr, type, rssi, 0, 0, 0);
192
+
193
+        // get advertisement from report event
194
+        const uint8_t *adv_data = gap_event_advertising_report_get_data(packet);
195
+        uint8_t adv_len = gap_event_advertising_report_get_data_length(packet);
196
+
197
+        // iterate over advertisement data
198
+        ad_context_t context;
199
+        for (ad_iterator_init(&context, adv_len, adv_data);
200
+             ad_iterator_has_more(&context);
201
+             ad_iterator_next(&context)) {
202
+            uint8_t data_type = ad_iterator_get_data_type(&context);
203
+            uint8_t data_size = ad_iterator_get_data_len(&context);
204
+            const uint8_t *data = ad_iterator_get_data(&context);
205
+            switch (data_type) {
206
+            case BLUETOOTH_DATA_TYPE_SHORTENED_LOCAL_NAME:
207
+            case BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME:
208
+                // unfortunately not the name we're interested in for our targets...
209
+                hci_scan_result_add_name(addr, data, data_size);
210
+                break;
211
+
212
+            case BLUETOOTH_DATA_TYPE_FLAGS:
213
+            case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS:
214
+            case BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID:
215
+            case BLUETOOTH_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
216
+            case BLUETOOTH_DATA_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE:
217
+                break;
218
+
219
+            default:
220
+                debug("Unexpected advertisement type 0x%02X from %s", data_type, bd_addr_to_str(addr));
221
+                hexdump(data, data_size);
222
+                break;
223
+            }
224
+        }
225
+        break;
226
+    }
227
+
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();
80
         break;
301
         break;
302
+    }
81
 
303
 
82
     case HCI_EVENT_LE_META:
304
     case HCI_EVENT_LE_META:
83
         switch (hci_event_le_meta_get_subevent_code(packet)) {
305
         switch (hci_event_le_meta_get_subevent_code(packet)) {
84
             case HCI_SUBEVENT_LE_ADVERTISING_REPORT:
306
             case HCI_SUBEVENT_LE_ADVERTISING_REPORT:
307
+                // handled internally by BTstack
85
                 break;
308
                 break;
86
 
309
 
87
             case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
310
             case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
101
 }
324
 }
102
 
325
 
103
 void ble_init(void) {
326
 void ble_init(void) {
327
+    for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
328
+        scans[i].set = false;
329
+    }
330
+
104
     l2cap_init();
331
     l2cap_init();
105
     sm_init();
332
     sm_init();
106
     sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
333
     sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
107
 
334
 
108
     gatt_client_init();
335
     gatt_client_init();
109
 
336
 
337
+    hci_set_inquiry_mode(INQUIRY_MODE_RSSI_AND_EIR);
338
+
110
     hci_event_callback_registration.callback = &hci_event_handler;
339
     hci_event_callback_registration.callback = &hci_event_handler;
111
     hci_add_event_handler(&hci_event_callback_registration);
340
     hci_add_event_handler(&hci_event_callback_registration);
112
 
341
 
114
 }
343
 }
115
 
344
 
116
 void ble_scan(enum ble_scan_mode mode) {
345
 void ble_scan(enum ble_scan_mode mode) {
346
+    cyw43_thread_enter();
347
+
117
     switch (mode) {
348
     switch (mode) {
118
     case BLE_SCAN_OFF:
349
     case BLE_SCAN_OFF:
119
         debug("stopping BLE scan");
350
         debug("stopping BLE scan");
120
         state = TC_IDLE;
351
         state = TC_IDLE;
121
         gap_stop_scan();
352
         gap_stop_scan();
353
+        gap_inquiry_stop();
122
         break;
354
         break;
123
 
355
 
124
     case BLE_SCAN_ON:
356
     case BLE_SCAN_ON:
125
         debug("starting BLE scan");
357
         debug("starting BLE scan");
126
         state = TC_W4_SCAN_RESULT;
358
         state = TC_W4_SCAN_RESULT;
359
+
127
         gap_set_scan_parameters(0,0x0030, 0x0030);
360
         gap_set_scan_parameters(0,0x0030, 0x0030);
128
         gap_start_scan();
361
         gap_start_scan();
362
+
363
+        // also start an inquiry scan
364
+        gap_inquiry_start(GAP_INQUIRY_INTERVAL);
129
         break;
365
         break;
130
 
366
 
131
     case BLE_SCAN_TOGGLE:
367
     case BLE_SCAN_TOGGLE:
132
         switch (state) {
368
         switch (state) {
133
         case TC_W4_SCAN_RESULT:
369
         case TC_W4_SCAN_RESULT:
370
+            cyw43_thread_exit();
134
             ble_scan(0);
371
             ble_scan(0);
135
-            break;
372
+            return;
136
 
373
 
137
         case TC_IDLE:
374
         case TC_IDLE:
375
+            cyw43_thread_exit();
138
             ble_scan(1);
376
             ble_scan(1);
139
-            break;
377
+            return;
140
 
378
 
141
         default:
379
         default:
142
             debug("invalid state %d", state);
380
             debug("invalid state %d", state);
148
         debug("invalid mode %d", mode);
386
         debug("invalid mode %d", mode);
149
         break;
387
         break;
150
     }
388
     }
389
+
390
+    cyw43_thread_exit();
391
+}
392
+
393
+int ble_get_scan_results(struct ble_scan_result *buf, uint len) {
394
+    if (!buf || (len <= 0)) {
395
+        return -1;
396
+    }
397
+
398
+    cyw43_thread_enter();
399
+
400
+    uint pos = 0;
401
+    for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
402
+        if (!scans[i].set) {
403
+            continue;
404
+        }
405
+
406
+        memcpy(buf + pos, scans + i, sizeof(struct ble_scan_result));
407
+        pos++;
408
+
409
+        if (pos >= len) {
410
+            break;
411
+        }
412
+    }
413
+
414
+    cyw43_thread_exit();
415
+    return pos;
151
 }
416
 }

+ 16
- 0
src/console.c View File

78
         println("  mount - make mass storage medium (un)available");
78
         println("  mount - make mass storage medium (un)available");
79
         println("  power - show Lipo battery status");
79
         println("  power - show Lipo battery status");
80
         println("   scan - start or stop BLE scan");
80
         println("   scan - start or stop BLE scan");
81
+        println("scanres - print list of found BLE devices");
81
         println("  clear - blank screen");
82
         println("  clear - blank screen");
82
         println(" splash - draw image on screen");
83
         println(" splash - draw image on screen");
83
         println("  fonts - show font list");
84
         println("  fonts - show font list");
101
                 lipo_charging() ? "charging" : "draining");
102
                 lipo_charging() ? "charging" : "draining");
102
     } else if (strcmp(line, "scan") == 0) {
103
     } else if (strcmp(line, "scan") == 0) {
103
         ble_scan(2);
104
         ble_scan(2);
105
+    } else if (strcmp(line, "scanres") == 0) {
106
+        struct ble_scan_result results[BLE_MAX_SCAN_RESULTS] = {0};
107
+        int n = ble_get_scan_results(results, BLE_MAX_SCAN_RESULTS);
108
+        if (n < 0) {
109
+            println("Error reading results (%d)", n);
110
+        } else {
111
+            println("%d results", n);
112
+            for (int i = 0; i < n; i++) {
113
+                uint32_t age = to_ms_since_boot(get_absolute_time()) - results[i].time;
114
+                println("addr=%s type=%d rssi=%d age=%.1fs name='%s'",
115
+                        bd_addr_to_str(results[i].addr),
116
+                        results[i].type, results[i].rssi,
117
+                        age / 1000.0, results[i].name);
118
+            }
119
+        }
104
     } else if (strcmp(line, "clear") == 0) {
120
     } else if (strcmp(line, "clear") == 0) {
105
         lcd_clear();
121
         lcd_clear();
106
     } else if (strcmp(line, "splash") == 0) {
122
     } else if (strcmp(line, "splash") == 0) {

+ 1
- 1
src/util.c View File

89
     }
89
     }
90
 }
90
 }
91
 
91
 
92
-void hexdump(uint8_t *buff, size_t len) {
92
+void hexdump(const uint8_t *buff, size_t len) {
93
     for (size_t i = 0; i < len; i += 16) {
93
     for (size_t i = 0; i < len; i += 16) {
94
         for (size_t j = 0; (j < 16) && ((i + j) < len); j++) {
94
         for (size_t j = 0; (j < 16) && ((i + j) < len); j++) {
95
             print("0x%02X", buff[i + j]);
95
             print("0x%02X", buff[i + j]);

Loading…
Cancel
Save