Bluetooth: controller: Add support for Read/Write Conn. Accept Timeout

Implement HCI commands HCI_Read_Connection_Accept_Timeout and
HCI_Write_Connection_Accept_Timeout, and enable the feature in
supported commands.
Remove hardcoded use of default accept timeout in new LLCP code, and
use configurable value instead.

This makes EBQ test /HCI/CIN/BV-03-C pass.

Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
Morten Priess 2022-06-03 14:43:25 +02:00 committed by Carles Cufí
commit 3915754ac3
5 changed files with 99 additions and 2 deletions

View file

@ -647,6 +647,34 @@ static void configure_data_path(struct net_buf *buf,
}
#endif /* CONFIG_BT_CTLR_HCI_CODEC_AND_DELAY_INFO */
#if defined(CONFIG_BT_CTLR_CONN_ISO)
static void read_conn_accept_timeout(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_rp_read_conn_accept_timeout *rp;
uint16_t timeout;
ARG_UNUSED(buf);
rp = hci_cmd_complete(evt, sizeof(*rp));
rp->status = ll_conn_iso_accept_timeout_get(&timeout);
rp->conn_accept_timeout = sys_cpu_to_le16(timeout);
}
static void write_conn_accept_timeout(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_cp_write_conn_accept_timeout *cmd = (void *)buf->data;
struct bt_hci_rp_write_conn_accept_timeout *rp;
uint16_t timeout;
timeout = sys_le16_to_cpu(cmd->conn_accept_timeout);
rp = hci_cmd_complete(evt, sizeof(*rp));
rp->status = ll_conn_iso_accept_timeout_set(timeout);
}
#endif /* CONFIG_BT_CTLR_CONN_ISO */
#if defined(CONFIG_BT_CONN)
static void read_tx_power_level(struct net_buf *buf, struct net_buf **evt)
{
@ -685,6 +713,16 @@ static int ctrl_bb_cmd_handle(uint16_t ocf, struct net_buf *cmd,
set_event_mask_page_2(cmd, evt);
break;
#if defined(CONFIG_BT_CTLR_CONN_ISO)
case BT_OCF(BT_HCI_OP_READ_CONN_ACCEPT_TIMEOUT):
read_conn_accept_timeout(cmd, evt);
break;
case BT_OCF(BT_HCI_OP_WRITE_CONN_ACCEPT_TIMEOUT):
write_conn_accept_timeout(cmd, evt);
break;
#endif /* CONFIG_BT_CTLR_CONN_ISO */
#if defined(CONFIG_BT_CONN)
case BT_OCF(BT_HCI_OP_READ_TX_POWER_LEVEL):
read_tx_power_level(cmd, evt);
@ -757,6 +795,12 @@ static void read_supported_commands(struct net_buf *buf, struct net_buf **evt)
#endif
/* Set Event Mask, and Reset. */
rp->commands[5] |= BIT(6) | BIT(7);
#if defined(CONFIG_BT_CTLR_CONN_ISO)
/* Read/Write Connection Accept Timeout */
rp->commands[7] |= BIT(2) | BIT(3);
#endif /* CONFIG_BT_CTLR_CONN_ISO */
/* Read TX Power Level. */
rp->commands[10] |= BIT(2);

View file

@ -324,6 +324,9 @@ void ll_iso_tx_mem_release(void *tx);
int ll_iso_tx_mem_enqueue(uint16_t handle, void *tx, void *link);
void ll_iso_link_tx_release(void *link);
uint8_t ll_conn_iso_accept_timeout_get(uint16_t *timeout);
uint8_t ll_conn_iso_accept_timeout_set(uint16_t timeout);
/* External co-operation */
void ll_timeslice_ticker_id_get(uint8_t * const instance_index,
uint8_t * const ticker_id);

View file

@ -75,6 +75,12 @@ static void *cis_free;
static struct ll_conn_iso_group cig_pool[CONFIG_BT_CTLR_CONN_ISO_GROUPS];
static void *cig_free;
/* BT. 5.3 Spec - Vol 4, Part E, Sect 6.7 */
#define CONN_ACCEPT_TIMEOUT_DEFAULT 0x1F40
#define CONN_ACCEPT_TIMEOUT_MAX 0xB540
#define CONN_ACCEPT_TIMEOUT_MIN 0x0001
static uint16_t conn_accept_timeout;
struct ll_conn_iso_group *ll_conn_iso_group_acquire(void)
{
return mem_acquire(&cig_free);
@ -230,6 +236,25 @@ struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_group(struct ll_conn_iso_gr
return NULL;
}
uint8_t ll_conn_iso_accept_timeout_get(uint16_t *timeout)
{
*timeout = conn_accept_timeout;
return 0;
}
uint8_t ll_conn_iso_accept_timeout_set(uint16_t timeout)
{
if (!IN_RANGE(timeout, CONN_ACCEPT_TIMEOUT_MIN,
CONN_ACCEPT_TIMEOUT_MAX)) {
return BT_HCI_ERR_INVALID_LL_PARAM;
}
conn_accept_timeout = timeout;
return 0;
}
void ull_conn_iso_cis_established(struct ll_conn_iso_stream *cis)
{
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
@ -478,6 +503,8 @@ static int init_reset(void)
cis->group = NULL;
}
conn_accept_timeout = CONN_ACCEPT_TIMEOUT_DEFAULT;
/* Initialize LLL */
err = lll_conn_iso_init();
if (err) {

View file

@ -219,9 +219,17 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
ull_cp_prt_reload_set(conn, conn_interval_us);
#endif /* CONFIG_BT_LL_SW_LLCP_LEGACY */
#if (!defined(CONFIG_BT_LL_SW_LLCP_LEGACY))
#if !defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
#if defined(CONFIG_BT_CTLR_CONN_ISO)
uint16_t conn_accept_timeout;
(void)ll_conn_iso_accept_timeout_get(&conn_accept_timeout);
conn->connect_accept_to = conn_accept_timeout * 625U;
#else
conn->connect_accept_to = DEFAULT_CONNECTION_ACCEPT_TIMEOUT_US;
#endif /* !defined(CONFIG_BT_LL_SW_LLCP_LEGACY) */
#endif /* CONFIG_BT_CTLR_CONN_ISO */
#endif /* !CONFIG_BT_LL_SW_LLCP_LEGACY */
#if defined(CONFIG_BT_CTLR_LE_PING)
/* APTO in no. of connection events */
conn->apto_reload = RADIO_CONN_EVENTS((30 * 1000 * 1000),