1 /** @file
2  *  @brief Internal APIs for Bluetooth ISO handling.
3  */
4 
5 /*
6  * Copyright (c) 2020 Intel Corporation
7  * Copyright (c) 2021-2024 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include <stdint.h>
13 
14 #include <zephyr/bluetooth/conn.h>
15 #include <zephyr/bluetooth/buf.h>
16 #include <zephyr/bluetooth/iso.h>
17 #include <zephyr/kernel.h>
18 #include <zephyr/net_buf.h>
19 #include <zephyr/sys/atomic.h>
20 #include <zephyr/sys/slist.h>
21 #include <zephyr/sys_clock.h>
22 
23 struct iso_data {
24 	/* Extend the bt_buf user data */
25 	struct bt_buf_data buf_data;
26 
27 	/* Index into the bt_conn storage array */
28 	uint8_t  index;
29 
30 	/** ISO connection handle */
31 	uint16_t handle;
32 };
33 
34 enum bt_iso_cig_state {
35 	BT_ISO_CIG_STATE_IDLE,
36 	BT_ISO_CIG_STATE_CONFIGURED,
37 	BT_ISO_CIG_STATE_ACTIVE,
38 	BT_ISO_CIG_STATE_INACTIVE
39 };
40 
41 struct bt_iso_cig {
42 	/** List of ISO channels to setup as CIS (the CIG). */
43 	sys_slist_t cis_channels;
44 
45 	/** Total number of CISes in the CIG. */
46 	uint8_t  num_cis;
47 
48 	/** The CIG ID */
49 	uint8_t id;
50 
51 	/** The CIG state
52 	 *
53 	 * Refer to BT Core Spec 5.3, Vol 6, Part 6, Figure 4.63
54 	 */
55 	enum bt_iso_cig_state state;
56 };
57 
58 enum {
59 	BT_BIG_INITIALIZED,
60 
61 	/* Creating a BIG as a broadcaster */
62 	BT_BIG_PENDING,
63 	/* Creating a BIG as a receiver */
64 	BT_BIG_SYNCING,
65 
66 	BT_BIG_NUM_FLAGS,
67 };
68 
69 struct bt_iso_big {
70 	/** List of ISO channels to setup as BIS (the BIG). */
71 	sys_slist_t bis_channels;
72 
73 	/** Total number of BISes in the BIG. */
74 	uint8_t  num_bis;
75 
76 	/** The BIG handle */
77 	uint8_t handle;
78 
79 	ATOMIC_DEFINE(flags, BT_BIG_NUM_FLAGS);
80 };
81 
82 #define iso(buf) ((struct iso_data *)net_buf_user_data(buf))
83 
84 /* Process ISO buffer */
85 void hci_iso(struct net_buf *buf);
86 
87 /* Allocates RX buffer */
88 struct net_buf *bt_iso_get_rx(k_timeout_t timeout);
89 
90 /** A callback used to notify about freed buffer in the iso rx pool. */
91 typedef void (*bt_iso_buf_rx_freed_cb_t)(void);
92 
93 /** Set a callback to notify about freed buffer in the iso rx pool.
94  *
95  * @param cb Callback to notify about freed buffer in the iso rx pool. If NULL, the callback is
96  *           disabled.
97  */
98 void bt_iso_buf_rx_freed_cb_set(bt_iso_buf_rx_freed_cb_t cb);
99 
100 /* Process CIS Established event */
101 void hci_le_cis_established(struct net_buf *buf);
102 void hci_le_cis_established_v2(struct net_buf *buf);
103 
104 /* Process CIS Request event */
105 void hci_le_cis_req(struct net_buf *buf);
106 
107 /** Process BIG complete event */
108 void hci_le_big_complete(struct net_buf *buf);
109 
110 /** Process BIG terminate event */
111 void hci_le_big_terminate(struct net_buf *buf);
112 
113 /** Process BIG sync established event */
114 void hci_le_big_sync_established(struct net_buf *buf);
115 
116 /** Process BIG sync lost event */
117 void hci_le_big_sync_lost(struct net_buf *buf);
118 
119 /* Notify ISO channels of a new connection */
120 void bt_iso_connected(struct bt_conn *iso);
121 
122 /* Notify ISO channels of a disconnect event */
123 void bt_iso_disconnected(struct bt_conn *iso);
124 
125 /* Notify ISO connected channels of security changed */
126 void bt_iso_security_changed(struct bt_conn *acl, uint8_t hci_status);
127 
128 #if defined(CONFIG_BT_ISO_LOG_LEVEL_DBG)
129 void bt_iso_chan_set_state_debug(struct bt_iso_chan *chan,
130 				 enum bt_iso_state state,
131 				 const char *func, int line);
132 #define bt_iso_chan_set_state(_chan, _state) \
133 	bt_iso_chan_set_state_debug(_chan, _state, __func__, __LINE__)
134 #else
135 void bt_iso_chan_set_state(struct bt_iso_chan *chan, enum bt_iso_state state);
136 #endif /* CONFIG_BT_ISO_LOG_LEVEL_DBG */
137 
138 /* Process incoming data for a connection */
139 void bt_iso_recv(struct bt_conn *iso, struct net_buf *buf, uint8_t flags);
140 
141 /* Whether the HCI ISO data packet contains a timestamp or not.
142  * Per spec, the TS flag can only be set for the first fragment.
143  */
144 enum bt_iso_timestamp {
145 	BT_ISO_TS_ABSENT = 0,
146 	BT_ISO_TS_PRESENT,
147 };
148