Bluetooth: controller: Start CIG immediately if instant is next event
To be able to timely start the first CIS/CIG, if the requested instant is the next connection event, call ull_peripheral_iso_start directly from rp_cc_state_wait_rx_cis_ind instead of waiting for next time through the state machine. To enable ULL/LLL to prevent adding latency when LLCP is waiting for instant, local- and remote procedures with instant now expose a function for checking this state. Fixed event_counter function to prevent one-off in RX path. Unified to use single function ull_conn_event_counter. Fixed LLCP unit tests and added new mock function. Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
parent
1af16d896c
commit
a982c9f9f6
|
@ -8064,12 +8064,25 @@ uint16_t ull_conn_event_counter(struct ll_conn *conn)
|
|||
struct lll_conn *lll;
|
||||
uint16_t event_counter;
|
||||
|
||||
uint16_t lazy = conn->llcp.prep.lazy;
|
||||
|
||||
lll = &conn->lll;
|
||||
|
||||
/* Calculate current event counter */
|
||||
event_counter = lll->event_counter + lll->latency_prepare + lazy;
|
||||
/* Calculate current event counter. If refcount is non-zero, we have called
|
||||
* prepare and the LLL implementation has calculated and incremented the event
|
||||
* counter (RX path). In this case we need to subtract one from the current
|
||||
* event counter.
|
||||
* Otherwise we are in the TX path, and we calculate the current event counter
|
||||
* similar to LLL by taking the expected event counter value plus accumulated
|
||||
* latency.
|
||||
*/
|
||||
if (ull_ref_get(&conn->ull)) {
|
||||
/* We are in post-prepare (RX path). Event counter is already
|
||||
* calculated and incremented by 1 for next event.
|
||||
*/
|
||||
event_counter = lll->event_counter - 1;
|
||||
} else {
|
||||
event_counter = lll->event_counter + lll->latency_prepare +
|
||||
conn->llcp.prep.lazy;
|
||||
}
|
||||
|
||||
return event_counter;
|
||||
}
|
||||
|
|
|
@ -89,22 +89,6 @@ static void cc_ntf_established(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
static uint16_t cc_event_counter(struct ll_conn *conn)
|
||||
{
|
||||
struct lll_conn *lll;
|
||||
uint16_t event_counter;
|
||||
|
||||
uint16_t lazy = conn->llcp.prep.lazy;
|
||||
|
||||
/**/
|
||||
lll = &conn->lll;
|
||||
|
||||
/* Calculate current event counter */
|
||||
event_counter = lll->event_counter + lll->latency_prepare + lazy;
|
||||
|
||||
return event_counter;
|
||||
}
|
||||
|
||||
/* LLCP Remote Procedure FSM states */
|
||||
enum {
|
||||
/* Establish Procedure */
|
||||
|
@ -147,6 +131,9 @@ enum {
|
|||
RP_CC_EVT_UNKNOWN,
|
||||
};
|
||||
|
||||
static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||
void *param);
|
||||
|
||||
/*
|
||||
* LLCP Remote Procedure FSM
|
||||
*/
|
||||
|
@ -162,8 +149,13 @@ static void llcp_rp_cc_tx_rsp(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
|
||||
pdu = (struct pdu_data *)tx->pdu;
|
||||
|
||||
/* Postpone if instant is in this or next connection event. This would handle obsolete value
|
||||
* due to retransmission, as well as incorrect behavior by central.
|
||||
* We need at least 2 connection events to get ready. First for receiving the indication,
|
||||
* the second for setting up the CIS.
|
||||
*/
|
||||
ctx->data.cis_create.conn_event_count = MAX(ctx->data.cis_create.conn_event_count,
|
||||
cc_event_counter(conn) + 2);
|
||||
ull_conn_event_counter(conn) + 2);
|
||||
|
||||
llcp_pdu_encode_cis_rsp(ctx, pdu);
|
||||
ctx->tx_opcode = pdu->llctrl.opcode;
|
||||
|
@ -380,19 +372,13 @@ static void rp_cc_state_wait_rx_cis_ind(struct ll_conn *conn, struct proc_ctx *c
|
|||
case RP_CC_EVT_CIS_IND:
|
||||
llcp_pdu_decode_cis_ind(ctx, pdu);
|
||||
if (!ull_peripheral_iso_setup(&pdu->llctrl.cis_ind, ctx->data.cis_create.cig_id,
|
||||
ctx->data.cis_create.cis_handle)) {
|
||||
ctx->data.cis_create.cis_handle)) {
|
||||
|
||||
/* CIS has been setup, go wait for 'instant' before starting */
|
||||
ctx->state = RP_CC_STATE_WAIT_INSTANT;
|
||||
|
||||
/* Fixme - Implement CIS Supervision timeout
|
||||
* Spec:
|
||||
* When establishing a CIS, the Peripheral shall start the CIS supervision
|
||||
* timer at the start of the next CIS event after receiving the LL_CIS_IND.
|
||||
* If the CIS supervision timer reaches 6 * ISO_Interval before the CIS is
|
||||
* established, the CIS shall be considered lost.
|
||||
*/
|
||||
|
||||
/* Check if this connection event is where we need to start the CIS */
|
||||
rp_cc_check_instant(conn, ctx, evt, param);
|
||||
break;
|
||||
}
|
||||
/* If we get to here the CIG_ID referred in req/acquire has become void/invalid */
|
||||
|
@ -454,7 +440,7 @@ static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint
|
|||
}
|
||||
|
||||
if (is_instant_reached_or_passed(start_event_count,
|
||||
cc_event_counter(conn))) {
|
||||
ull_conn_event_counter(conn))) {
|
||||
/* Start CIS */
|
||||
ull_conn_iso_start(conn, conn->llcp.prep.ticks_at_expire,
|
||||
ctx->data.cis_create.cis_handle);
|
||||
|
@ -625,6 +611,11 @@ void llcp_rp_cc_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param)
|
|||
{
|
||||
rp_cc_execute_fsm(conn, ctx, RP_CC_EVT_RUN, param);
|
||||
}
|
||||
|
||||
bool llcp_rp_cc_awaiting_instant(struct proc_ctx *ctx)
|
||||
{
|
||||
return (ctx->state == RP_CC_STATE_WAIT_INSTANT);
|
||||
}
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO)
|
||||
|
|
|
@ -204,6 +204,10 @@ void llcp_lp_chmu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param)
|
|||
lp_chmu_execute_fsm(conn, ctx, LP_CHMU_EVT_RUN, param);
|
||||
}
|
||||
|
||||
bool llcp_lp_chmu_awaiting_instant(struct proc_ctx *ctx)
|
||||
{
|
||||
return (ctx->state == LP_CHMU_STATE_WAIT_INSTANT);
|
||||
}
|
||||
#endif /* CONFIG_BT_CENTRAL */
|
||||
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
|
@ -320,4 +324,9 @@ void llcp_rp_chmu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param)
|
|||
{
|
||||
rp_chmu_execute_fsm(conn, ctx, RP_CHMU_EVT_RUN, param);
|
||||
}
|
||||
|
||||
bool llcp_rp_chmu_awaiting_instant(struct proc_ctx *ctx)
|
||||
{
|
||||
return (ctx->state == RP_CHMU_STATE_WAIT_INSTANT);
|
||||
}
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
|
|
@ -1225,6 +1225,16 @@ void llcp_rp_cu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param)
|
|||
rp_cu_execute_fsm(conn, ctx, RP_CU_EVT_RUN, param);
|
||||
}
|
||||
|
||||
bool llcp_rp_cu_awaiting_instant(struct proc_ctx *ctx)
|
||||
{
|
||||
return (ctx->state == RP_CU_STATE_WAIT_INSTANT);
|
||||
}
|
||||
|
||||
bool llcp_lp_cu_awaiting_instant(struct proc_ctx *ctx)
|
||||
{
|
||||
return (ctx->state == LP_CU_STATE_WAIT_INSTANT);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
|
||||
void llcp_rp_conn_param_req_reply(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||
{
|
||||
|
|
|
@ -458,6 +458,7 @@ void llcp_lp_pu_init_proc(struct proc_ctx *ctx);
|
|||
void llcp_lp_pu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||
void llcp_lp_pu_tx_ack(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||
void llcp_lp_pu_tx_ntf(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||
bool llcp_lp_pu_awaiting_instant(struct proc_ctx *ctx);
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
/*
|
||||
|
@ -466,6 +467,7 @@ void llcp_lp_pu_tx_ntf(struct ll_conn *conn, struct proc_ctx *ctx);
|
|||
void llcp_lp_cu_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx);
|
||||
void llcp_lp_cu_init_proc(struct proc_ctx *ctx);
|
||||
void llcp_lp_cu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||
bool llcp_lp_cu_awaiting_instant(struct proc_ctx *ctx);
|
||||
|
||||
/*
|
||||
* LLCP Local Channel Map Update
|
||||
|
@ -473,6 +475,7 @@ void llcp_lp_cu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
|||
void llcp_lp_chmu_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx);
|
||||
void llcp_lp_chmu_init_proc(struct proc_ctx *ctx);
|
||||
void llcp_lp_chmu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||
bool llcp_lp_chmu_awaiting_instant(struct proc_ctx *ctx);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
/*
|
||||
|
@ -483,6 +486,7 @@ void llcp_rp_pu_init_proc(struct proc_ctx *ctx);
|
|||
void llcp_rp_pu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||
void llcp_rp_pu_tx_ack(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||
void llcp_rp_pu_tx_ntf(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||
bool llcp_rp_pu_awaiting_instant(struct proc_ctx *ctx);
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
/*
|
||||
|
@ -495,6 +499,7 @@ void llcp_rp_conn_param_req_reply(struct ll_conn *conn, struct proc_ctx *ctx);
|
|||
void llcp_rp_conn_param_req_neg_reply(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||
bool llcp_rp_conn_param_req_apm_awaiting_reply(struct proc_ctx *ctx);
|
||||
void llcp_rp_conn_param_req_apm_reply(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||
bool llcp_rp_cu_awaiting_instant(struct proc_ctx *ctx);
|
||||
|
||||
/*
|
||||
* Terminate Helper
|
||||
|
@ -659,6 +664,7 @@ void llcp_pdu_decode_chan_map_update_ind(struct proc_ctx *ctx, struct pdu_data *
|
|||
void llcp_rp_chmu_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx);
|
||||
void llcp_rp_chmu_init_proc(struct proc_ctx *ctx);
|
||||
void llcp_rp_chmu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||
bool llcp_rp_chmu_awaiting_instant(struct proc_ctx *ctx);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
/*
|
||||
|
@ -712,6 +718,7 @@ void llcp_rp_cc_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
|||
bool llcp_rp_cc_awaiting_reply(struct proc_ctx *ctx);
|
||||
void llcp_rp_cc_accept(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||
void llcp_rp_cc_reject(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||
bool llcp_rp_cc_awaiting_instant(struct proc_ctx *ctx);
|
||||
|
||||
void llcp_pdu_decode_cis_req(struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||
void llcp_pdu_encode_cis_rsp(struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||
|
|
|
@ -892,6 +892,12 @@ void llcp_lp_pu_tx_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
{
|
||||
lp_pu_execute_fsm(conn, ctx, LP_PU_EVT_NTF, NULL);
|
||||
}
|
||||
|
||||
bool llcp_lp_pu_awaiting_instant(struct proc_ctx *ctx)
|
||||
{
|
||||
return (ctx->state == LP_PU_STATE_WAIT_INSTANT);
|
||||
}
|
||||
|
||||
/*
|
||||
* LLCP Remote Procedure PHY Update FSM
|
||||
*/
|
||||
|
@ -1318,3 +1324,8 @@ void llcp_rp_pu_tx_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
{
|
||||
rp_pu_execute_fsm(conn, ctx, RP_PU_EVT_NTF, NULL);
|
||||
}
|
||||
|
||||
bool llcp_rp_pu_awaiting_instant(struct proc_ctx *ctx)
|
||||
{
|
||||
return (ctx->state == RP_PU_STATE_WAIT_INSTANT);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,11 @@ struct ll_conn_iso_stream *ll_conn_iso_stream_get(uint16_t handle)
|
|||
return &cis;
|
||||
}
|
||||
|
||||
struct ll_conn_iso_stream *ll_iso_stream_connected_get(uint16_t handle)
|
||||
{
|
||||
return &cis;
|
||||
}
|
||||
|
||||
struct ll_conn_iso_group *ll_conn_iso_group_get_by_id(uint8_t id)
|
||||
{
|
||||
return &cig;
|
||||
|
|
Loading…
Reference in a new issue