Browse Source

ble connect and disconnect

Thomas Buck 7 months ago
parent
commit
c376ba1486
3 changed files with 107 additions and 44 deletions
  1. 2
    0
      include/ble.h
  2. 83
    37
      src/ble.c
  3. 22
    7
      src/console.c

+ 2
- 0
include/ble.h View File

@@ -44,5 +44,7 @@ void ble_init(void);
44 44
 bool ble_is_ready(void);
45 45
 void ble_scan(enum ble_scan_mode mode);
46 46
 int ble_get_scan_results(struct ble_scan_result *buf, uint len);
47
+void ble_connect(bd_addr_t addr, bd_addr_type_t type);
48
+void ble_disconnect(void);
47 49
 
48 50
 #endif // __BLE_H__

+ 83
- 37
src/ble.c View File

@@ -26,23 +26,22 @@
26 26
 #include "util.h"
27 27
 #include "ble.h"
28 28
 
29
+#define BLE_MAX_SCAN_AGE_MS (10 * 1000)
30
+
29 31
 enum ble_state {
30 32
     TC_OFF = 0,
31 33
     TC_IDLE,
32
-    TC_W4_SCAN_RESULT,
34
+    TC_W4_SCAN,
33 35
     TC_W4_CONNECT,
34
-    TC_W4_SERVICE_RESULT,
35
-    TC_W4_CHARACTERISTIC_RESULT,
36
-    TC_W4_ENABLE_NOTIFICATIONS_COMPLETE,
37
-    TC_W4_READY
36
+    TC_READY
38 37
 };
39 38
 
40 39
 static btstack_packet_callback_registration_t hci_event_callback_registration;
40
+static hci_con_handle_t connection_handle;
41
+
41 42
 static enum ble_state state = TC_OFF;
42 43
 static struct ble_scan_result scans[BLE_MAX_SCAN_RESULTS] = {0};
43 44
 
44
-// TODO scan result entries are not aging out
45
-
46 45
 static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type, int8_t rssi) {
47 46
     int unused = -1;
48 47
 
@@ -55,8 +54,9 @@ static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type, int8_t rssi
55 54
         }
56 55
 
57 56
         if (memcmp(addr, scans[i].addr, sizeof(bd_addr_t)) == 0) {
58
-            // already in list, just update time for aging
57
+            // already in list, just update changing values
59 58
             scans[i].time = to_ms_since_boot(get_absolute_time());
59
+            scans[i].rssi = rssi;
60 60
             return;
61 61
         }
62 62
     }
@@ -102,7 +102,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
102 102
     UNUSED(channel);
103 103
 
104 104
     if (packet_type != HCI_EVENT_PACKET) {
105
-        debug("unexpected packet 0x%02X", packet_type);
105
+        //debug("unexpected packet 0x%02X", packet_type);
106 106
         return;
107 107
     }
108 108
 
@@ -119,16 +119,8 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
119 119
             }
120 120
         break;
121 121
 
122
-    case HCI_EVENT_INQUIRY_COMPLETE:
123
-    case HCI_EVENT_COMMAND_STATUS:
124
-    case HCI_EVENT_REMOTE_HOST_SUPPORTED_FEATURES:
125
-    case BTSTACK_EVENT_SCAN_MODE_CHANGED:
126
-    case HCI_EVENT_COMMAND_COMPLETE:
127
-    case HCI_EVENT_TRANSPORT_PACKET_SENT:
128
-        break;
129
-
130 122
     case GAP_EVENT_ADVERTISING_REPORT: {
131
-        if (state != TC_W4_SCAN_RESULT) {
123
+        if (state != TC_W4_SCAN) {
132 124
             debug("scan result in invalid state %d", state);
133 125
             return;
134 126
         }
@@ -163,17 +155,9 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
163 155
                 hci_scan_result_add_name(addr, data, data_size);
164 156
                 break;
165 157
 
166
-            case BLUETOOTH_DATA_TYPE_FLAGS:
167
-            case BLUETOOTH_DATA_TYPE_TX_POWER_LEVEL:
168
-            case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS:
169
-            case BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID:
170
-            case BLUETOOTH_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
171
-            case BLUETOOTH_DATA_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE:
172
-                break;
173
-
174 158
             default:
175
-                debug("Unexpected advertisement type 0x%02X from %s", data_type, bd_addr_to_str(addr));
176
-                hexdump(data, data_size);
159
+                //debug("Unexpected advertisement type 0x%02X from %s", data_type, bd_addr_to_str(addr));
160
+                //hexdump(data, data_size);
177 161
                 break;
178 162
             }
179 163
         }
