Bluetooth: Controller: Initial ISO Sync Receiver datapath integration

Initial attempt at integrating the ISOAL datapath with ISO
Synchronized Receiver implementation to generate HCI ISO
data packets.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2021-11-23 21:57:16 +05:30 committed by Anas Nashif
commit 2c65856ee8
5 changed files with 169 additions and 44 deletions

View file

@ -38,11 +38,11 @@
#include "ll_sw/lll_adv.h"
#include "lll/lll_adv_pdu.h"
#include "ll_sw/lll_scan.h"
#include "lll/lll_df_types.h"
#include "ll_sw/lll_sync.h"
#include "ll_sw/lll_sync_iso.h"
#include "ll_sw/lll_conn.h"
#include "ll_sw/lll_conn_iso.h"
#include "lll/lll_df_types.h"
#include "ll_sw/isoal.h"
@ -6448,7 +6448,16 @@ static void le_sync_iso_pdu(struct pdu_data *pdu,
struct node_rx_pdu *node_rx,
struct net_buf *buf)
{
/* FIXME: integrate with ISOAL interface */
/* If HCI datapath pass to ISO AL here */
const struct lll_sync_iso_stream *stream;
struct isoal_pdu_rx isoal_rx;
isoal_status_t err;
stream = ull_sync_iso_stream_get(node_rx->hdr.handle);
isoal_rx.meta = &node_rx->hdr.rx_iso_meta;
isoal_rx.pdu = (void *)node_rx->pdu;
err = isoal_rx_pdu_recombine(stream->dp->sink_hdl, &isoal_rx);
LL_ASSERT(err == ISOAL_STATUS_OK || err == ISOAL_STATUS_ERR_SDU_ALLOC);
}
static void le_big_sync_lost(struct pdu_data *pdu,

View file

@ -6,7 +6,7 @@
struct lll_sync_iso_stream {
uint8_t big_handle;
void *rfi;
struct ll_iso_datapath *dp;
};
struct lll_sync_iso {

View file

@ -10,6 +10,7 @@
#include "hal/cpu.h"
#include "hal/ccm.h"
#include "util/util.h"
#include "util/memq.h"
#include "util/mem.h"
#include "util/mfifo.h"
@ -17,28 +18,48 @@
#include "pdu.h"
#include "lll.h"
#include "lll_conn.h" /* for `struct lll_tx` */
#include "lll_sync.h"
#include "lll_sync_iso.h"
#include "lll_conn.h"
#include "lll_conn_iso.h"
#include "isoal.h"
#include "ull_sync_types.h"
#include "ull_iso_types.h"
#include "ull_conn_iso_types.h"
#include "ull_conn_internal.h"
#include "ull_sync_iso_internal.h"
#include "ull_conn_iso_internal.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_ull_iso
#include "common/log.h"
#include "hal/debug.h"
#include "lll_conn_iso.h"
#include "ull_conn_iso_types.h"
#include "isoal.h"
#include "ull_iso_types.h"
#include "ull_conn_internal.h"
#include "ull_conn_iso_internal.h"
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS)
/* Allocate data path pools for RX/TX directions for each stream */
static struct ll_iso_datapath datapath_pool[2*CONFIG_BT_CTLR_CONN_ISO_STREAMS];
static void *datapath_free;
#endif
#define BT_CTLR_CONN_ISO_STREAMS CONFIG_BT_CTLR_CONN_ISO_STREAMS
#else /* !CONFIG_BT_CTLR_CONN_ISO_STREAMS */
#define BT_CTLR_CONN_ISO_STREAMS 0
#endif /* !CONFIG_BT_CTLR_CONN_ISO_STREAMS */
#if defined(CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT)
#define BT_CTLR_SYNC_ISO_STREAMS (CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT)
#else /* !CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT */
#define BT_CTLR_SYNC_ISO_STREAMS 0
#endif /* CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT */
static int init_reset(void);
/* Allocate data path pools for RX/TX directions for each stream */
#define BT_CTLR_ISO_STREAMS ((2 * (BT_CTLR_CONN_ISO_STREAMS)) + \
BT_CTLR_SYNC_ISO_STREAMS)
#if BT_CTLR_ISO_STREAMS
static struct ll_iso_datapath datapath_pool[BT_CTLR_ISO_STREAMS];
#endif
static void *datapath_free;
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
static MFIFO_DEFINE(iso_tx, sizeof(struct lll_tx),
CONFIG_BT_CTLR_ISO_TX_BUFFERS);
@ -228,6 +249,71 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id,
}
#endif
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
struct lll_sync_iso_stream *stream;
struct ll_sync_iso_set *sync_iso;
isoal_sink_handle_t sink_handle;
struct lll_sync_iso *lll_iso;
struct ll_iso_datapath *dp;
uint16_t stream_handle;
uint32_t sdu_interval;
uint16_t iso_interval;
uint8_t burst_number;
int err;
if (path_dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
/* FIXME: workaround to succeed datapath setup for ISO
* broadcaster until Tx datapath is implemented, in the
* future.
*/
return BT_HCI_ERR_SUCCESS;
}
if (handle < BT_CTLR_SYNC_ISO_STREAM_HANDLE_BASE) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
stream_handle = handle - BT_CTLR_SYNC_ISO_STREAM_HANDLE_BASE;
stream = ull_sync_iso_stream_get(stream_handle);
if (stream->dp) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
/* Allocate and configure datapath */
dp = mem_acquire(&datapath_free);
if (!dp) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
dp->path_dir = path_dir;
dp->path_id = path_id;
dp->coding_format = coding_format;
dp->company_id = company_id;
/* TODO dp->sync_delay = controller_delay; ?*/
sync_iso = ull_sync_iso_by_stream_get(stream_handle);
lll_iso = &sync_iso->lll;
burst_number = lll_iso->bn;
sdu_interval = lll_iso->sdu_interval;
iso_interval = lll_iso->iso_interval;
err = isoal_sink_create(&sink_handle, handle, burst_number,
sdu_interval, iso_interval, sink_sdu_alloc_hci,
sink_sdu_emit_hci, sink_sdu_write_hci);
if (err) {
mem_release(dp, &datapath_free);
return BT_HCI_ERR_CMD_DISALLOWED;
}
dp->sink_hdl = sink_handle;
stream->dp = dp;
isoal_sink_enable(sink_handle);
#endif
return 0;
}
@ -260,6 +346,21 @@ uint8_t ll_remove_iso_path(uint16_t handle, uint8_t path_dir)
}
#endif /* CONFIG_BT_CTLR_CONN_ISO */
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
struct lll_sync_iso_stream *stream;
if (path_dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
stream = ull_sync_iso_stream_get(handle);
dp = stream->dp;
if (dp) {
stream->dp = NULL;
mem_release(dp, &datapath_free);
}
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
if (!dp) {
/* Datapath was not previously set up */
return BT_HCI_ERR_CMD_DISALLOWED;
@ -336,6 +437,36 @@ uint8_t ll_iso_test_end(uint16_t handle, uint32_t *received_cnt,
return BT_HCI_ERR_CMD_DISALLOWED;
}
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
void *ll_iso_tx_mem_acquire(void)
{
return mem_acquire(&mem_iso_tx.free);
}
void ll_iso_tx_mem_release(void *node_tx)
{
mem_release(node_tx, &mem_iso_tx.free);
}
int ll_iso_tx_mem_enqueue(uint16_t handle, void *node_tx)
{
struct lll_tx *tx;
uint8_t idx;
idx = MFIFO_ENQUEUE_GET(iso_tx, (void **) &tx);
if (!tx) {
return -ENOBUFS;
}
tx->handle = handle;
tx->node = node_tx;
MFIFO_ENQUEUE(iso_tx, idx);
return 0;
}
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
int ull_iso_init(void)
{
int err;
@ -365,36 +496,11 @@ int ull_iso_reset(void)
return 0;
}
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
void *ll_iso_tx_mem_acquire(void)
void ull_iso_datapath_release(struct ll_iso_datapath *dp)
{
return mem_acquire(&mem_iso_tx.free);
mem_release(dp, &datapath_free);
}
void ll_iso_tx_mem_release(void *tx)
{
mem_release(tx, &mem_iso_tx.free);
}
int ll_iso_tx_mem_enqueue(uint16_t handle, void *tx)
{
struct lll_tx *lll_tx;
uint8_t idx;
idx = MFIFO_ENQUEUE_GET(iso_tx, (void **) &lll_tx);
if (!lll_tx) {
return -ENOBUFS;
}
lll_tx->handle = handle;
lll_tx->node = tx;
MFIFO_ENQUEUE(iso_tx, idx);
return 0;
}
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
static int init_reset(void)
{
#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
@ -403,7 +509,7 @@ static int init_reset(void)
CONFIG_BT_CTLR_ISO_TX_BUFFERS, &mem_iso_tx.free);
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS)
#if BT_CTLR_ISO_STREAMS
/* Initialize ISO Datapath pool */
mem_init(datapath_pool, sizeof(struct ll_iso_datapath),
sizeof(datapath_pool) / sizeof(struct ll_iso_datapath), &datapath_free);

View file

@ -1,8 +1,9 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* Copyright (c) 2020-2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
int ull_iso_init(void);
int ull_iso_reset(void);
void ull_iso_datapath_release(struct ll_iso_datapath *dp);

View file

@ -34,6 +34,7 @@
#include "ull_internal.h"
#include "ull_scan_internal.h"
#include "ull_sync_internal.h"
#include "ull_iso_internal.h"
#include "ull_sync_iso_internal.h"
#include "ll.h"
@ -145,6 +146,7 @@ uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
stream = (void *)sync_iso_stream_acquire();
stream->big_handle = big_handle;
stream->dp = NULL;
lll->stream_handle[i] = sync_iso_stream_handle_get(stream);
}
@ -280,10 +282,17 @@ void ull_sync_iso_stream_release(struct ll_sync_iso_set *sync_iso)
lll = &sync_iso->lll;
while (lll->stream_count--) {
struct lll_sync_iso_stream *stream;
struct ll_iso_datapath *dp;
uint16_t handle;
handle = lll->stream_handle[lll->stream_count];
stream = ull_sync_iso_stream_get(handle);
dp = stream->dp;
if (dp) {
ull_iso_datapath_release(dp);
}
mem_release(stream, &stream_free);
}