@@ -49,6 +49,8 @@ struct peripheral_slot {
49
49
50
50
static struct peripheral_slot peripherals [ZMK_BLE_SPLIT_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_BLE_SPLIT_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,56 @@ 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_scan ();
347
353
}
348
354
349
- static bool split_central_eir_found (struct bt_data * data , void * user_data ) {
355
+ static bool split_central_eir_found (const bt_addr_le_t * addr ) {
356
+ LOG_DBG ("Found the split service" );
357
+
358
+ int slot_idx = reserve_peripheral_slot (addr );
359
+ if (slot_idx < 0 ) {
360
+ LOG_ERR ("Failed to reserve peripheral slot (err %d)" , slot_idx );
361
+ return false;
362
+ }
363
+
364
+ // Stop scanning so we can connect to the peripheral device.
365
+ LOG_DBG ("Stopping peripheral scanning" );
366
+ is_scanning = false;
367
+ int err = bt_le_scan_stop ();
368
+ if (err ) {
369
+ LOG_ERR ("Stop LE scan failed (err %d)" , err );
370
+ return false;
371
+ }
372
+
373
+ struct peripheral_slot * slot = & peripherals [slot_idx ];
374
+
375
+ slot -> conn = bt_conn_lookup_addr_le (BT_ID_DEFAULT , addr );
376
+ if (slot -> conn ) {
377
+ LOG_DBG ("Found existing connection" );
378
+ split_central_process_connection (slot -> conn );
379
+ err = bt_conn_le_phy_update (slot -> conn , BT_CONN_LE_PHY_PARAM_2M );
380
+ if (err ) {
381
+ LOG_ERR ("Update phy conn failed (err %d)" , err );
382
+ }
383
+ } else {
384
+ struct bt_le_conn_param * param = BT_LE_CONN_PARAM (0x0006 , 0x0006 , 30 , 400 );
385
+
386
+ LOG_DBG ("Initiating new connnection" );
387
+
388
+ err = bt_conn_le_create (addr , BT_CONN_LE_CREATE_CONN , param , & slot -> conn );
389
+ if (err ) {
390
+ LOG_ERR ("Create conn failed (err %d) (create conn? 0x%04x)" , err ,
391
+ BT_HCI_OP_LE_CREATE_CONN );
392
+ start_scan ();
393
+ }
394
+ }
395
+
396
+ return false;
397
+ }
398
+
399
+ static bool split_central_eir_parse (struct bt_data * data , void * user_data ) {
350
400
bt_addr_le_t * addr = user_data ;
351
401
int i ;
352
402
@@ -361,9 +411,7 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data) {
361
411
}
362
412
363
413
for (i = 0 ; i < data -> data_len ; i += 16 ) {
364
- struct bt_le_conn_param * param ;
365
414
struct bt_uuid_128 uuid ;
366
- int err ;
367
415
368
416
if (!bt_uuid_create (& uuid .uuid , & data -> data [i ], 16 )) {
369
417
LOG_ERR ("Unable to load UUID" );
@@ -382,46 +430,7 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data) {
382
430
continue ;
383
431
}
384
432
385
- LOG_DBG ("Found the split service" );
386
-
387
- zmk_ble_set_peripheral_addr (addr );
388
-
389
- err = bt_le_scan_stop ();
390
- if (err ) {
391
- LOG_ERR ("Stop LE scan failed (err %d)" , err );
392
- continue ;
393
- }
394
-
395
- uint8_t slot_idx = reserve_peripheral_slot ();
396
- if (slot_idx < 0 ) {
397
- LOG_ERR ("Faild to reserve peripheral slot (err %d)" , slot_idx );
398
- continue ;
399
- }
400
-
401
- struct peripheral_slot * slot = & peripherals [slot_idx ];
402
-
403
- slot -> conn = bt_conn_lookup_addr_le (BT_ID_DEFAULT , addr );
404
- if (slot -> conn ) {
405
- LOG_DBG ("Found existing connection" );
406
- split_central_process_connection (slot -> conn );
407
- err = bt_conn_le_phy_update (slot -> conn , BT_CONN_LE_PHY_PARAM_2M );
408
- if (err ) {
409
- LOG_ERR ("Update phy conn failed (err %d)" , err );
410
- }
411
- } else {
412
- param = BT_LE_CONN_PARAM (0x0006 , 0x0006 , 30 , 400 );
413
-
414
- LOG_DBG ("Initiating new connnection" );
415
-
416
- err = bt_conn_le_create (addr , BT_CONN_LE_CREATE_CONN , param , & slot -> conn );
417
- if (err ) {
418
- LOG_ERR ("Create conn failed (err %d) (create conn? 0x%04x)" , err ,
419
- BT_HCI_OP_LE_CREATE_CONN );
420
- start_scan ();
421
- }
422
- }
423
-
424
- return false;
433
+ return split_central_eir_found (addr );
425
434
}
426
435
}
427
436
@@ -438,14 +447,33 @@ static void split_central_device_found(const bt_addr_le_t *addr, int8_t rssi, ui
438
447
439
448
/* We're only interested in connectable events */
440
449
if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND ) {
441
- bt_data_parse (ad , split_central_eir_found , (void * )addr );
450
+ bt_data_parse (ad , split_central_eir_parse , (void * )addr );
442
451
}
443
452
}
444
453
445
454
static int start_scan (void ) {
446
- int err ;
455
+ // No action is necessary if central is already scanning.
456
+ if (is_scanning ) {
457
+ LOG_DBG ("Scanning already running" );
458
+ return 0 ;
459
+ }
460
+
461
+ // If all the devices are connected, there is no need to scan.
462
+ bool has_unconnected = false;
463
+ for (int i = 0 ; i < CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS ; i ++ ) {
464
+ if (peripherals [i ].conn == NULL ) {
465
+ has_unconnected = true;
466
+ break ;
467
+ }
468
+ }
469
+ if (!has_unconnected ) {
470
+ LOG_DBG ("All devices are connected, scanning is unnecessary" );
471
+ return 0 ;
472
+ }
447
473
448
- err = bt_le_scan_start (BT_LE_SCAN_PASSIVE , split_central_device_found );
474
+ // Start scanning otherwise.
475
+ is_scanning = true;
476
+ int err = bt_le_scan_start (BT_LE_SCAN_PASSIVE , split_central_device_found );
449
477
if (err ) {
450
478
LOG_ERR ("Scanning failed to start (err %d)" , err );
451
479
return err ;
0 commit comments