Bluetooth: controller: HCI fixes for ISO central role CIG/CIS creation

Fix issues with referencing invalid netbuf data and add missing
parameter. Removed returning of handle in setup functions, as handles
are  not available until commit.

Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
Morten Priess 2022-11-10 08:43:46 +01:00 committed by Carles Cufí
commit 07acdc9650
3 changed files with 81 additions and 46 deletions

View file

@ -1981,6 +1981,8 @@ static void le_set_cig_parameters(struct net_buf *buf, struct net_buf **evt)
uint32_t p_interval; uint32_t p_interval;
uint16_t c_latency; uint16_t c_latency;
uint16_t p_latency; uint16_t p_latency;
uint8_t cis_count;
uint8_t cig_id;
uint8_t status; uint8_t status;
uint8_t i; uint8_t i;
@ -1989,20 +1991,17 @@ static void le_set_cig_parameters(struct net_buf *buf, struct net_buf **evt)
c_latency = sys_le16_to_cpu(cmd->c_latency); c_latency = sys_le16_to_cpu(cmd->c_latency);
p_latency = sys_le16_to_cpu(cmd->p_latency); p_latency = sys_le16_to_cpu(cmd->p_latency);
/* Create CIG or start modifying existing CIG */ cig_id = cmd->cig_id;
status = ll_cig_parameters_open(cmd->cig_id, c_interval, p_interval, cis_count = cmd->num_cis;
cmd->sca, cmd->packing, cmd->framing,
c_latency, p_latency, cmd->num_cis);
rp = hci_cmd_complete(evt, sizeof(*rp) + /* Create CIG or start modifying existing CIG */
cmd->num_cis * sizeof(uint16_t)); status = ll_cig_parameters_open(cig_id, c_interval, p_interval,
rp->cig_id = cmd->cig_id; cmd->sca, cmd->packing, cmd->framing,
rp->num_handles = cmd->num_cis; c_latency, p_latency, cis_count);
/* Configure individual CISes */ /* Configure individual CISes */
for (i = 0; !status && i < cmd->num_cis; i++) { for (i = 0; !status && i < cis_count; i++) {
struct bt_hci_cis_params *params = cmd->cis; struct bt_hci_cis_params *params = &cmd->cis[i];
uint16_t handle;
uint16_t c_sdu; uint16_t c_sdu;
uint16_t p_sdu; uint16_t p_sdu;
@ -2011,14 +2010,29 @@ static void le_set_cig_parameters(struct net_buf *buf, struct net_buf **evt)
status = ll_cis_parameters_set(params->cis_id, c_sdu, p_sdu, status = ll_cis_parameters_set(params->cis_id, c_sdu, p_sdu,
params->c_phy, params->p_phy, params->c_phy, params->p_phy,
params->c_rtn, params->p_rtn, params->c_rtn, params->p_rtn);
&handle);
rp->handle[i] = sys_cpu_to_le16(handle);
} }
rp = hci_cmd_complete(evt, sizeof(*rp) + cis_count * sizeof(uint16_t));
rp->cig_id = cig_id;
rp->num_handles = cis_count;
/* Only apply parameters if all went well */ /* Only apply parameters if all went well */
if (!status) { if (!status) {
status = ll_cig_parameters_commit(cmd->cig_id); status = ll_cig_parameters_commit(cig_id);
if (status == BT_HCI_ERR_SUCCESS) {
struct ll_conn_iso_group *cig;
uint16_t handle;
cig = ll_conn_iso_group_get_by_id(cig_id);
handle = UINT16_MAX;
for (uint8_t i = 0; i < cis_count; i++) {
(void)ll_conn_iso_stream_get_by_group(cig, &handle);
rp->handle[i] = sys_cpu_to_le16(handle);
}
}
} }
rp->status = status; rp->status = status;
@ -2032,6 +2046,8 @@ static void le_set_cig_params_test(struct net_buf *buf, struct net_buf **evt)
uint32_t c_interval; uint32_t c_interval;
uint32_t p_interval; uint32_t p_interval;
uint16_t iso_interval; uint16_t iso_interval;
uint8_t cis_count;
uint8_t cig_id;
uint8_t status; uint8_t status;
uint8_t i; uint8_t i;
@ -2039,47 +2055,61 @@ static void le_set_cig_params_test(struct net_buf *buf, struct net_buf **evt)
p_interval = sys_get_le24(cmd->p_interval); p_interval = sys_get_le24(cmd->p_interval);
iso_interval = sys_le16_to_cpu(cmd->iso_interval); iso_interval = sys_le16_to_cpu(cmd->iso_interval);
cig_id = cmd->cig_id;
cis_count = cmd->num_cis;
/* Create CIG or start modifying existing CIG */ /* Create CIG or start modifying existing CIG */
status = ll_cig_parameters_test_open(cmd->cig_id, c_interval, status = ll_cig_parameters_test_open(cig_id, c_interval,
p_interval, cmd->c_ft, p_interval, cmd->c_ft,
cmd->p_ft, iso_interval, cmd->p_ft, iso_interval,
cmd->sca, cmd->packing, cmd->sca, cmd->packing,
cmd->framing, cmd->framing,
cmd->num_cis); cis_count);
rp = hci_cmd_complete(evt, sizeof(*rp) +
cmd->num_cis * sizeof(uint16_t));
rp->cig_id = cmd->cig_id;
rp->num_handles = cmd->num_cis;
/* Configure individual CISes */ /* Configure individual CISes */
for (i = 0; !status && i < cmd->num_cis; i++) { for (i = 0; !status && i < cis_count; i++) {
struct bt_hci_cis_params_test *params = cmd->cis; struct bt_hci_cis_params_test *params = &cmd->cis[i];
uint16_t handle;
uint16_t c_sdu; uint16_t c_sdu;
uint16_t p_sdu; uint16_t p_sdu;
uint16_t c_pdu; uint16_t c_pdu;
uint16_t p_pdu; uint16_t p_pdu;
uint8_t nse;
nse = params->nse;
c_sdu = sys_le16_to_cpu(params->c_sdu); c_sdu = sys_le16_to_cpu(params->c_sdu);
p_sdu = sys_le16_to_cpu(params->p_sdu); p_sdu = sys_le16_to_cpu(params->p_sdu);
c_pdu = sys_le16_to_cpu(params->c_pdu); c_pdu = sys_le16_to_cpu(params->c_pdu);
p_pdu = sys_le16_to_cpu(params->p_pdu); p_pdu = sys_le16_to_cpu(params->p_pdu);
status = ll_cis_parameters_test_set(params->cis_id, status = ll_cis_parameters_test_set(params->cis_id, nse,
c_sdu, p_sdu, c_sdu, p_sdu,
c_pdu, p_pdu, c_pdu, p_pdu,
params->c_phy, params->c_phy,
params->p_phy, params->p_phy,
params->c_bn, params->c_bn,
params->p_bn, params->p_bn);
&handle);
rp->handle[i] = sys_cpu_to_le16(handle);
} }
rp = hci_cmd_complete(evt, sizeof(*rp) + cis_count * sizeof(uint16_t));
rp->cig_id = cig_id;
rp->num_handles = cis_count;
/* Only apply parameters if all went well */ /* Only apply parameters if all went well */
if (!status) { if (!status) {
status = ll_cig_parameters_commit(cmd->cig_id); status = ll_cig_parameters_commit(cig_id);
if (status == BT_HCI_ERR_SUCCESS) {
struct ll_conn_iso_group *cig;
uint16_t handle;
cig = ll_conn_iso_group_get_by_id(cig_id);
handle = UINT16_MAX;
for (uint8_t i = 0; i < cis_count; i++) {
(void)ll_conn_iso_stream_get_by_group(cig, &handle);
rp->handle[i] = sys_cpu_to_le16(handle);
}
}
} }
rp->status = status; rp->status = status;
@ -2110,9 +2140,9 @@ static void le_create_cis(struct net_buf *buf, struct net_buf **evt)
acl_handle = sys_le16_to_cpu(cmd->cis[i].acl_handle); acl_handle = sys_le16_to_cpu(cmd->cis[i].acl_handle);
status = ll_cis_create_check(cis_handle, acl_handle); status = ll_cis_create_check(cis_handle, acl_handle);
} }
*evt = cmd_status(status);
if (!status) { if (status) {
*evt = cmd_status(status);
return; return;
} }
@ -2129,6 +2159,8 @@ static void le_create_cis(struct net_buf *buf, struct net_buf **evt)
acl_handle = sys_le16_to_cpu(cmd->cis[i].acl_handle); acl_handle = sys_le16_to_cpu(cmd->cis[i].acl_handle);
ll_cis_create(cis_handle, acl_handle); ll_cis_create(cis_handle, acl_handle);
} }
*evt = cmd_status(status);
} }
static void le_remove_cig(struct net_buf *buf, struct net_buf **evt) static void le_remove_cig(struct net_buf *buf, struct net_buf **evt)
@ -4155,10 +4187,6 @@ static void le_cis_established(struct pdu_data *pdu_data,
cis = node_rx->hdr.rx_ftr.param; cis = node_rx->hdr.rx_ftr.param;
cig = cis->group; cig = cis->group;
lll_cis = &cis->lll;
is_central = cig->lll.role == BT_CONN_ROLE_CENTRAL;
lll_cis_c = is_central ? &lll_cis->tx : &lll_cis->rx;
lll_cis_p = is_central ? &lll_cis->rx : &lll_cis->tx;
sep = meta_evt(buf, BT_HCI_EVT_LE_CIS_ESTABLISHED, sizeof(*sep)); sep = meta_evt(buf, BT_HCI_EVT_LE_CIS_ESTABLISHED, sizeof(*sep));
@ -4171,6 +4199,17 @@ static void le_cis_established(struct pdu_data *pdu_data,
est = node; est = node;
sep->status = est->status; sep->status = est->status;
sep->conn_handle = sys_cpu_to_le16(est->cis_handle); sep->conn_handle = sys_cpu_to_le16(est->cis_handle);
if (!cig) {
/* CIS was not established and instance was released */
return;
}
lll_cis = &cis->lll;
is_central = cig->lll.role == BT_CONN_ROLE_CENTRAL;
lll_cis_c = is_central ? &lll_cis->tx : &lll_cis->rx;
lll_cis_p = is_central ? &lll_cis->rx : &lll_cis->tx;
sys_put_le24(cig->sync_delay, sep->cig_sync_delay); sys_put_le24(cig->sync_delay, sep->cig_sync_delay);
sys_put_le24(cis->sync_delay, sep->cis_sync_delay); sys_put_le24(cis->sync_delay, sep->cis_sync_delay);
sys_put_le24(cig->c_latency, sep->c_latency); sys_put_le24(cig->c_latency, sep->c_latency);

View file

@ -147,8 +147,7 @@ uint8_t ll_cig_parameters_open(uint8_t cig_id,
uint8_t ll_cis_parameters_set(uint8_t cis_id, uint8_t ll_cis_parameters_set(uint8_t cis_id,
uint16_t c_sdu, uint16_t p_sdu, uint16_t c_sdu, uint16_t p_sdu,
uint8_t c_phy, uint8_t p_phy, uint8_t c_phy, uint8_t p_phy,
uint8_t c_rtn, uint8_t p_rtn, uint8_t c_rtn, uint8_t p_rtn);
uint16_t *handle);
uint8_t ll_cig_parameters_commit(uint8_t cig_id); uint8_t ll_cig_parameters_commit(uint8_t cig_id);
uint8_t ll_cig_parameters_test_open(uint8_t cig_id, uint8_t ll_cig_parameters_test_open(uint8_t cig_id,
uint32_t c_interval, uint32_t c_interval,
@ -160,12 +159,11 @@ uint8_t ll_cig_parameters_test_open(uint8_t cig_id,
uint8_t packing, uint8_t packing,
uint8_t framing, uint8_t framing,
uint8_t num_cis); uint8_t num_cis);
uint8_t ll_cis_parameters_test_set(uint8_t cis_id, uint8_t ll_cis_parameters_test_set(uint8_t cis_id, uint8_t nse,
uint16_t c_sdu, uint16_t p_sdu, uint16_t c_sdu, uint16_t p_sdu,
uint16_t c_pdu, uint16_t p_pdu, uint16_t c_pdu, uint16_t p_pdu,
uint8_t c_phy, uint8_t p_phy, uint8_t c_phy, uint8_t p_phy,
uint8_t c_bn, uint8_t p_bn, uint8_t c_bn, uint8_t p_bn);
uint16_t *handle);
uint8_t ll_configure_data_path(uint8_t data_path_dir, uint8_t ll_configure_data_path(uint8_t data_path_dir,
uint8_t data_path_id, uint8_t data_path_id,
uint8_t vs_config_len, uint8_t vs_config_len,

View file

@ -33,8 +33,7 @@ uint8_t ll_cig_parameters_open(uint8_t cig_id,
uint8_t ll_cis_parameters_set(uint8_t cis_id, uint8_t ll_cis_parameters_set(uint8_t cis_id,
uint16_t c_sdu, uint16_t p_sdu, uint16_t c_sdu, uint16_t p_sdu,
uint8_t c_phy, uint8_t p_phy, uint8_t c_phy, uint8_t p_phy,
uint8_t c_rtn, uint8_t p_rtn, uint8_t c_rtn, uint8_t p_rtn)
uint16_t *handle)
{ {
ARG_UNUSED(cis_id); ARG_UNUSED(cis_id);
@ -74,12 +73,11 @@ uint8_t ll_cig_parameters_test_open(uint8_t cig_id,
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
} }
uint8_t ll_cis_parameters_test_set(uint8_t cis_id, uint8_t ll_cis_parameters_test_set(uint8_t cis_id, uint8_t nse,
uint16_t c_sdu, uint16_t p_sdu, uint16_t c_sdu, uint16_t p_sdu,
uint16_t c_pdu, uint16_t p_pdu, uint16_t c_pdu, uint16_t p_pdu,
uint8_t c_phy, uint8_t p_phy, uint8_t c_phy, uint8_t p_phy,
uint8_t c_bn, uint8_t p_bn, uint8_t c_bn, uint8_t p_bn)
uint16_t *handle)
{ {
ARG_UNUSED(cis_id); ARG_UNUSED(cis_id);
ARG_UNUSED(c_sdu); ARG_UNUSED(c_sdu);