@@ -182,22 +166,29 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
182 166
 
183 167
     case HCI_EVENT_LE_META:
184 168
         switch (hci_event_le_meta_get_subevent_code(packet)) {
185
-            case HCI_SUBEVENT_LE_ADVERTISING_REPORT:
186
-                // handled internally by BTstack
187
-                break;
188
-
189 169
             case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
190
-                debug("connection complete?!");
170
+                if (state != TC_W4_CONNECT) {
171
+                    return;
172
+                }
173
+                debug("connection complete");
174
+                connection_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
175
+                state = TC_READY;
191 176
                 break;
192 177
 
193 178
             default:
194
-                debug("unexpected LE meta event 0x%02X", hci_event_le_meta_get_subevent_code(packet));
179
+                //debug("unexpected LE meta event 0x%02X", hci_event_le_meta_get_subevent_code(packet));
195 180
                 break;
196 181
         }
197 182
         break;
198 183
 
184
+    case HCI_EVENT_DISCONNECTION_COMPLETE:
185
+        debug("disconnected");
186
+        connection_handle = HCI_CON_HANDLE_INVALID;
187
+        state = TC_IDLE;
188
+        break;
189
+
199 190
     default:
200
-        debug("unexpected event 0x%02X", hci_event_packet_get_type(packet));
191
+        //debug("unexpected event 0x%02X", hci_event_packet_get_type(packet));
201 192
         break;
202 193
     }
203 194
 }
@@ -236,6 +227,11 @@ bool ble_is_ready(void) {
236 227
 void ble_scan(enum ble_scan_mode mode) {
237 228
     cyw43_thread_enter();
238 229
 
230
+    if (state == TC_OFF) {
231
+        cyw43_thread_exit();
232
+        return;
233
+    }
234
+
239 235
     switch (mode) {
240 236
     case BLE_SCAN_OFF:
241 237
         debug("stopping BLE scan");
@@ -245,14 +241,14 @@ void ble_scan(enum ble_scan_mode mode) {
245 241
 
246 242
     case BLE_SCAN_ON:
247 243
         debug("starting BLE scan");
248
-        state = TC_W4_SCAN_RESULT;
244
+        state = TC_W4_SCAN;
249 245
         gap_set_scan_parameters(1, 0x0030, 0x0030);
250 246
         gap_start_scan();
251 247
         break;
252 248
 
253 249
     case BLE_SCAN_TOGGLE:
254 250
         switch (state) {
255
-        case TC_W4_SCAN_RESULT:
251
+        case TC_W4_SCAN:
256 252
             cyw43_thread_exit();
257 253
             ble_scan(0);
258 254
             return;
@@ -283,12 +279,23 @@ int ble_get_scan_results(struct ble_scan_result *buf, uint len) {
283 279
 
284 280
     cyw43_thread_enter();
285 281
 
282
+    if (state == TC_OFF) {
283
+        cyw43_thread_exit();
284
+        return -1;
285
+    }
286
+
286 287
     uint pos = 0;
287 288
     for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
288 289
         if (!scans[i].set) {
289 290
             continue;
290 291
         }
291 292
 
293
+        uint32_t diff = to_ms_since_boot(get_absolute_time()) - scans[i].time;
294
+        if (diff >= BLE_MAX_SCAN_AGE_MS) {
295
+            //debug("removing %s due to age", bd_addr_to_str(scans[i].addr));
296
+            scans[i].set = false;
297
+        }
298
+
292 299
         memcpy(buf + pos, scans + i, sizeof(struct ble_scan_result));
293 300
         pos++;
294 301
 
@@ -300,3 +307,42 @@ int ble_get_scan_results(struct ble_scan_result *buf, uint len) {
300 307
     cyw43_thread_exit();
301 308
     return pos;
302 309
 }
310
+
311
+void ble_connect(bd_addr_t addr, bd_addr_type_t type) {
312
+    cyw43_thread_enter();
313
+
314
+    switch (state) {
315
+    case TC_OFF:
316
+        cyw43_thread_exit();
317
+        return;
318
+
319
+    case TC_W4_SCAN:
320
+        cyw43_thread_exit();
321
+        ble_scan(0);
322
+        cyw43_thread_enter();
323
+        break;
324
+
325
+    case TC_READY:
326
+        gap_disconnect(connection_handle);
327
+        break;
328
+
329
+    default:
330
+        break;
331
+    }
332
+
333
+    debug("connecting to %s", bd_addr_to_str(addr));
334
+    state = TC_W4_CONNECT;
335
+    gap_connect(addr, type);
336
+
337
+    cyw43_thread_exit();
338
+}
339
+
340
+void ble_disconnect(void) {
341
+    cyw43_thread_enter();
342
+
343
+    if (state == TC_READY) {
344
+        gap_disconnect(connection_handle);
345
+    }
346
+
347
+    cyw43_thread_exit();
348
+}

+ 22
- 7
src/console.c View File

@@ -20,6 +20,7 @@
20 20
 #include <string.h>
21 21
 #include "pico/stdlib.h"
22 22
 #include <unistd.h>
23
+#include <stdio.h>
23 24
 
24 25
 #include "config.h"
25 26
 #include "log.h"
@@ -37,8 +38,6 @@
37 38
 #define CNSL_BUFF_SIZE 1024
38 39
 #define CNSL_REPEAT_MS 500
39 40
 
40
-//#define CNSL_REPEAT_PMW_STATUS_BY_DEFAULT
41
-
42 41
 static char cnsl_line_buff[CNSL_BUFF_SIZE + 1];
43 42
 static uint32_t cnsl_buff_pos = 0;
44 43
 
@@ -71,19 +70,25 @@ static void cnsl_interpret(const char *line) {
71 70
             || (strcmp(line, "h") == 0)
72 71
             || (strcmp(line, "?") == 0)) {
73 72
         println("VolcanoRC Firmware Usage:");
73
+        println("");
74 74
         println("  reset - reset back into this firmware");
75 75
         println("   \\x18 - reset to bootloader");
76 76
         println(" repeat - repeat last command every %d milliseconds", CNSL_REPEAT_MS);
77 77
         println("   help - print this message");
78 78
         println("  mount - make mass storage medium (un)available");
79 79
         println("  power - show Lipo battery status");
80
+        println("");
80 81
         println("   scan - start or stop BLE scan");
81 82
         println("scanres - print list of found BLE devices");
83
+        println("con M T - connect to (M)AC and (T)ype");
84
+        println(" discon - disconnect from BLE device");
85
+        println("");
82 86
         println("  clear - blank screen");
83 87
         println(" splash - draw image on screen");
84 88
         println("  fonts - show font list");
85 89
         println("   text - draw text on screen");
86 90
         println("    bat - draw battery indicator");
91
+        println("");
87 92
         println("Press Enter with no input to repeat last command.");
88 93
         println("Use repeat to continuously execute last command.");
89 94
         println("Stop this by calling repeat again.");
@@ -117,6 +122,21 @@ static void cnsl_interpret(const char *line) {
117 122
                         age / 1000.0, results[i].name);
118 123
             }
119 124
         }
125
+    } else if (str_startswith(line, "con ")) {
126
+        bd_addr_t addr;
127
+        bd_addr_type_t type;
128
+        int r = sscanf(line, "con %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX %hhu",
129
+                       &addr[0], &addr[1], &addr[2], &addr[3],
130
+                       &addr[4], &addr[5], &type);
131
+
132
+        if (r == 7) {
133
+            debug("connecting");
134
+            ble_connect(addr, type);
135
+        } else {
136
+            debug("invalid input (%d)", r);
137
+        }
138
+    } else if (strcmp(line, "discon") == 0) {
139
+        ble_disconnect();
120 140
     } else if (strcmp(line, "clear") == 0) {
121 141
         lcd_clear();
122 142
     } else if (strcmp(line, "splash") == 0) {
@@ -186,11 +206,6 @@ void cnsl_init(void) {
186 206
         cnsl_last_command[i] = '\0';
187 207
         cnsl_repeated_command[i] = '\0';
188 208
     }
189
-
190
-#ifdef CNSL_REPEAT_PMW_STATUS_BY_DEFAULT
191
-    strcpy(cnsl_repeated_command, "pmws");
192
-    repeat_command = true;
193
-#endif // CNSL_REPEAT_PMW_STATUS_BY_DEFAULT
194 209
 }
195 210
 
196 211
 static int32_t cnsl_find_line_end(void) {

Loading…
Cancel
Save