Bluetooth: controller: fix CIS REQ event generation and rejection
Check LE event mask state as well as host controlled feature mask state and reject CIS request accordingly. Release pre-allocated ISO resources on rejection of request Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
parent
32d10fca25
commit
6b324122e7
5 changed files with 45 additions and 9 deletions
|
@ -4097,14 +4097,6 @@ static void le_cis_request(struct pdu_data *pdu_data,
|
||||||
struct node_rx_conn_iso_req *req;
|
struct node_rx_conn_iso_req *req;
|
||||||
void *node;
|
void *node;
|
||||||
|
|
||||||
if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
|
|
||||||
!(le_event_mask & BT_EVT_MASK_LE_CIS_REQ)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sep = meta_evt(buf, BT_HCI_EVT_LE_CIS_REQ, sizeof(*sep));
|
|
||||||
sep->acl_handle = sys_cpu_to_le16(node_rx->hdr.handle);
|
|
||||||
|
|
||||||
/* Check for pdu field being aligned before accessing CIS established
|
/* Check for pdu field being aligned before accessing CIS established
|
||||||
* event.
|
* event.
|
||||||
*/
|
*/
|
||||||
|
@ -4112,6 +4104,15 @@ static void le_cis_request(struct pdu_data *pdu_data,
|
||||||
LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_conn_iso_estab));
|
LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_conn_iso_estab));
|
||||||
|
|
||||||
req = node;
|
req = node;
|
||||||
|
if (!(ll_feat_get() & BIT64(BT_LE_FEAT_BIT_ISO_CHANNELS)) ||
|
||||||
|
!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
|
||||||
|
!(le_event_mask & BT_EVT_MASK_LE_CIS_REQ)) {
|
||||||
|
ll_cis_reject(req->cis_handle, BT_HCI_ERR_UNSUPP_REMOTE_FEATURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sep = meta_evt(buf, BT_HCI_EVT_LE_CIS_REQ, sizeof(*sep));
|
||||||
|
sep->acl_handle = sys_cpu_to_le16(node_rx->hdr.handle);
|
||||||
sep->cis_handle = sys_cpu_to_le16(req->cis_handle);
|
sep->cis_handle = sys_cpu_to_le16(req->cis_handle);
|
||||||
sep->cig_id = req->cig_id;
|
sep->cig_id = req->cig_id;
|
||||||
sep->cis_id = req->cis_id;
|
sep->cis_id = req->cis_id;
|
||||||
|
|
|
@ -463,6 +463,8 @@ static void rp_cc_state_wait_reply(struct ll_conn *conn, struct proc_ctx *ctx, u
|
||||||
ctx->data.cis_create.error = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT;
|
ctx->data.cis_create.error = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT;
|
||||||
/* If timeout is hit, fall through and reject */
|
/* If timeout is hit, fall through and reject */
|
||||||
case RP_CC_EVT_CIS_REQ_REJECT:
|
case RP_CC_EVT_CIS_REQ_REJECT:
|
||||||
|
/* CIS Request is rejected, so clean up CIG/CIS acquisitions */
|
||||||
|
ull_peripheral_iso_release(ctx->data.cis_create.cis_handle);
|
||||||
/* Continue procedure in next prepare run */
|
/* Continue procedure in next prepare run */
|
||||||
ctx->state = RP_CC_STATE_WAIT_TX_REJECT_IND;
|
ctx->state = RP_CC_STATE_WAIT_TX_REJECT_IND;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -123,7 +123,7 @@ uint8_t ll_cis_reject(uint16_t handle, uint8_t reason)
|
||||||
struct ll_conn *acl_conn = ll_cis_get_acl_awaiting_reply(handle, &status);
|
struct ll_conn *acl_conn = ll_cis_get_acl_awaiting_reply(handle, &status);
|
||||||
|
|
||||||
if (acl_conn) {
|
if (acl_conn) {
|
||||||
/* Accept request */
|
/* Reject request */
|
||||||
ull_cp_cc_reject(acl_conn, reason);
|
ull_cp_cc_reject(acl_conn, reason);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -141,6 +141,28 @@ int ull_peripheral_iso_reset(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use this function to release CIS/CIG resources on an aborted CIS setup
|
||||||
|
* ie if CIS setup is 'cancelled' after call to ull_peripheral_iso_acquire()
|
||||||
|
* because of a rejection of the CIS request
|
||||||
|
*/
|
||||||
|
void ull_peripheral_iso_release(uint16_t cis_handle)
|
||||||
|
{
|
||||||
|
struct ll_conn_iso_stream *cis;
|
||||||
|
struct ll_conn_iso_group *cig;
|
||||||
|
|
||||||
|
cis = ll_conn_iso_stream_get(cis_handle);
|
||||||
|
LL_ASSERT(cis);
|
||||||
|
|
||||||
|
cig = cis->group;
|
||||||
|
|
||||||
|
ll_conn_iso_stream_release(cis);
|
||||||
|
cig->lll.num_cis--;
|
||||||
|
|
||||||
|
if (!cig->lll.num_cis) {
|
||||||
|
ll_conn_iso_group_release(cig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
||||||
struct pdu_data_llctrl_cis_req *req,
|
struct pdu_data_llctrl_cis_req *req,
|
||||||
uint16_t *cis_handle)
|
uint16_t *cis_handle)
|
||||||
|
@ -202,6 +224,12 @@ uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
||||||
/* Acquire new CIS */
|
/* Acquire new CIS */
|
||||||
cis = ll_conn_iso_stream_acquire();
|
cis = ll_conn_iso_stream_acquire();
|
||||||
if (cis == NULL) {
|
if (cis == NULL) {
|
||||||
|
if (!cig->lll.num_cis) {
|
||||||
|
/* No CIS's in CIG, so this was just allocated
|
||||||
|
* so release as we can't use it
|
||||||
|
*/
|
||||||
|
ll_conn_iso_group_release(cig);
|
||||||
|
}
|
||||||
/* No space for new CIS */
|
/* No space for new CIS */
|
||||||
return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
|
return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
int ull_peripheral_iso_init(void);
|
int ull_peripheral_iso_init(void);
|
||||||
int ull_peripheral_iso_reset(void);
|
int ull_peripheral_iso_reset(void);
|
||||||
|
|
||||||
|
void ull_peripheral_iso_release(uint16_t cis_handle);
|
||||||
uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
||||||
struct pdu_data_llctrl_cis_req *req,
|
struct pdu_data_llctrl_cis_req *req,
|
||||||
uint16_t *cis_handle);
|
uint16_t *cis_handle);
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
#include "ull_conn_iso_internal.h"
|
#include "ull_conn_iso_internal.h"
|
||||||
#include "lll_peripheral_iso.h"
|
#include "lll_peripheral_iso.h"
|
||||||
|
|
||||||
|
void ull_peripheral_iso_release(uint16_t cis_handle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
||||||
struct pdu_data_llctrl_cis_req *req,
|
struct pdu_data_llctrl_cis_req *req,
|
||||||
uint16_t *cis_handle)
|
uint16_t *cis_handle)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue