Skip to content

Commit b9b1c7e

Browse files
asmk-otcarlescufi
authored andcommitted
Bluetooth: controller: ISO adaptation layer, Rx unframed
First design towards ISO adaptation layer, this PR introduces data-structures and framework for Rx unframed PDUs (BT RX ingress). Two callbacks are defined for the SDU production (BT RX egress), one for SDU allocation as well as a callback for emitting a reassembled SDU. Signed-off-by: Asger Munk Nielsen <[email protected]>
1 parent 958e826 commit b9b1c7e

File tree

13 files changed

+1016
-19
lines changed

13 files changed

+1016
-19
lines changed

include/bluetooth/hci.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,12 @@ struct bt_hci_rp_read_bd_addr {
667667
#define BT_HCI_DATAPATH_DIR_HOST_TO_CTLR 0x00
668668
#define BT_HCI_DATAPATH_DIR_CTLR_TO_HOST 0x01
669669

670+
/* audio datapath IDs */
671+
#define BT_HCI_DATAPATH_ID_HCI 0x00
672+
#define BT_HCI_DATAPATH_ID_VS 0x01
673+
#define BT_HCI_DATAPATH_ID_VS_END 0xfe
674+
#define BT_HCI_DATAPATH_ID_DISABLED 0xff
675+
670676
/* coding format assigned numbers, used for codec IDs */
671677
#define BT_HCI_CODING_FORMAT_ULAW_LOG 0x00
672678
#define BT_HCI_CODING_FORMAT_ALAW_LOG 0x01

subsys/bluetooth/controller/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ if(CONFIG_BT_LL_SW_SPLIT)
103103
CONFIG_BT_CTLR_CENTRAL_ISO)
104104
zephyr_library_sources(
105105
ll_sw/ull_iso.c
106+
ll_sw/isoal.c
106107
)
107108
endif()
108109
if(CONFIG_BT_CONN OR

subsys/bluetooth/controller/hci/hci.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,7 @@ static void le_setup_iso_path(struct net_buf *buf, struct net_buf **evt)
19261926

19271927
rp = hci_cmd_complete(evt, sizeof(*rp));
19281928
rp->status = status;
1929-
rp->handle = cmd->handle;
1929+
rp->handle = sys_cpu_to_le16(handle);
19301930
}
19311931

19321932
static void le_remove_iso_path(struct net_buf *buf, struct net_buf **evt)
@@ -1942,7 +1942,7 @@ static void le_remove_iso_path(struct net_buf *buf, struct net_buf **evt)
19421942

19431943
rp = hci_cmd_complete(evt, sizeof(*rp));
19441944
rp->status = status;
1945-
rp->handle = cmd->handle;
1945+
rp->handle = sys_cpu_to_le16(handle);
19461946
}
19471947

19481948
static void le_iso_receive_test(struct net_buf *buf, struct net_buf **evt)
@@ -6237,6 +6237,11 @@ uint8_t hci_get_class(struct node_rx_pdu *node_rx)
62376237
#endif /* CONFIG_BT_CTLR_PHY */
62386238
return HCI_CLASS_EVT_CONNECTION;
62396239
#endif /* CONFIG_BT_CONN */
6240+
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO) || \
6241+
defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
6242+
case NODE_RX_TYPE_ISO_PDU:
6243+
return HCI_CLASS_ISO_DATA;
6244+
#endif
62406245

62416246
#if CONFIG_BT_CTLR_USER_EVT_RANGE > 0
62426247
case NODE_RX_TYPE_USER_START ... NODE_RX_TYPE_USER_END - 1:

subsys/bluetooth/controller/hci/hci_driver.c

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
#include "ll_sw/lll.h"
4646
#include "ll.h"
4747

48+
#include "isoal.h"
49+
#include "lll_conn_iso.h"
50+
#include "ull_conn_iso_internal.h"
51+
#include "ull_conn_iso_types.h"
52+
#include "ull_iso_types.h"
53+
4854
#include "hci_internal.h"
4955

5056
#include "hal/debug.h"
@@ -65,6 +71,93 @@ static sys_slist_t hbuf_pend;
6571
static int32_t hbuf_count;
6672
#endif
6773

