@@ -2365,6 +2365,10 @@ static uint8_t set_rpa_timeout(const void *cmd, uint16_t cmd_len, void *rsp, uin
2365
2365
}
2366
2366
#endif /* defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC) */
2367
2367
2368
+ #if defined(CONFIG_BT_ISO_SYNC_RECEIVER ) || defined(CONFIG_BT_ISO_BROADCASTER )
2369
+ static int bt_iso_chan_get_index (struct bt_iso_chan * chan );
2370
+ #endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(CONFIG_BT_ISO_BROADCASTER) */
2371
+
2368
2372
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER )
2369
2373
static struct bt_iso_big * iso_sync_receiver_big ;
2370
2374
@@ -2442,8 +2446,6 @@ BUILD_ASSERT(BIS_STREAM_DATA_LEN < BTP_DATA_MAX_SIZE, "BIS stream data length ex
2442
2446
2443
2447
static struct net_buf_simple * iso_sync_receiver_buf = NET_BUF_SIMPLE (BIS_STREAM_DATA_LEN );
2444
2448
2445
- static int bt_iso_chan_get_index (struct bt_iso_chan * chan );
2446
-
2447
2449
static void iso_sync_receiver_recv (struct bt_iso_chan * chan , const struct bt_iso_recv_info * info ,
2448
2450
struct net_buf * buf )
2449
2451
{
@@ -2525,7 +2527,57 @@ static struct bt_iso_chan_ops iso_sync_receiver_ops = {
2525
2527
.connected = iso_sync_receiver_connected ,
2526
2528
.disconnected = iso_sync_receiver_disconnected ,
2527
2529
};
2530
+ #endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */
2531
+
2532
+ #if defined(CONFIG_BT_ISO_BROADCASTER )
2533
+ static uint32_t bis_sn_last ;
2534
+ static int64_t bis_sn_last_updated_ticks ;
2535
+ static uint32_t bis_sdu_interval_us ;
2536
+
2537
+ static void iso_broadcaster_connected (struct bt_iso_chan * chan )
2538
+ {
2539
+ int err ;
2540
+ const struct bt_iso_chan_path hci_path = {
2541
+ .pid = BT_ISO_DATA_PATH_HCI ,
2542
+ .format = BT_HCI_CODING_FORMAT_TRANSPARENT ,
2543
+ };
2544
+ struct btp_gap_bis_data_path_setup_ev ev ;
2545
+ struct bt_le_ext_adv * ext_adv = tester_gap_ext_adv_get (0 );
2528
2546
2547
+ err = bt_iso_chan_get_index (chan );
2548
+ if (err < 0 ) {
2549
+ LOG_ERR ("Failed to get BIS channel index: %d" , err );
2550
+ return ;
2551
+ }
2552
+ ev .bis_id = (uint8_t )err ;
2553
+
2554
+ bis_sn_last = 0 ;
2555
+ bis_sn_last_updated_ticks = k_uptime_ticks ();
2556
+
2557
+ err = bt_iso_setup_data_path (chan , BT_HCI_DATAPATH_DIR_HOST_TO_CTLR , & hci_path );
2558
+ if (err != 0 ) {
2559
+ LOG_ERR ("Failed to setup ISO TX data path: %d" , err );
2560
+ return ;
2561
+ }
2562
+
2563
+ bt_addr_le_copy (& ev .address , & ext_adv -> random_addr );
2564
+
2565
+ tester_event (BTP_SERVICE_ID_GAP , BTP_GAP_EV_BIS_DATA_PATH_SETUP , & ev , sizeof (ev ));
2566
+ }
2567
+
2568
+ static void iso_broadcaster_disconnected (struct bt_iso_chan * chan , uint8_t reason )
2569
+ {
2570
+ ARG_UNUSED (chan );
2571
+ ARG_UNUSED (reason );
2572
+ }
2573
+
2574
+ static struct bt_iso_chan_ops iso_broadcaster_ops = {
2575
+ .connected = iso_broadcaster_connected ,
2576
+ .disconnected = iso_broadcaster_disconnected ,
2577
+ };
2578
+ #endif /* defined(CONFIG_BT_ISO_BROADCASTER) */
2579
+
2580
+ #if defined(CONFIG_BT_ISO_SYNC_RECEIVER ) || defined(CONFIG_BT_ISO_BROADCASTER )
2529
2581
static struct bt_iso_chan_qos bis_iso_qos ;
2530
2582
2531
2583
static struct bt_iso_chan bis_iso_chan = {
@@ -2534,8 +2586,6 @@ static struct bt_iso_chan bis_iso_chan = {
2534
2586
2535
2587
#define DEFAULT_IO_QOS {.sdu = 40u, .phy = BT_GAP_LE_PHY_2M, .rtn = 2u,}
2536
2588
2537
- static struct bt_iso_chan_io_qos iso_sync_receiver_qos = DEFAULT_IO_QOS ;
2538
-
2539
2589
#define BIS_ISO_CHAN_COUNT 1
2540
2590
2541
2591
static struct bt_iso_chan * bis_channels [BIS_ISO_CHAN_COUNT ] = { & bis_iso_chan };
@@ -2549,6 +2599,10 @@ static int bt_iso_chan_get_index(struct bt_iso_chan *chan)
2549
2599
}
2550
2600
return - EINVAL ;
2551
2601
}
2602
+ #endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(CONFIG_BT_ISO_BROADCASTER) */
2603
+
2604
+ #if defined(CONFIG_BT_ISO_SYNC_RECEIVER )
2605
+ static struct bt_iso_chan_io_qos iso_sync_receiver_qos = DEFAULT_IO_QOS ;
2552
2606
2553
2607
static uint8_t big_create_sync (const void * cmd , uint16_t cmd_len , void * rsp , uint16_t * rsp_len )
2554
2608
{
@@ -2606,6 +2660,137 @@ static uint8_t big_create_sync(const void *cmd, uint16_t cmd_len, void *rsp, uin
2606
2660
}
2607
2661
#endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */
2608
2662
2663
+ #if defined(CONFIG_BT_ISO_BROADCASTER )
2664
+ static struct bt_iso_chan_io_qos iso_broadcaster_qos = DEFAULT_IO_QOS ;
2665
+
2666
+ static struct bt_iso_big * iso_broadcaster_big ;
2667
+
2668
+ static uint8_t create_big (const void * cmd , uint16_t cmd_len , void * rsp , uint16_t * rsp_len )
2669
+ {
2670
+ int err ;
2671
+ const struct btp_gap_create_big_cmd * cp = cmd ;
2672
+ struct bt_iso_big_create_param param = {0 };
2673
+ struct bt_le_ext_adv * ext_adv = tester_gap_ext_adv_get (0 );
2674
+
2675
+ if ((cmd_len < sizeof (* cp )) ||
2676
+ (cmd_len != (sizeof (* cp ) + sizeof (param .bcode ) * cp -> encryption ))) {
2677
+ LOG_ERR ("Invalid cmd len" );
2678
+ return BTP_STATUS_FAILED ;
2679
+ }
2680
+
2681
+ if (!(cp -> encryption == BTP_GAP_CREATE_BIG_ENC_DISABLE ||
2682
+ cp -> encryption == BTP_GAP_CREATE_BIG_ENC_ENABLE )) {
2683
+ LOG_ERR ("Invalid encryption %u" , cp -> encryption );
2684
+ return BTP_STATUS_FAILED ;
2685
+ }
2686
+
2687
+ if ((ext_adv == NULL ) || (cp -> id != ext_adv -> id )) {
2688
+ LOG_ERR ("Invalid extended adv" );
2689
+ return BTP_STATUS_FAILED ;
2690
+ }
2691
+
2692
+ if (cp -> num_bis > ARRAY_SIZE (bis_channels )) {
2693
+ LOG_ERR ("BIS num exceeds %u > %u" , cp -> num_bis , ARRAY_SIZE (bis_channels ));
2694
+ return BTP_STATUS_FAILED ;
2695
+ }
2696
+
2697
+ bis_iso_qos .rx = NULL ;
2698
+ bis_iso_qos .tx = & iso_broadcaster_qos ;
2699
+ bis_iso_qos .tx -> phy = cp -> phy ;
2700
+ bis_iso_qos .tx -> rtn = cp -> rtn ;
2701
+ bis_iso_qos .tx -> sdu = CONFIG_BT_ISO_TX_MTU ;
2702
+
2703
+ bis_iso_chan .ops = & iso_broadcaster_ops ;
2704
+
2705
+ param .bis_channels = bis_channels ;
2706
+ param .num_bis = cp -> num_bis ;
2707
+ param .interval = sys_le32_to_cpu (cp -> interval );
2708
+ param .packing = cp -> packing ;
2709
+ param .framing = cp -> framing ;
2710
+ param .latency = sys_le16_to_cpu (cp -> latency );
2711
+
2712
+ param .encryption = cp -> encryption == BTP_GAP_CREATE_BIG_ENC_ENABLE ;
2713
+ if (param .encryption ) {
2714
+ memcpy (param .bcode , cp -> broadcast_code , sizeof (param .bcode ));
2715
+ }
2716
+
2717
+ bis_sdu_interval_us = param .interval ;
2718
+
2719
+ err = bt_iso_big_create (ext_adv , & param , & iso_broadcaster_big );
2720
+ if (err != 0 ) {
2721
+ LOG_ERR ("Unable to create BIG (err %d)" , err );
2722
+ return BTP_STATUS_FAILED ;
2723
+ }
2724
+
2725
+ LOG_DBG ("BIG created" );
2726
+
2727
+ return BTP_STATUS_SUCCESS ;
2728
+ }
2729
+
2730
+ NET_BUF_POOL_FIXED_DEFINE (bis_tx_pool , BIS_ISO_CHAN_COUNT ,
2731
+ BT_ISO_SDU_BUF_SIZE (CONFIG_BT_ISO_TX_MTU ),
2732
+ CONFIG_BT_CONN_TX_USER_DATA_SIZE , NULL );
2733
+
2734
+ static uint32_t get_next_sn (uint32_t last_sn , int64_t * last_ticks ,
2735
+ uint32_t interval_us )
2736
+ {
2737
+ int64_t uptime_ticks , delta_ticks ;
2738
+ uint64_t delta_us ;
2739
+ uint64_t sn_incr ;
2740
+ uint64_t next_sn ;
2741
+
2742
+ /* Note: This does not handle wrapping of ticks when they go above
2743
+ * 2^(62-1)
2744
+ */
2745
+ uptime_ticks = k_uptime_ticks ();
2746
+ delta_ticks = uptime_ticks - * last_ticks ;
2747
+ * last_ticks = uptime_ticks ;
2748
+
2749
+ delta_us = k_ticks_to_us_near64 ((uint64_t )delta_ticks );
2750
+ sn_incr = delta_us / interval_us ;
2751
+ next_sn = (sn_incr + last_sn );
2752
+
2753
+ return (uint32_t )next_sn ;
2754
+ }
2755
+
2756
+ static uint8_t bis_broadcast (const void * cmd , uint16_t cmd_len , void * rsp , uint16_t * rsp_len )
2757
+ {
2758
+ int err ;
2759
+ const struct btp_gap_bis_broadcast_cmd * cp = cmd ;
2760
+ struct net_buf * buf ;
2761
+
2762
+ buf = net_buf_alloc (& bis_tx_pool , K_NO_WAIT );
2763
+ if (buf == NULL ) {
2764
+ LOG_ERR ("Failed to allocate buffer" );
2765
+ return BTP_STATUS_FAILED ;
2766
+ }
2767
+
2768
+ net_buf_reserve (buf , BT_ISO_CHAN_SEND_RESERVE );
2769
+
2770
+ if (cp -> data_len > net_buf_tailroom (buf )) {
2771
+ net_buf_unref (buf );
2772
+ LOG_ERR ("Data length exceeds buffer tailroom" );
2773
+ return BTP_STATUS_FAILED ;
2774
+ }
2775
+
2776
+ bis_sn_last = get_next_sn (bis_sn_last , & bis_sn_last_updated_ticks ,
2777
+ bis_sdu_interval_us );
2778
+
2779
+ net_buf_add_mem (buf , cp -> data , cp -> data_len );
2780
+
2781
+ err = bt_iso_chan_send (& bis_iso_chan , buf , bis_sn_last );
2782
+ if (err < 0 ) {
2783
+ LOG_ERR ("Unable to broadcast: %d" , - err );
2784
+ net_buf_unref (buf );
2785
+ return BTP_STATUS_FAILED ;
2786
+ }
2787
+
2788
+ LOG_DBG ("ISO broadcasting..., sn %u len %u" , bis_sn_last , cp -> data_len );
2789
+
2790
+ return BTP_STATUS_SUCCESS ;
2791
+ }
2792
+ #endif /* defined(CONFIG_BT_ISO_BROADCASTER) */
2793
+
2609
2794
static const struct btp_handler handlers [] = {
2610
2795
{
2611
2796
.opcode = BTP_GAP_READ_SUPPORTED_COMMANDS ,
@@ -2808,6 +2993,18 @@ static const struct btp_handler handlers[] = {
2808
2993
.func = big_create_sync ,
2809
2994
},
2810
2995
#endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */
2996
+ #if defined(CONFIG_BT_ISO_BROADCASTER )
2997
+ {
2998
+ .opcode = BTP_GAP_CREATE_BIG ,
2999
+ .expect_len = BTP_HANDLER_LENGTH_VARIABLE ,
3000
+ .func = create_big ,
3001
+ },
3002
+ {
3003
+ .opcode = BTP_GAP_BIS_BROADCAST ,
3004
+ .expect_len = BTP_HANDLER_LENGTH_VARIABLE ,
3005
+ .func = bis_broadcast ,
3006
+ },
3007
+ #endif /* defined(CONFIG_BT_ISO_BROADCASTER) */
2811
3008
};
2812
3009
2813
3010
uint8_t tester_init_gap (void )
0 commit comments