瀏覽代碼

ble connect and disconnect

Thomas Buck 1 年之前
父節點
當前提交
c376ba1486
共有 3 個文件被更改,包括 107 次插入44 次删除
  1. 2
    0
      include/ble.h
  2. 83
    37
      src/ble.c
  3. 22
    7
      src/console.c

+ 2
- 0
include/ble.h 查看文件

44
 bool ble_is_ready(void);
44
 bool ble_is_ready(void);
45
 void ble_scan(enum ble_scan_mode mode);
45
 void ble_scan(enum ble_scan_mode mode);
46
 int ble_get_scan_results(struct ble_scan_result *buf, uint len);
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
 #endif // __BLE_H__
50
 #endif // __BLE_H__

+ 83
- 37
src/ble.c 查看文件

26
 #include "util.h"
26
 #include "util.h"
27
 #include "ble.h"
27
 #include "ble.h"
28
 
28
 
29
+#define BLE_MAX_SCAN_AGE_MS (10 * 1000)
30
+
29
 enum ble_state {
31
 enum ble_state {
30
     TC_OFF = 0,
32
     TC_OFF = 0,
31
     TC_IDLE,
33
     TC_IDLE,
32
-    TC_W4_SCAN_RESULT,
34
+    TC_W4_SCAN,
33
     TC_W4_CONNECT,
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
 static btstack_packet_callback_registration_t hci_event_callback_registration;
39
 static btstack_packet_callback_registration_t hci_event_callback_registration;
40
+static hci_con_handle_t connection_handle;
41
+
41
 static enum ble_state state = TC_OFF;
42
 static enum ble_state state = TC_OFF;
42
 static struct ble_scan_result scans[BLE_MAX_SCAN_RESULTS] = {0};
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
 static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type, int8_t rssi) {
45
 static void hci_add_scan_result(bd_addr_t addr, bd_addr_type_t type, int8_t rssi) {
47
     int unused = -1;
46
     int unused = -1;
48
 
47
 
55
         }
54
         }
56
 
55
 
57
         if (memcmp(addr, scans[i].addr, sizeof(bd_addr_t)) == 0) {
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
             scans[i].time = to_ms_since_boot(get_absolute_time());
58
             scans[i].time = to_ms_since_boot(get_absolute_time());
59
+            scans[i].rssi = rssi;
60
             return;
60
             return;
61
         }
61
         }
62
     }
62
     }
102
     UNUSED(channel);
102
     UNUSED(channel);
103
 
103
 
104
     if (packet_type != HCI_EVENT_PACKET) {
104
     if (packet_type != HCI_EVENT_PACKET) {
105
-        debug("unexpected packet 0x%02X", packet_type);
105
+        //debug("unexpected packet 0x%02X", packet_type);
106
         return;
106
         return;
107
     }
107
     }
108
 
108
 
119
             }
119
             }
120
         break;
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
     case GAP_EVENT_ADVERTISING_REPORT: {
122
     case GAP_EVENT_ADVERTISING_REPORT: {
131
-        if (state != TC_W4_SCAN_RESULT) {
123
+        if (state != TC_W4_SCAN) {
132
             debug("scan result in invalid state %d", state);
124
             debug("scan result in invalid state %d", state);
133
             return;
125
             return;
134
         }
126
         }
163
                 hci_scan_result_add_name(addr, data, data_size);
155
                 hci_scan_result_add_name(addr, data, data_size);
164
                 break;
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
             default:
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
                 break;
161
                 break;
178
             }
162
             }
179
         }
163
         }
182
 
166
 
183
     case HCI_EVENT_LE_META:
167
     case HCI_EVENT_LE_META:
184
         switch (hci_event_le_meta_get_subevent_code(packet)) {
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
             case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
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
                 break;
176
                 break;
192
 
177
 
193
             default:
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
                 break;
180
                 break;
196
         }
181
         }
197
         break;
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
     default:
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
         break;
192
         break;
202
     }
193
     }
203
 }
194
 }
236
 void ble_scan(enum ble_scan_mode mode) {
227
 void ble_scan(enum ble_scan_mode mode) {
237
     cyw43_thread_enter();
228
     cyw43_thread_enter();
238
 
229
 
230
+    if (state == TC_OFF) {
231
+        cyw43_thread_exit();
232
+        return;
233
+    }
234
+
239
     switch (mode) {
235
     switch (mode) {
240
     case BLE_SCAN_OFF:
236
     case BLE_SCAN_OFF:
241
         debug("stopping BLE scan");
237
         debug("stopping BLE scan");
245
 
241
 
246
     case BLE_SCAN_ON:
242
     case BLE_SCAN_ON:
247
         debug("starting BLE scan");
243
         debug("starting BLE scan");
248
-        state = TC_W4_SCAN_RESULT;
244
+        state = TC_W4_SCAN;
249
         gap_set_scan_parameters(1, 0x0030, 0x0030);
245
         gap_set_scan_parameters(1, 0x0030, 0x0030);
250
         gap_start_scan();
246
         gap_start_scan();
251
         break;
247
         break;
252
 
248
 
253
     case BLE_SCAN_TOGGLE:
249
     case BLE_SCAN_TOGGLE:
254
         switch (state) {
250
         switch (state) {
255
-        case TC_W4_SCAN_RESULT:
251
+        case TC_W4_SCAN:
256
             cyw43_thread_exit();
252
             cyw43_thread_exit();
257
             ble_scan(0);
253
             ble_scan(0);
258
             return;
254
             return;
283
 
279
 
284
     cyw43_thread_enter();
280
     cyw43_thread_enter();
285
 
281
 
282
+    if (state == TC_OFF) {
283
+        cyw43_thread_exit();
284
+        return -1;
285
+    }
286
+
286
     uint pos = 0;
287
     uint pos = 0;
287
     for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
288
     for (uint i = 0; i < BLE_MAX_SCAN_RESULTS; i++) {
288
         if (!scans[i].set) {
289
         if (!scans[i].set) {
289
             continue;
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
         memcpy(buf + pos, scans + i, sizeof(struct ble_scan_result));
299
         memcpy(buf + pos, scans + i, sizeof(struct ble_scan_result));
293
         pos++;
300
         pos++;
294
 
301
 
300
     cyw43_thread_exit();
307
     cyw43_thread_exit();
301
     return pos;
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 查看文件

20
 #include <string.h>
20
 #include <string.h>
21
 #include "pico/stdlib.h"
21
 #include "pico/stdlib.h"
22
 #include <unistd.h>
22
 #include <unistd.h>
23
+#include <stdio.h>
23
 
24
 
24
 #include "config.h"
25
 #include "config.h"
25
 #include "log.h"
26
 #include "log.h"
37
 #define CNSL_BUFF_SIZE 1024
38
 #define CNSL_BUFF_SIZE 1024
38
 #define CNSL_REPEAT_MS 500
39
 #define CNSL_REPEAT_MS 500
39
 
40
 
40
-//#define CNSL_REPEAT_PMW_STATUS_BY_DEFAULT
41
-
42
 static char cnsl_line_buff[CNSL_BUFF_SIZE + 1];
41
 static char cnsl_line_buff[CNSL_BUFF_SIZE + 1];
43
 static uint32_t cnsl_buff_pos = 0;
42
 static uint32_t cnsl_buff_pos = 0;
44
 
43
 
71
             || (strcmp(line, "h") == 0)
70
             || (strcmp(line, "h") == 0)
72
             || (strcmp(line, "?") == 0)) {
71
             || (strcmp(line, "?") == 0)) {
73
         println("VolcanoRC Firmware Usage:");
72
         println("VolcanoRC Firmware Usage:");
73
+        println("");
74
         println("  reset - reset back into this firmware");
74
         println("  reset - reset back into this firmware");
75
         println("   \\x18 - reset to bootloader");
75
         println("   \\x18 - reset to bootloader");
76
         println(" repeat - repeat last command every %d milliseconds", CNSL_REPEAT_MS);
76
         println(" repeat - repeat last command every %d milliseconds", CNSL_REPEAT_MS);
77
         println("   help - print this message");
77
         println("   help - print this message");
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("");
80
         println("   scan - start or stop BLE scan");
81
         println("   scan - start or stop BLE scan");
81
         println("scanres - print list of found BLE devices");
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
         println("  clear - blank screen");
86
         println("  clear - blank screen");
83
         println(" splash - draw image on screen");
87
         println(" splash - draw image on screen");
84
         println("  fonts - show font list");
88
         println("  fonts - show font list");
85
         println("   text - draw text on screen");
89
         println("   text - draw text on screen");
86
         println("    bat - draw battery indicator");
90
         println("    bat - draw battery indicator");
91
+        println("");
87
         println("Press Enter with no input to repeat last command.");
92
         println("Press Enter with no input to repeat last command.");
88
         println("Use repeat to continuously execute last command.");
93
         println("Use repeat to continuously execute last command.");
89
         println("Stop this by calling repeat again.");
94
         println("Stop this by calling repeat again.");
117
                         age / 1000.0, results[i].name);
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
     } else if (strcmp(line, "clear") == 0) {
140
     } else if (strcmp(line, "clear") == 0) {
121
         lcd_clear();
141
         lcd_clear();
122
     } else if (strcmp(line, "splash") == 0) {
142
     } else if (strcmp(line, "splash") == 0) {
186
         cnsl_last_command[i] = '\0';
206
         cnsl_last_command[i] = '\0';
187
         cnsl_repeated_command[i] = '\0';
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
 static int32_t cnsl_find_line_end(void) {
211
 static int32_t cnsl_find_line_end(void) {

Loading…
取消
儲存