74+
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO) || \
75+
defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
76+
77+
#define SDU_HCI_HDR_SIZE (BT_HCI_ISO_HDR_SIZE + BT_HCI_ISO_TS_DATA_HDR_SIZE)
78+
79+
isoal_status_t sink_sdu_alloc_hci(const struct isoal_sink *sink_ctx,
80+
const struct isoal_pdu_rx *valid_pdu,
81+
struct isoal_sdu_buffer *sdu_buffer)
82+
{
83+
ARG_UNUSED(sink_ctx);
84+
ARG_UNUSED(valid_pdu); /* TODO copy valid pdu into netbuf ? */
85+
86+
struct net_buf *buf = bt_buf_get_rx(BT_BUF_ISO_IN, K_NO_WAIT);
87+
88+
if (buf) {
89+
/* Reserve space for headers */
90+
net_buf_reserve(buf, SDU_HCI_HDR_SIZE);
91+
92+
sdu_buffer->dbuf = buf;
93+
sdu_buffer->size = net_buf_tailroom(buf);
94+
} else {
95+
LL_ASSERT(0);
96+
}
97+
98+
return ISOAL_STATUS_OK;
99+
}
100+
101+
102+
isoal_status_t sink_sdu_emit_hci(const struct isoal_sink *sink_ctx,
103+
const struct isoal_sdu_produced *valid_sdu)
104+
{
105+
struct ll_conn_iso_stream *cis;
106+
uint16_t handle;
107+
uint16_t handle_packed;
108+
uint8_t ts, pb;
109+
uint16_t len;
110+
uint16_t packet_status_flag;
111+
uint16_t slen, slen_packed;
112+
struct bt_hci_iso_hdr *hdr;
113+
struct bt_hci_iso_ts_data_hdr *data_hdr;
114+
115+
struct net_buf *buf = (struct net_buf *) valid_sdu->contents.dbuf;
116+
117+
if (buf) {
118+
data_hdr = net_buf_push(buf, BT_HCI_ISO_TS_DATA_HDR_SIZE);
119+
hdr = net_buf_push(buf, BT_HCI_ISO_HDR_SIZE);
120+
121+
cis = sink_ctx->session.cis;
122+
handle = ll_conn_iso_stream_handle_get(cis);
123+
124+
pb = sink_ctx->sdu_production.sdu_state;
125+
126+
ts = 1; /*TODO: Always assume timestamp? */
127+
handle_packed = bt_iso_handle_pack(handle, pb, ts);
128+
len = sink_ctx->sdu_production.sdu_written + BT_HCI_ISO_TS_DATA_HDR_SIZE;
129+
130+
hdr->handle = sys_cpu_to_le16(handle_packed);
131+
hdr->len = sys_cpu_to_le16(len);
132+
133+
packet_status_flag = 0x0000; /* TODO: For now always assume "valid data" */
134+
slen = sink_ctx->sdu_production.sdu_written;
135+
slen_packed = bt_iso_pkt_len_pack(slen, packet_status_flag);
136+
137+
data_hdr->ts = sys_cpu_to_le32((uint32_t) valid_sdu->timestamp);
138+
data_hdr->data.sn = sys_cpu_to_le16((uint16_t) valid_sdu->seqn);
139+
data_hdr->data.slen = sys_cpu_to_le16(slen_packed);
140+
141+
/* send fragment up the chain */
142+
bt_recv(buf);
143+
}
144+
145+
return ISOAL_STATUS_OK;
146+
}
147+
148+
isoal_status_t sink_sdu_write_hci(void *dbuf,
149+
const uint8_t *pdu_payload,
150+
const size_t consume_len)
151+
{
152+
struct net_buf *buf = (struct net_buf *) dbuf;
153+
154+
LL_ASSERT(buf);
155+
net_buf_add_mem(buf, pdu_payload, consume_len);
156+
157+
return ISOAL_STATUS_OK;
158+
}
159+
#endif
160+
68161
static struct net_buf *process_prio_evt(struct node_rx_pdu *node_rx,
69162
uint8_t *evt_flags)
70163
{
@@ -203,6 +296,33 @@ static inline struct net_buf *encode_node(struct node_rx_pdu *node_rx,
203296
hci_acl_encode(node_rx, buf);
204297
break;
205298
#endif
299+
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO) || \
300+
defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
301+
case HCI_CLASS_ISO_DATA: {
302+
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
303+
struct ll_conn_iso_stream *cis =
304+
ll_conn_iso_stream_get(node_rx->hdr.handle);
305+
struct ll_iso_datapath *dp = cis->datapath_out;
306+
isoal_sink_handle_t sink = dp->sink_hdl;
307+
308+
if (dp->path_id == BT_HCI_DATAPATH_ID_HCI) {
309+
/* If HCI datapath pass to ISO AL here */
310+
struct isoal_pdu_rx pckt_meta = {
311+
.meta = &node_rx->hdr.rx_iso_meta,
312+
.pdu = (union isoal_pdu *) &node_rx->pdu[0]
313+
};
314+
315+
/* Pass the ISO PDU through ISO-AL */
316+
isoal_status_t err =
317+
isoal_rx_pdu_recombine(sink, &pckt_meta);
318+
319+
LL_ASSERT(err == ISOAL_STATUS_OK); /* TODO handle err */
320+
}
321+
#endif
322+
break;
323+
}
324+
#endif
325+
206326
default:
207327
LL_ASSERT(0);
208328
break;
@@ -225,6 +345,7 @@ static inline struct net_buf *process_node(struct node_rx_pdu *node_rx)
225345

226346
/* controller to host flow control enabled */
227347
switch (class) {
348+
case HCI_CLASS_ISO_DATA:
228349
case HCI_CLASS_EVT_DISCARDABLE:
229350
case HCI_CLASS_EVT_REQUIRED:
230351
break;
@@ -403,7 +524,6 @@ static void recv_thread(void *p1, void *p2, void *p3)
403524
net_buf_unref(buf);
404525
}
405526
}
406-
407527
k_yield();
408528
}
409529
}

subsys/bluetooth/controller/hci/hci_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ extern atomic_t hci_state_mask;
2828
#define HCI_CLASS_ACL_DATA 5 /* Asynchronous Connection Less (general
2929
* data)
3030
*/
31+
#define HCI_CLASS_ISO_DATA 6 /* Isochronous data */
32+
3133

3234
void hci_init(struct k_poll_signal *signal_host_buf);
3335
struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx);
@@ -41,6 +43,10 @@ int hci_acl_handle(struct net_buf *acl, struct net_buf **evt);
4143
void hci_acl_encode(struct node_rx_pdu *node_rx, struct net_buf *buf);
4244
void hci_num_cmplt_encode(struct net_buf *buf, uint16_t handle, uint8_t num);
4345
#endif
46+
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO) || \
47+
defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) || defined(CONFIG_BT_CTLR_CENTRAL_ISO)
48+
void hci_iso_encode(struct net_buf *buf, uint16_t handle, uint8_t flags);
49+
#endif
4450
int hci_vendor_cmd_handle(uint16_t ocf, struct net_buf *cmd,
4551
struct net_buf **evt);
4652
uint8_t hci_vendor_read_static_addr(struct bt_hci_vs_static_addr addrs[],

0 commit comments

Comments
 (0)