5
5
6
6
/*
7
7
* Copyright (c) 2020 Intel Corporation
8
- * Copyright (c) 2022-2023 Nordic Semiconductor ASA
8
+ * Copyright (c) 2022-2025 Nordic Semiconductor ASA
9
9
*
10
10
* SPDX-License-Identifier: Apache-2.0
11
11
*/
@@ -390,7 +390,6 @@ static bool encode_frame(struct shell_stream *sh_stream, uint8_t index, size_t f
390
390
false;
391
391
}
392
392
393
- /* TODO: Move the following to a function in bap_usb.c*/
394
393
bap_usb_get_frame (sh_stream , chan_alloc , lc3_tx_buf );
395
394
} else {
396
395
/* Generate sine wave */
@@ -817,6 +816,20 @@ static int set_metadata(struct bt_audio_codec_cfg *codec_cfg, const char *meta_s
817
816
}
818
817
819
818
#if defined(CONFIG_BT_BAP_UNICAST_CLIENT )
819
+ static void disconnected_cb (struct bt_conn * conn , uint8_t reason )
820
+ {
821
+ #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
822
+ (void )memset (snks [bt_conn_index (conn )], 0 , sizeof (snks [0 ]));
823
+ #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
824
+ #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
825
+ (void )memset (srcs [bt_conn_index (conn )], 0 , sizeof (srcs [0 ]));
826
+ #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
827
+ }
828
+
829
+ BT_CONN_CB_DEFINE (conn_callbacks ) = {
830
+ .disconnected = disconnected_cb ,
831
+ };
832
+
820
833
static uint8_t stream_dir (const struct bt_bap_stream * stream )
821
834
{
822
835
if (stream -> conn ) {
@@ -2299,7 +2312,6 @@ struct bt_broadcast_info {
2299
2312
static struct broadcast_sink_auto_scan {
2300
2313
struct broadcast_sink * broadcast_sink ;
2301
2314
struct bt_broadcast_info broadcast_info ;
2302
- struct bt_le_per_adv_sync * * out_sync ;
2303
2315
} auto_scan = {
2304
2316
.broadcast_info = {
2305
2317
.broadcast_id = BT_BAP_INVALID_BROADCAST_ID ,
@@ -2363,6 +2375,49 @@ static bool scan_check_and_get_broadcast_values(struct bt_data *data, void *user
2363
2375
}
2364
2376
}
2365
2377
2378
+ static void pa_sync_broadcast_sink (const struct bt_le_scan_recv_info * info )
2379
+ {
2380
+ struct bt_le_per_adv_sync_param create_params = {0 };
2381
+ int err ;
2382
+
2383
+ err = bt_le_scan_stop ();
2384
+ if (err != 0 ) {
2385
+ bt_shell_error ("Could not stop scan: %d" , err );
2386
+ }
2387
+
2388
+ bt_addr_le_copy (& create_params .addr , info -> addr );
2389
+ create_params .options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE ;
2390
+ create_params .sid = info -> sid ;
2391
+ create_params .skip = PA_SYNC_SKIP ;
2392
+ create_params .timeout = interval_to_sync_timeout (info -> interval );
2393
+
2394
+ bt_shell_print ("Attempting to PA sync to the broadcaster" );
2395
+ err = bt_le_per_adv_sync_create (& create_params , & per_adv_syncs [selected_per_adv_sync ]);
2396
+ if (err != 0 ) {
2397
+ bt_shell_error ("Could not create Broadcast PA sync: %d" , err );
2398
+ } else {
2399
+ struct bt_le_per_adv_sync * pa_sync = per_adv_syncs [selected_per_adv_sync ];
2400
+ struct scan_delegator_sync_state * sync_state = NULL ;
2401
+
2402
+ default_broadcast_sink .pa_sync = pa_sync ;
2403
+
2404
+ sync_state = scan_delegator_sync_state_get_by_values (
2405
+ auto_scan .broadcast_info .broadcast_id , info -> addr -> type , info -> sid );
2406
+ if (sync_state == NULL ) {
2407
+ sync_state = scan_delegator_sync_state_new ();
2408
+
2409
+ if (sync_state == NULL ) {
2410
+ bt_shell_error ("Could not get new sync state" );
2411
+
2412
+ return ;
2413
+ }
2414
+ }
2415
+
2416
+ sync_state -> pa_sync = pa_sync ;
2417
+ sync_state -> broadcast_id = auto_scan .broadcast_info .broadcast_id ;
2418
+ }
2419
+ }
2420
+
2366
2421
static void broadcast_scan_recv (const struct bt_le_scan_recv_info * info , struct net_buf_simple * ad )
2367
2422
{
2368
2423
struct bt_broadcast_info sr_info = {0 };
@@ -2407,31 +2462,11 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct
2407
2462
return ;
2408
2463
}
2409
2464
2410
- bt_shell_print ("Found matched broadcast with address %s" , addr_str );
2411
-
2412
- if (identified_broadcast && (auto_scan .broadcast_sink != NULL ) &&
2413
- (auto_scan .broadcast_sink -> pa_sync == NULL )) {
2414
- struct bt_le_per_adv_sync_param create_params = {0 };
2415
- int err ;
2465
+ bt_shell_print ("Found matched broadcast with address %s%s" , addr_str ,
2466
+ info -> interval > 0U ? "" : " but is not syncable" );
2416
2467
2417
- err = bt_le_scan_stop ();
2418
- if (err != 0 ) {
2419
- bt_shell_error ("Could not stop scan: %d" , err );
2420
- }
2421
-
2422
- bt_addr_le_copy (& create_params .addr , info -> addr );
2423
- create_params .options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE ;
2424
- create_params .sid = info -> sid ;
2425
- create_params .skip = PA_SYNC_SKIP ;
2426
- create_params .timeout = interval_to_sync_timeout (info -> interval );
2427
-
2428
- bt_shell_print ("Attempting to PA sync to the broadcaster" );
2429
- err = bt_le_per_adv_sync_create (& create_params , auto_scan .out_sync );
2430
- if (err != 0 ) {
2431
- bt_shell_error ("Could not create Broadcast PA sync: %d" , err );
2432
- } else {
2433
- auto_scan .broadcast_sink -> pa_sync = * auto_scan .out_sync ;
2434
- }
2468
+ if (info -> interval > 0U && identified_broadcast && auto_scan .broadcast_sink != NULL ) {
2469
+ pa_sync_broadcast_sink (info );
2435
2470
}
2436
2471
}
2437
2472
@@ -2465,8 +2500,7 @@ static void syncable(struct bt_bap_broadcast_sink *sink, const struct bt_iso_big
2465
2500
static void bap_pa_sync_synced_cb (struct bt_le_per_adv_sync * sync ,
2466
2501
struct bt_le_per_adv_sync_synced_info * info )
2467
2502
{
2468
- if (auto_scan .broadcast_sink != NULL && auto_scan .out_sync != NULL &&
2469
- sync == * auto_scan .out_sync ) {
2503
+ if (auto_scan .broadcast_sink != NULL && auto_scan .broadcast_sink -> pa_sync == sync ) {
2470
2504
bt_shell_print ("PA synced to broadcast with broadcast ID 0x%06x" ,
2471
2505
auto_scan .broadcast_info .broadcast_id );
2472
2506
@@ -3075,7 +3109,6 @@ static void clear_stream_data(struct shell_stream *sh_stream)
3075
3109
/* All streams in the broadcast sink has been terminated */
3076
3110
memset (& default_broadcast_sink .received_base , 0 ,
3077
3111
sizeof (default_broadcast_sink .received_base ));
3078
- default_broadcast_sink .broadcast_id = 0 ;
3079
3112
default_broadcast_sink .syncable = false;
3080
3113
}
3081
3114
}
@@ -3326,13 +3359,20 @@ static int cmd_start_broadcast(const struct shell *sh, size_t argc,
3326
3359
char * argv [])
3327
3360
{
3328
3361
struct bt_le_ext_adv * adv = adv_sets [selected_adv ];
3362
+ struct bt_le_ext_adv_info adv_info ;
3329
3363
int err ;
3330
3364
3331
3365
if (adv == NULL ) {
3332
3366
shell_info (sh , "Extended advertising set is NULL" );
3333
3367
return - ENOEXEC ;
3334
3368
}
3335
3369
3370
+ err = bt_le_ext_adv_get_info (adv , & adv_info );
3371
+ if (err != 0 ) {
3372
+ shell_error (sh , "Failed to get adv info: %d\n" , err );
3373
+ return - ENOEXEC ;
3374
+ }
3375
+
3336
3376
if (default_source .bap_source == NULL || default_source .is_cap ) {
3337
3377
shell_info (sh , "Broadcast source not created" );
3338
3378
return - ENOEXEC ;
@@ -3344,6 +3384,9 @@ static int cmd_start_broadcast(const struct shell *sh, size_t argc,
3344
3384
return err ;
3345
3385
}
3346
3386
3387
+ default_source .addr_type = adv_info .addr -> type ;
3388
+ default_source .adv_sid = adv_info .sid ;
3389
+
3347
3390
return 0 ;
3348
3391
}
3349
3392
@@ -3362,6 +3405,8 @@ static int cmd_stop_broadcast(const struct shell *sh, size_t argc, char *argv[])
3362
3405
return err ;
3363
3406
}
3364
3407
3408
+ default_source .adv_sid = BT_GAP_SID_INVALID ;
3409
+
3365
3410
return 0 ;
3366
3411
}
3367
3412
@@ -3426,7 +3471,6 @@ static int cmd_create_broadcast_sink(const struct shell *sh, size_t argc, char *
3426
3471
3427
3472
auto_scan .broadcast_sink = & default_broadcast_sink ;
3428
3473
auto_scan .broadcast_info .broadcast_id = broadcast_id ;
3429
- auto_scan .out_sync = & per_adv_syncs [selected_per_adv_sync ];
3430
3474
} else {
3431
3475
shell_print (sh , "Creating broadcast sink with broadcast ID 0x%06X" ,
3432
3476
(uint32_t )broadcast_id );
@@ -3438,6 +3482,52 @@ static int cmd_create_broadcast_sink(const struct shell *sh, size_t argc, char *
3438
3482
shell_error (sh , "Failed to create broadcast sink: %d" , err );
3439
3483
3440
3484
return - ENOEXEC ;
3485
+ } else {
3486
+ struct scan_delegator_sync_state * sync_state = NULL ;
3487
+
3488
+ default_broadcast_sink .pa_sync = per_adv_sync ;
3489
+
3490
+ /* Lookup sync_state by PA sync or by values */
3491
+ sync_state = scan_delegator_sync_state_get_by_pa (per_adv_sync );
3492
+ if (sync_state == NULL ) {
3493
+ struct bt_le_per_adv_sync_info sync_info ;
3494
+
3495
+ err = bt_le_per_adv_sync_get_info (per_adv_sync , & sync_info );
3496
+ if (err != 0 ) {
3497
+ bt_shell_error ("Failed to get sync info: %d" , err );
3498
+ err = bt_bap_broadcast_sink_delete (
3499
+ default_broadcast_sink .bap_sink );
3500
+ if (err != 0 ) {
3501
+ bt_shell_error (
3502
+ "Failed to delete broadcast sink: %d" , err );
3503
+ }
3504
+
3505
+ return - ENOEXEC ;
3506
+ }
3507
+
3508
+ sync_state = scan_delegator_sync_state_get_by_values (
3509
+ auto_scan .broadcast_info .broadcast_id , sync_info .addr .type ,
3510
+ sync_info .sid );
3511
+ }
3512
+
3513
+ if (sync_state == NULL ) {
3514
+ sync_state = scan_delegator_sync_state_new ();
3515
+
3516
+ if (sync_state == NULL ) {
3517
+ bt_shell_error ("Could not get new sync state" );
3518
+ err = bt_bap_broadcast_sink_delete (
3519
+ default_broadcast_sink .bap_sink );
3520
+ if (err != 0 ) {
3521
+ bt_shell_error (
3522
+ "Failed to delete broadcast sink: %d" , err );
3523
+ }
3524
+
3525
+ return - ENOEXEC ;
3526
+ }
3527
+ }
3528
+
3529
+ sync_state -> pa_sync = per_adv_sync ;
3530
+ sync_state -> broadcast_id = (uint32_t )broadcast_id ;
3441
3531
}
3442
3532
}
3443
3533
@@ -3479,7 +3569,6 @@ static int cmd_create_sink_by_name(const struct shell *sh, size_t argc, char *ar
3479
3569
3480
3570
auto_scan .broadcast_info .broadcast_id = BT_BAP_INVALID_BROADCAST_ID ;
3481
3571
auto_scan .broadcast_sink = & default_broadcast_sink ;
3482
- auto_scan .out_sync = & per_adv_syncs [selected_per_adv_sync ];
3483
3572
3484
3573
return 0 ;
3485
3574
}
@@ -3860,6 +3949,7 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
3860
3949
}
3861
3950
3862
3951
default_source .broadcast_id = BT_BAP_INVALID_BROADCAST_ID ;
3952
+ default_source .adv_sid = BT_GAP_SID_INVALID ;
3863
3953
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
3864
3954
3865
3955
#if defined(CONFIG_LIBLC3 )
0 commit comments