@@ -26,7 +26,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
26
26
#include <zmk/event_manager.h>
27
27
#include <zmk/events/position_state_changed.h>
28
28
29
- static int start_scan (void );
29
+ static int start_scanning (void );
30
30
31
31
#define POSITION_STATE_DATA_LEN 16
32
32
@@ -49,6 +49,8 @@ struct peripheral_slot {
49
49
50
50
static struct peripheral_slot peripherals [ZMK_SPLIT_BLE_PERIPHERAL_COUNT ];
51
51
52
+ static bool is_scanning = false;
53
+
52
54
static const struct bt_uuid_128 split_service_uuid = BT_UUID_INIT_128 (ZMK_SPLIT_BT_SERVICE_UUID );
53
55
54
56
K_MSGQ_DEFINE (peripheral_event_msgq , sizeof (struct zmk_position_state_changed ),
@@ -130,8 +132,9 @@ int release_peripheral_slot(int index) {
130
132
return 0 ;
131
133
}
132
134
133
- int reserve_peripheral_slot () {
134
- for (int i = 0 ; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT ; i ++ ) {
135
+ int reserve_peripheral_slot (const bt_addr_le_t * addr ) {
136
+ int i = zmk_ble_put_peripheral_addr (addr );
137
+ if (i >= 0 ) {
135
138
if (peripherals [i ].state == PERIPHERAL_SLOT_STATE_OPEN ) {
136
139
// Be sure the slot is fully reinitialized.
137
140
release_peripheral_slot (i );
@@ -344,9 +347,54 @@ static void split_central_process_connection(struct bt_conn *conn) {
344
347
345
348
LOG_DBG ("New connection params: Interval: %d, Latency: %d, PHY: %d" , info .le .interval ,
346
349
info .le .latency , info .le .phy -> rx_phy );
350
+
351
+ // Restart scanning if necessary.
352
+ start_scanning ();
353
+ }
354
+
355
+ static int stop_scanning () {
356
+ LOG_DBG ("Stopping peripheral scanning" );
357
+ is_scanning = false;
358
+
359
+ int err = bt_le_scan_stop ();
360
+ if (err < 0 ) {
361
+ LOG_ERR ("Stop LE scan failed (err %d)" , err );
362
+ return err ;
363
+ }
364
+
365
+ return 0 ;
347
366
}
348
367
349
- static bool split_central_eir_found (struct bt_data * data , void * user_data ) {
368
+ static bool split_central_eir_found (const bt_addr_le_t * addr ) {
369
+ LOG_DBG ("Found the split service" );
370
+
371
+ // Stop scanning so we can connect to the peripheral device.
372
+ int err = stop_scanning ();
373
+ if (err < 0 ) {
374
+ return false;
375
+ }
376
+
377
+ int slot_idx = reserve_peripheral_slot (addr );
378
+ if (slot_idx < 0 ) {
379
+ LOG_ERR ("Failed to reserve peripheral slot (err %d)" , slot_idx );
380
+ return false;
381
+ }
382
+
383
+ struct peripheral_slot * slot = & peripherals [slot_idx ];
384
+
385
+ LOG_DBG ("Initiating new connnection" );
386
+ struct bt_le_conn_param * param = BT_LE_CONN_PARAM (0x0006 , 0x0006 , 30 , 400 );
387
+ err = bt_conn_le_create (addr , BT_CONN_LE_CREATE_CONN , param , & slot -> conn );
388
+ if (err < 0 ) {
389
+ LOG_ERR ("Create conn failed (err %d) (create conn? 0x%04x)" , err , BT_HCI_OP_LE_CREATE_CONN );
390
+ release_peripheral_slot (slot_idx );
391
+ start_scanning ();
392
+ }
393
+
394
+ return false;
395
+ }
396
+
397
+ static bool split_central_eir_parse (struct bt_data * data , void * user_data ) {
350
398
bt_addr_le_t * addr = user_data ;
351
399
int i ;
352
400
@@ -361,9 +409,7 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data) {
361
409
}
362
410
363
411
for (i = 0 ; i < data -> data_len ; i += 16 ) {
364
- struct bt_le_conn_param * param ;
365
412
struct bt_uuid_128 uuid ;
366
- int err ;
367
413
368
414
if (!bt_uuid_create (& uuid .uuid , & data -> data [i ], 16 )) {
369
415
LOG_ERR ("Unable to load UUID" );
@@ -381,46 +427,7 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data) {
381
427
continue ;
382
428
}
383
429
384
- LOG_DBG ("Found the split service" );
385
-
386
- zmk_ble_set_peripheral_addr (addr );
387
-
388
- err = bt_le_scan_stop ();
389
- if (err ) {
390
- LOG_ERR ("Stop LE scan failed (err %d)" , err );
391
- continue ;
392
- }
393
-
394
- uint8_t slot_idx = reserve_peripheral_slot ();
395
- if (slot_idx < 0 ) {
396
- LOG_ERR ("Faild to reserve peripheral slot (err %d)" , slot_idx );
397
- continue ;
398
- }
399
-
400
- struct peripheral_slot * slot = & peripherals [slot_idx ];
401
-
402
- slot -> conn = bt_conn_lookup_addr_le (BT_ID_DEFAULT , addr );
403
- if (slot -> conn ) {
404
- LOG_DBG ("Found existing connection" );
405
- split_central_process_connection (slot -> conn );
406
- err = bt_conn_le_phy_update (slot -> conn , BT_CONN_LE_PHY_PARAM_2M );
407
- if (err ) {
408
- LOG_ERR ("Update phy conn failed (err %d)" , err );
409
- }
410
- } else {
411
- param = BT_LE_CONN_PARAM (0x0006 , 0x0006 , 30 , 400 );
412
-
413
- LOG_DBG ("Initiating new connnection" );
414
-
415
- err = bt_conn_le_create (addr , BT_CONN_LE_CREATE_CONN , param , & slot -> conn );
416
- if (err ) {
417
- LOG_ERR ("Create conn failed (err %d) (create conn? 0x%04x)" , err ,
418
- BT_HCI_OP_LE_CREATE_CONN );
419
- start_scan ();
420
- }
421
- }
422
-
423
- return false;
430
+ return split_central_eir_found (addr );
424
431
}
425
432
}
426
433
@@ -436,15 +443,34 @@ static void split_central_device_found(const bt_addr_le_t *addr, int8_t rssi, ui
436
443
437
444
/* We're only interested in connectable events */
438
445
if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND ) {
439
- bt_data_parse (ad , split_central_eir_found , (void * )addr );
446
+ bt_data_parse (ad , split_central_eir_parse , (void * )addr );
440
447
}
441
448
}
442
449
443
- static int start_scan (void ) {
444
- int err ;
450
+ static int start_scanning (void ) {
451
+ // No action is necessary if central is already scanning.
452
+ if (is_scanning ) {
453
+ LOG_DBG ("Scanning already running" );
454
+ return 0 ;
455
+ }
445
456
446
- err = bt_le_scan_start (BT_LE_SCAN_PASSIVE , split_central_device_found );
447
- if (err ) {
457
+ // If all the devices are connected, there is no need to scan.
458
+ bool has_unconnected = false;
459
+ for (int i = 0 ; i < CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS ; i ++ ) {
460
+ if (peripherals [i ].conn == NULL ) {
461
+ has_unconnected = true;
462
+ break ;
463
+ }
464
+ }
465
+ if (!has_unconnected ) {
466
+ LOG_DBG ("All devices are connected, scanning is unnecessary" );
467
+ return 0 ;
468
+ }
469
+
470
+ // Start scanning otherwise.
471
+ is_scanning = true;
472
+ int err = bt_le_scan_start (BT_LE_SCAN_PASSIVE , split_central_device_found );
473
+ if (err < 0 ) {
448
474
LOG_ERR ("Scanning failed to start (err %d)" , err );
449
475
return err ;
450
476
}
@@ -471,7 +497,7 @@ static void split_central_connected(struct bt_conn *conn, uint8_t conn_err) {
471
497
472
498
release_peripheral_slot_for_conn (conn );
473
499
474
- start_scan ();
500
+ start_scanning ();
475
501
return ;
476
502
}
477
503
@@ -495,7 +521,7 @@ static void split_central_disconnected(struct bt_conn *conn, uint8_t reason) {
495
521
return ;
496
522
}
497
523
498
- start_scan ();
524
+ start_scanning ();
499
525
}
500
526
501
527
static struct bt_conn_cb conn_callbacks = {
@@ -527,6 +553,10 @@ void split_central_split_run_callback(struct k_work *work) {
527
553
LOG_ERR ("Source not connected" );
528
554
continue ;
529
555
}
556
+ if (!peripherals [payload_wrapper .source ].run_behavior_handle ) {
557
+ LOG_ERR ("Run behavior handle not found" );
558
+ continue ;
559
+ }
530
560
531
561
int err = bt_gatt_write_without_response (
532
562
peripherals [payload_wrapper .source ].conn ,
@@ -590,7 +620,7 @@ int zmk_split_bt_central_init(const struct device *_arg) {
590
620
CONFIG_ZMK_BLE_THREAD_PRIORITY , NULL );
591
621
bt_conn_cb_register (& conn_callbacks );
592
622
593
- return start_scan ();
623
+ return start_scanning ();
594
624
}
595
625
596
626
SYS_INIT (zmk_split_bt_central_init , APPLICATION , CONFIG_ZMK_BLE_INIT_PRIORITY );
0 commit comments