Bluetooth: controller: Implement CIS offset equivalent calculation
When the 'instant' of a CIS is postponed by increasing the conn_event of the CIS_RSP compared to CIS_REQ, the CIS offset shall be calculated as an equivalent window offset by an integer number of ISO intervals. This is obtained by increasing the CIS_Offset_Min and CIS_Offset_Max by the modulus of the connection interval delay time. Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
parent
a982c9f9f6
commit
78c3bf569b
3 changed files with 29 additions and 3 deletions
|
@ -140,14 +140,17 @@ static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint
|
|||
|
||||
static void llcp_rp_cc_tx_rsp(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||
{
|
||||
struct node_tx *tx;
|
||||
uint16_t delay_conn_events;
|
||||
uint16_t conn_event_count;
|
||||
struct pdu_data *pdu;
|
||||
struct node_tx *tx;
|
||||
|
||||
/* Allocate tx node */
|
||||
tx = llcp_tx_alloc(conn, ctx);
|
||||
LL_ASSERT(tx);
|
||||
|
||||
pdu = (struct pdu_data *)tx->pdu;
|
||||
conn_event_count = ctx->data.cis_create.conn_event_count;
|
||||
|
||||
/* 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.
|
||||
|
@ -157,6 +160,29 @@ static void llcp_rp_cc_tx_rsp(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
ctx->data.cis_create.conn_event_count = MAX(ctx->data.cis_create.conn_event_count,
|
||||
ull_conn_event_counter(conn) + 2);
|
||||
|
||||
delay_conn_events = ctx->data.cis_create.conn_event_count - conn_event_count;
|
||||
|
||||
/* If instant is postponed, calculate the offset to add to CIS_Offset_Min and
|
||||
* CIS_Offset_Max.
|
||||
*
|
||||
* BT Core v5.3, Vol 6, Part B, section 5.1.15:
|
||||
* Two windows are equivalent if they have the same width and the difference between their
|
||||
* start times is an integer multiple of ISO_Interval for the CIS.
|
||||
*
|
||||
* The offset shall compensate for the relation between ISO- and connection interval. The
|
||||
* offset translates to what is additionally needed to move the window by an integer number
|
||||
* of ISO intervals. I.e.:
|
||||
* offset = (delayed * CONN_interval) MOD ISO_interval
|
||||
*/
|
||||
if (delay_conn_events) {
|
||||
uint32_t conn_interval_us = conn->lll.interval * CONN_INT_UNIT_US;
|
||||
uint32_t iso_interval_us = ctx->data.cis_create.iso_interval * ISO_INT_UNIT_US;
|
||||
uint32_t offset_us = (delay_conn_events * conn_interval_us) % iso_interval_us;
|
||||
|
||||
ctx->data.cis_create.cis_offset_min += offset_us;
|
||||
ctx->data.cis_create.cis_offset_max += offset_us;
|
||||
}
|
||||
|
||||
llcp_pdu_encode_cis_rsp(ctx, pdu);
|
||||
ctx->tx_opcode = pdu->llctrl.opcode;
|
||||
|
||||
|
|
|
@ -258,6 +258,7 @@ struct proc_ctx {
|
|||
uint8_t cig_id;
|
||||
uint8_t cis_id;
|
||||
uint16_t conn_event_count;
|
||||
uint16_t iso_interval;
|
||||
uint32_t cis_offset_min;
|
||||
uint32_t cis_offset_max;
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
|
@ -281,7 +282,6 @@ struct proc_ctx {
|
|||
uint8_t c_bn;
|
||||
uint8_t c_ft;
|
||||
uint8_t p_ft;
|
||||
uint16_t iso_interval;
|
||||
uint8_t aa[4];
|
||||
#endif /* defined(CONFIG_BT_CENTRAL) */
|
||||
} cis_create;
|
||||
|
|
|
@ -775,6 +775,7 @@ void llcp_pdu_decode_cis_req(struct proc_ctx *ctx, struct pdu_data *pdu)
|
|||
ctx->data.cis_create.cis_offset_max = sys_get_le24(pdu->llctrl.cis_req.cis_offset_max);
|
||||
ctx->data.cis_create.conn_event_count =
|
||||
sys_le16_to_cpu(pdu->llctrl.cis_req.conn_event_count);
|
||||
ctx->data.cis_create.iso_interval = sys_le16_to_cpu(pdu->llctrl.cis_req.iso_interval);
|
||||
/* The remainder of the req is decoded by ull_peripheral_iso_acquire, so
|
||||
* no need to do it here too
|
||||
ctx->data.cis_create.c_phy = pdu->llctrl.cis_req.c_phy;
|
||||
|
@ -792,7 +793,6 @@ void llcp_pdu_decode_cis_req(struct proc_ctx *ctx, struct pdu_data *pdu)
|
|||
ctx->data.cis_create.c_bn = pdu->llctrl.cis_req.c_bn;
|
||||
ctx->data.cis_create.c_ft = pdu->llctrl.cis_req.c_ft;
|
||||
ctx->data.cis_create.p_ft = pdu->llctrl.cis_req.p_ft;
|
||||
ctx->data.cis_create.iso_interval = sys_le16_to_cpu(pdu->llctrl.cis_req.iso_interval);
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue