1 /*
2 * Copyright (c) 2020 Demant
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8
9 #include <zephyr/sys/byteorder.h>
10 #include <zephyr/sys/slist.h>
11 #include <zephyr/sys/util.h>
12
13 #include <zephyr/bluetooth/hci_types.h>
14
15 #include "hal/ccm.h"
16
17 #include "util/util.h"
18 #include "util/mem.h"
19 #include "util/memq.h"
20 #include "util/dbuf.h"
21
22 #include "pdu_df.h"
23 #include "lll/pdu_vendor.h"
24 #include "pdu.h"
25
26 #include "ll.h"
27 #include "ll_feat.h"
28 #include "ll_settings.h"
29
30 #include "lll.h"
31 #include "lll/lll_df_types.h"
32 #include "lll_conn.h"
33
34 #include "lll_conn_iso.h"
35
36 #include "ull_tx_queue.h"
37
38 #include "isoal.h"
39 #include "ull_iso_types.h"
40 #include "ull_conn_iso_types.h"
41 #include "ull_conn_iso_internal.h"
42
43 #include "ull_conn_internal.h"
44 #include "ull_conn_types.h"
45
46 #if defined(CONFIG_BT_CTLR_USER_EXT)
47 #include "ull_vendor.h"
48 #endif /* CONFIG_BT_CTLR_USER_EXT */
49
50 #include "ull_internal.h"
51 #include "ull_llcp.h"
52 #include "ull_llcp_features.h"
53 #include "ull_llcp_internal.h"
54
55 #include <soc.h>
56 #include "hal/debug.h"
57
58 /* Hardcoded instant delta +6 */
59 #define CONN_UPDATE_INSTANT_DELTA 6U
60
61 /* CPR parameter ranges */
62 #define CONN_UPDATE_TIMEOUT_100MS 10U
63 #define CONN_UPDATE_TIMEOUT_32SEC 3200U
64 #define CONN_UPDATE_LATENCY_MAX 499U
65 #define CONN_UPDATE_CONN_INTV_4SEC 3200U
66
67 /*
68 * TODO - Known, missing items (missing implementation):
69 *
70 * If DLE procedure supported:
71 * and current PHY is Coded PHY:
72 * ... (5.3.6.B.5.1.1) the new connection interval shall be at least connIntervalCodedMin us.
73 * ... (5.3.6.B.5.1.7.4) packet tx time restrictions should be in effect
74 *
75 * Inter-connection mutual exclusion on CPR
76 *
77 * LL/CON/MAS/BV-34-C [Accepting Connection Parameter Request w. event masked]
78 */
79
80 /* LLCP Local Procedure Connection Update FSM states */
81 enum {
82 LP_CU_STATE_IDLE = LLCP_STATE_IDLE,
83 LP_CU_STATE_WAIT_TX_CONN_PARAM_REQ,
84 LP_CU_STATE_WAIT_RX_CONN_PARAM_RSP,
85 LP_CU_STATE_WAIT_TX_CONN_UPDATE_IND,
86 LP_CU_STATE_WAIT_RX_CONN_UPDATE_IND,
87 LP_CU_STATE_WAIT_TX_REJECT_EXT_IND,
88 LP_CU_STATE_WAIT_INSTANT,
89 LP_CU_STATE_WAIT_NTF_AVAIL,
90 };
91
92 /* LLCP Local Procedure Connection Update FSM events */
93 enum {
94 /* Procedure run */
95 LP_CU_EVT_RUN,
96
97 /* Response received */
98 LP_CU_EVT_CONN_PARAM_RSP,
99
100 /* Indication received */
101 LP_CU_EVT_CONN_UPDATE_IND,
102
103 /* Reject response received */
104 LP_CU_EVT_REJECT,
105
106 /* Unknown response received */
107 LP_CU_EVT_UNKNOWN,
108 };
109
110 /* LLCP Remote Procedure Connection Update FSM states */
111 enum {
112 RP_CU_STATE_IDLE = LLCP_STATE_IDLE,
113 RP_CU_STATE_WAIT_RX_CONN_PARAM_REQ,
114 RP_CU_STATE_WAIT_CONN_PARAM_REQ_AVAILABLE,
115 RP_CU_STATE_WAIT_NTF_CONN_PARAM_REQ,
116 RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY,
117 RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY_CONTINUE,
118 RP_CU_STATE_WAIT_TX_REJECT_EXT_IND,
119 RP_CU_STATE_WAIT_USER_REPLY,
120 RP_CU_STATE_WAIT_TX_CONN_PARAM_RSP,
121 RP_CU_STATE_WAIT_TX_CONN_UPDATE_IND,
122 RP_CU_STATE_WAIT_RX_CONN_UPDATE_IND,
123 RP_CU_STATE_WAIT_INSTANT,
124 RP_CU_STATE_WAIT_NTF_AVAIL,
125 RP_CU_STATE_WAIT_TX_UNKNOWN_RSP
126 };
127
128 /* LLCP Remote Procedure Connection Update FSM events */
129 enum {
130 /* Procedure run */
131 RP_CU_EVT_RUN,
132
133 /* Request received */
134 RP_CU_EVT_CONN_PARAM_REQ,
135
136 /* Indication received */
137 RP_CU_EVT_CONN_UPDATE_IND,
138
139 /* CONN_PARAM_REQ reply */
140 RP_CU_EVT_CONN_PARAM_REQ_REPLY,
141
142 /* CONN_PARAM_REQ negative reply */
143 RP_CU_EVT_CONN_PARAM_REQ_NEG_REPLY,
144
145 /* CONN_PARAM_REQ Ancjor Point Move reply */
146 RP_CU_EVT_CONN_PARAM_REQ_USER_REPLY,
147 };
148
149 /*
150 * LLCP Local Procedure Connection Update FSM
151 */
152
cu_have_params_changed(struct ll_conn * conn,uint16_t interval,uint16_t latency,uint16_t timeout)153 static bool cu_have_params_changed(struct ll_conn *conn, uint16_t interval, uint16_t latency,
154 uint16_t timeout)
155 {
156 struct lll_conn *lll = &conn->lll;
157
158 if ((interval != lll->interval) || (latency != lll->latency) ||
159 (timeout != conn->supervision_timeout)) {
160 return true;
161 }
162 return false;
163 }
164
cu_update_conn_parameters(struct ll_conn * conn,struct proc_ctx * ctx)165 static void cu_update_conn_parameters(struct ll_conn *conn, struct proc_ctx *ctx)
166 {
167 ctx->data.cu.params_changed = cu_have_params_changed(
168 conn, ctx->data.cu.interval_max, ctx->data.cu.latency, ctx->data.cu.timeout);
169
170 ull_conn_update_parameters(conn, (ctx->proc == PROC_CONN_UPDATE), ctx->data.cu.win_size,
171 ctx->data.cu.win_offset_us, ctx->data.cu.interval_max,
172 ctx->data.cu.latency, ctx->data.cu.timeout,
173 ctx->data.cu.instant);
174 }
175
176 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
cu_check_conn_parameters(struct ll_conn * conn,struct proc_ctx * ctx)177 static bool cu_check_conn_parameters(struct ll_conn *conn, struct proc_ctx *ctx)
178 {
179 const uint16_t interval_min = ctx->data.cu.interval_min;
180 const uint16_t interval_max = ctx->data.cu.interval_max; /* unit conn events (ie 1.25ms) */
181 const uint16_t timeout = ctx->data.cu.timeout; /* unit 10ms */
182 const uint16_t latency = ctx->data.cu.latency;
183 const uint16_t preferred_periodicity = ctx->data.cu.preferred_periodicity;
184
185 /* Invalid parameters */
186 const bool invalid = ((interval_min < CONN_INTERVAL_MIN(conn)) ||
187 (interval_max > CONN_UPDATE_CONN_INTV_4SEC) ||
188 (interval_min > interval_max) ||
189 (latency > CONN_UPDATE_LATENCY_MAX) ||
190 (timeout < CONN_UPDATE_TIMEOUT_100MS) || (timeout > CONN_UPDATE_TIMEOUT_32SEC) ||
191 ((timeout * 4U) <= /* *4U re. conn events is equivalent to *2U re. ms */
192 ((latency + 1) * interval_max)) ||
193 (preferred_periodicity > interval_max));
194
195 return !invalid;
196 }
197 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
198
cu_check_conn_ind_parameters(struct ll_conn * conn,struct proc_ctx * ctx)199 static bool cu_check_conn_ind_parameters(struct ll_conn *conn, struct proc_ctx *ctx)
200 {
201 const uint16_t interval_max = ctx->data.cu.interval_max; /* unit 1.25ms */
202 const uint16_t timeout = ctx->data.cu.timeout; /* unit 10ms */
203 const uint16_t latency = ctx->data.cu.latency;
204
205 /* Valid conn_update_ind parameters */
206 return (interval_max >= CONN_INTERVAL_MIN(conn)) &&
207 (interval_max <= CONN_UPDATE_CONN_INTV_4SEC) &&
208 (latency <= CONN_UPDATE_LATENCY_MAX) &&
209 (timeout >= CONN_UPDATE_TIMEOUT_100MS) &&
210 (timeout <= CONN_UPDATE_TIMEOUT_32SEC) &&
211 ((timeout * 4U) > /* *4U re. conn events is equivalent to *2U re. ms */
212 ((latency + 1U) * interval_max));
213 }
214
cu_prepare_update_ind(struct ll_conn * conn,struct proc_ctx * ctx)215 static void cu_prepare_update_ind(struct ll_conn *conn, struct proc_ctx *ctx)
216 {
217 ctx->data.cu.win_size = 1U;
218 ctx->data.cu.win_offset_us = 0U;
219
220 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
221 /* Handle preferred periodicity */
222 const uint8_t preferred_periodicity = ctx->data.cu.preferred_periodicity;
223
224 if (preferred_periodicity) {
225 const uint16_t interval_max = (ctx->data.cu.interval_max / preferred_periodicity) *
226 preferred_periodicity;
227 if (interval_max >= ctx->data.cu.interval_min) {
228 /* In case of there is no underflowing interval_min use 'preferred max' */
229 ctx->data.cu.interval_max = interval_max;
230 }
231 }
232
233 #if !defined(CONFIG_BT_CTLR_SCHED_ADVANCED)
234 /* Use valid offset0 in range [0..interval]. An offset of
235 * 0xffff means not valid. Disregard other preferred offsets.
236 */
237 /* Handle win_offset/'anchor point move' */
238 if (ctx->data.cu.offsets[0] <= ctx->data.cu.interval_max) {
239 ctx->data.cu.win_offset_us = ctx->data.cu.offsets[0] * CONN_INT_UNIT_US;
240 }
241 #endif /* !CONFIG_BT_CTLR_SCHED_ADVANCED */
242 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
243
244 ctx->data.cu.instant = ull_conn_event_counter(conn) + conn->lll.latency +
245 CONN_UPDATE_INSTANT_DELTA;
246 }
247
cu_should_notify_host(struct proc_ctx * ctx)248 static bool cu_should_notify_host(struct proc_ctx *ctx)
249 {
250 return (((ctx->proc == PROC_CONN_PARAM_REQ) && (ctx->data.cu.error != 0U)) ||
251 (ctx->data.cu.params_changed != 0U));
252 }
253
cu_ntf(struct ll_conn * conn,struct proc_ctx * ctx)254 static void cu_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
255 {
256 struct node_rx_pdu *ntf;
257 struct node_rx_cu *pdu;
258 uint8_t piggy_back;
259
260 /* Allocate ntf node */
261 ntf = ctx->node_ref.rx;
262 ctx->node_ref.rx = NULL;
263 LL_ASSERT(ntf);
264
265 piggy_back = (ntf->hdr.type != NODE_RX_TYPE_RETAIN);
266
267 ntf->hdr.type = NODE_RX_TYPE_CONN_UPDATE;
268 ntf->hdr.handle = conn->lll.handle;
269 pdu = (struct node_rx_cu *)ntf->pdu;
270
271 pdu->status = ctx->data.cu.error;
272 if (!ctx->data.cu.error) {
273 pdu->interval = ctx->data.cu.interval_max;
274 pdu->latency = ctx->data.cu.latency;
275 pdu->timeout = ctx->data.cu.timeout;
276 } else {
277 pdu->interval = conn->lll.interval;
278 pdu->latency = conn->lll.latency;
279 pdu->timeout = conn->supervision_timeout;
280 }
281
282 if (!piggy_back) {
283 /* Enqueue notification towards LL, unless piggy-backing,
284 * in which case this is done on the rx return path
285 */
286 ll_rx_put_sched(ntf->hdr.link, ntf);
287 }
288 }
289
290 #if defined(CONFIG_BT_CENTRAL) || defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
lp_cu_tx(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t opcode)291 static void lp_cu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t opcode)
292 {
293 struct node_tx *tx;
294 struct pdu_data *pdu;
295
296 /* Get pre-allocated tx node */
297 tx = ctx->node_ref.tx;
298 ctx->node_ref.tx = NULL;
299
300 if (!tx) {
301 /* Allocate tx node if non pre-alloc'ed */
302 tx = llcp_tx_alloc(conn, ctx);
303 LL_ASSERT(tx);
304 }
305
306 pdu = (struct pdu_data *)tx->pdu;
307
308 /* Encode LL Control PDU */
309 switch (opcode) {
310 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
311 case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ:
312 llcp_pdu_encode_conn_param_req(ctx, pdu);
313 break;
314 case PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND:
315 llcp_pdu_encode_reject_ext_ind(pdu, ctx->data.cu.rejected_opcode,
316 ctx->data.cu.error);
317 break;
318 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
319 #if defined(CONFIG_BT_CENTRAL)
320 case PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND:
321 llcp_pdu_encode_conn_update_ind(ctx, pdu);
322 break;
323 #endif /* CONFIG_BT_CENTRAL */
324 default:
325 /* Unknown opcode */
326 LL_ASSERT(0);
327 break;
328 }
329
330 ctx->tx_opcode = pdu->llctrl.opcode;
331
332 /* Enqueue LL Control PDU towards LLL */
333 llcp_tx_enqueue(conn, tx);
334
335 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
336 if (ctx->proc == PROC_CONN_PARAM_REQ) {
337 /* Restart procedure response timeout timer */
338 llcp_lr_prt_restart(conn);
339 }
340 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
341 }
342 #endif /* CONFIG_BT_CENTRAL || CONFIG_BT_CTLR_CONN_PARAM_REQ */
343
lp_cu_complete(struct ll_conn * conn,struct proc_ctx * ctx)344 static void lp_cu_complete(struct ll_conn *conn, struct proc_ctx *ctx)
345 {
346 llcp_lr_complete(conn);
347 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
348 if (ctx->proc == PROC_CONN_PARAM_REQ &&
349 !(conn->lll.role && ull_cp_remote_cpr_pending(conn))) {
350 /* For a peripheral without a remote initiated CPR */
351 cpr_active_check_and_reset(conn);
352 }
353 #endif /* defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) */
354 ctx->state = LP_CU_STATE_IDLE;
355 }
356
lp_cu_ntf_complete(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)357 static void lp_cu_ntf_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
358 void *param)
359 {
360 cu_ntf(conn, ctx);
361 lp_cu_complete(conn, ctx);
362 }
363
364 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
lp_cu_send_reject_ext_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)365 static void lp_cu_send_reject_ext_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
366 void *param)
367 {
368 if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
369 ctx->state = LP_CU_STATE_WAIT_TX_REJECT_EXT_IND;
370 } else {
371 llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION);
372 lp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND);
373 lp_cu_complete(conn, ctx);
374 }
375 }
376
lp_cu_send_conn_param_req(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)377 static void lp_cu_send_conn_param_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
378 void *param)
379 {
380 if (cpr_active_is_set(conn) || llcp_lr_ispaused(conn) ||
381 llcp_rr_get_collision(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
382 ctx->state = LP_CU_STATE_WAIT_TX_CONN_PARAM_REQ;
383 } else {
384 uint16_t event_counter = ull_conn_event_counter(conn);
385
386 llcp_rr_set_incompat(conn, INCOMPAT_RESOLVABLE);
387
388 ctx->data.cu.reference_conn_event_count = event_counter;
389 ctx->data.cu.preferred_periodicity = 0U;
390
391 /* Mark CPR as active */
392 cpr_active_set(conn);
393
394 lp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ);
395
396 switch (conn->lll.role) {
397 #if defined(CONFIG_BT_CENTRAL)
398 case BT_HCI_ROLE_CENTRAL:
399 ctx->state = LP_CU_STATE_WAIT_RX_CONN_PARAM_RSP;
400 ctx->rx_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP;
401 break;
402 #endif /* CONFIG_BT_CENTRAL */
403 #if defined(CONFIG_BT_PERIPHERAL)
404 case BT_HCI_ROLE_PERIPHERAL:
405 ctx->state = LP_CU_STATE_WAIT_RX_CONN_UPDATE_IND;
406 ctx->rx_opcode = PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND;
407 break;
408 #endif /* CONFIG_BT_PERIPHERAL */
409 default:
410 /* Unknown role */
411 LL_ASSERT(0);
412 break;
413 }
414 }
415 }
416 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
417
418 #if defined(CONFIG_BT_CENTRAL)
lp_cu_send_conn_update_ind_finalize(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)419 static void lp_cu_send_conn_update_ind_finalize(struct ll_conn *conn, struct proc_ctx *ctx,
420 uint8_t evt, void *param)
421 {
422 if (ctx->node_ref.rx == NULL) {
423 /* If we get here without RX node we know one is avail to be allocated,
424 * so pre-alloc NTF node
425 */
426 ctx->node_ref.rx = llcp_ntf_alloc();
427 }
428
429 /* Signal put/sched on NTF - ie non-RX node piggy */
430 ctx->node_ref.rx->hdr.type = NODE_RX_TYPE_RETAIN;
431
432 cu_prepare_update_ind(conn, ctx);
433 lp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND);
434 ctx->rx_opcode = PDU_DATA_LLCTRL_TYPE_UNUSED;
435 ctx->state = LP_CU_STATE_WAIT_INSTANT;
436 }
437
lp_cu_send_conn_update_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)438 static void lp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
439 void *param)
440 {
441 if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
442 ctx->state = LP_CU_STATE_WAIT_TX_CONN_UPDATE_IND;
443 } else {
444 /* ensure alloc of TX node, before possibly waiting for NTF node */
445 ctx->node_ref.tx = llcp_tx_alloc(conn, ctx);
446 if (ctx->node_ref.rx == NULL && !llcp_ntf_alloc_is_available()) {
447 /* No RX node piggy, and no NTF avail, so go wait for one, before TX'ing */
448 ctx->state = LP_CU_STATE_WAIT_NTF_AVAIL;
449 } else {
450 lp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param);
451 }
452 }
453 }
454
lp_cu_st_wait_ntf_avail(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)455 static void lp_cu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
456 void *param)
457 {
458 switch (evt) {
459 case LP_CU_EVT_RUN:
460 if (llcp_ntf_alloc_is_available()) {
461 lp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param);
462 }
463 break;
464 default:
465 /* Ignore other evts */
466 break;
467 }
468 }
469 #endif /* CONFIG_BT_CENTRAL */
470
lp_cu_st_idle(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)471 static void lp_cu_st_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
472 {
473 switch (evt) {
474 case LP_CU_EVT_RUN:
475 switch (ctx->proc) {
476 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
477 case PROC_CONN_PARAM_REQ:
478 lp_cu_send_conn_param_req(conn, ctx, evt, param);
479 break;
480 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
481 #if defined(CONFIG_BT_CENTRAL)
482 case PROC_CONN_UPDATE:
483 /* Ensure the non-piggy-back'ing is signaled */
484 ctx->node_ref.rx = NULL;
485 lp_cu_send_conn_update_ind(conn, ctx, evt, param);
486 break;
487 #endif /* CONFIG_BT_CENTRAL */
488 default:
489 /* Unknown procedure */
490 LL_ASSERT(0);
491 break;
492 }
493 break;
494 default:
495 /* Ignore other evts */
496 break;
497 }
498 }
499
500 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
lp_cu_st_wait_tx_reject_ext_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)501 static void lp_cu_st_wait_tx_reject_ext_ind(struct ll_conn *conn, struct proc_ctx *ctx,
502 uint8_t evt, void *param)
503 {
504 switch (evt) {
505 case LP_CU_EVT_RUN:
506 lp_cu_send_reject_ext_ind(conn, ctx, evt, param);
507 break;
508 default:
509 /* Ignore other evts */
510 break;
511 }
512 }
513
514
lp_cu_st_wait_tx_conn_param_req(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)515 static void lp_cu_st_wait_tx_conn_param_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
516 void *param)
517 {
518 switch (evt) {
519 case LP_CU_EVT_RUN:
520 lp_cu_send_conn_param_req(conn, ctx, evt, param);
521 break;
522 default:
523 /* Ignore other evts */
524 break;
525 }
526 }
527 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
528
529 #if defined(CONFIG_BT_CENTRAL)
530 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
lp_cu_st_wait_rx_conn_param_rsp(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)531 static void lp_cu_st_wait_rx_conn_param_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
532 void *param)
533 {
534 struct pdu_data *pdu = (struct pdu_data *)param;
535
536 switch (evt) {
537 case LP_CU_EVT_CONN_PARAM_RSP:
538 llcp_pdu_decode_conn_param_rsp(ctx, param);
539 llcp_rr_set_incompat(conn, INCOMPAT_RESERVED);
540 /* Perform Param check and possibly reject (LL_REJECT_EXT_IND) */
541 if (!cu_check_conn_parameters(conn, ctx)) {
542 ctx->data.cu.rejected_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP;
543 ctx->data.cu.error = BT_HCI_ERR_INVALID_LL_PARAM;
544 lp_cu_send_reject_ext_ind(conn, ctx, evt, param);
545 break;
546 }
547 /* Keep RX node to use for NTF */
548 llcp_rx_node_retain(ctx);
549 lp_cu_send_conn_update_ind(conn, ctx, evt, param);
550 break;
551 case LP_CU_EVT_UNKNOWN:
552 llcp_rr_set_incompat(conn, INCOMPAT_RESERVED);
553 /* Unsupported in peer, so disable locally for this connection */
554 feature_unmask_features(conn, LL_FEAT_BIT_CONN_PARAM_REQ);
555 /* Keep RX node to use for NTF */
556 llcp_rx_node_retain(ctx);
557 lp_cu_send_conn_update_ind(conn, ctx, evt, param);
558 break;
559 case LP_CU_EVT_REJECT:
560 if (pdu->llctrl.reject_ext_ind.error_code == BT_HCI_ERR_UNSUPP_REMOTE_FEATURE) {
561 /* Remote legacy Host */
562 llcp_rr_set_incompat(conn, INCOMPAT_RESERVED);
563 /* Unsupported in peer, so disable locally for this connection */
564 feature_unmask_features(conn, LL_FEAT_BIT_CONN_PARAM_REQ);
565 /* Keep RX node to use for NTF */
566 llcp_rx_node_retain(ctx);
567 lp_cu_send_conn_update_ind(conn, ctx, evt, param);
568 } else {
569 llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION);
570 ctx->data.cu.error = pdu->llctrl.reject_ext_ind.error_code;
571 lp_cu_ntf_complete(conn, ctx, evt, param);
572 }
573 break;
574 default:
575 /* Ignore other evts */
576 break;
577 }
578 }
579 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
580
lp_cu_st_wait_tx_conn_update_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)581 static void lp_cu_st_wait_tx_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx,
582 uint8_t evt, void *param)
583 {
584 switch (evt) {
585 case LP_CU_EVT_RUN:
586 lp_cu_send_conn_update_ind(conn, ctx, evt, param);
587 break;
588 default:
589 /* Ignore other evts */
590 break;
591 }
592 }
593 #endif /* CONFIG_BT_CENTRAL */
594
595 #if defined(CONFIG_BT_PERIPHERAL)
lp_cu_st_wait_rx_conn_update_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)596 static void lp_cu_st_wait_rx_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx,
597 uint8_t evt, void *param)
598 {
599 struct pdu_data *pdu = (struct pdu_data *)param;
600
601 switch (evt) {
602 case LP_CU_EVT_CONN_UPDATE_IND:
603 llcp_pdu_decode_conn_update_ind(ctx, param);
604
605 /* Invalid PDU, mark the connection for termination */
606 if (!cu_check_conn_ind_parameters(conn, ctx)) {
607 llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION);
608 conn->llcp_terminate.reason_final = BT_HCI_ERR_INVALID_LL_PARAM;
609 lp_cu_complete(conn, ctx);
610 break;
611 }
612
613 llcp_rr_set_incompat(conn, INCOMPAT_RESERVED);
614
615 /* Keep RX node to use for NTF */
616 llcp_rx_node_retain(ctx);
617
618 ctx->state = LP_CU_STATE_WAIT_INSTANT;
619 break;
620 case LP_CU_EVT_UNKNOWN:
621 /* Unsupported in peer, so disable locally for this connection */
622 feature_unmask_features(conn, LL_FEAT_BIT_CONN_PARAM_REQ);
623 ctx->data.cu.error = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE;
624 lp_cu_ntf_complete(conn, ctx, evt, param);
625 break;
626 case LP_CU_EVT_REJECT:
627 ctx->data.cu.error = pdu->llctrl.reject_ext_ind.error_code;
628 lp_cu_ntf_complete(conn, ctx, evt, param);
629 break;
630 default:
631 /* Ignore other evts */
632 break;
633 }
634 }
635 #endif /* CONFIG_BT_PERIPHERAL */
636
lp_cu_check_instant(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)637 static void lp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
638 void *param)
639 {
640 uint16_t event_counter = ull_conn_event_counter(conn);
641
642 if (is_instant_reached_or_passed(ctx->data.cu.instant, event_counter)) {
643 bool notify;
644
645 /* Procedure is complete when the instant has passed, and the
646 * new connection event parameters have been applied.
647 */
648 llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION);
649 cu_update_conn_parameters(conn, ctx);
650
651 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
652 if (ctx->proc == PROC_CONN_PARAM_REQ) {
653 /* Stop procedure response timeout timer */
654 llcp_lr_prt_stop(conn);
655 }
656 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
657
658 notify = cu_should_notify_host(ctx);
659 if (notify) {
660 ctx->data.cu.error = BT_HCI_ERR_SUCCESS;
661 lp_cu_ntf_complete(conn, ctx, evt, param);
662 } else {
663 /* Release RX node kept for NTF */
664 llcp_rx_node_release(ctx);
665 ctx->node_ref.rx = NULL;
666
667 lp_cu_complete(conn, ctx);
668 }
669 }
670 }
671
lp_cu_st_wait_instant(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)672 static void lp_cu_st_wait_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
673 void *param)
674 {
675 switch (evt) {
676 case LP_CU_EVT_RUN:
677 lp_cu_check_instant(conn, ctx, evt, param);
678 break;
679 case LP_CU_EVT_REJECT:
680 /* In case of a central overtaking a peripheral initiated connection
681 * param request the following will occur:
682 * Since CONNECTION_UPDATE_IND PDU is used both as response to the peripheral
683 * connection param request AND as initiation of a remote connection update
684 * the peripheral cannot tell the difference in the case when there is a
685 * collision. Ie when the central and peripheral 'exchange' CONNECTION_PARAM_REQ
686 * and CONNECTION_UPDATE_IND in the same connection event. In this case
687 * the central should follow the CONNECTION_UPDATE_IND with a REJECT_IND to
688 * signal procedure collision and then complete procedure as initiated.
689 * The peer on the other hand, should abandon the local initiated procedure
690 * and instead run the remote connection update to completion. What happens
691 * instead is that the peripheral reaches WAIT_FOR_INSTANT state as it
692 * assumes the UPDATE_IND was a response to the local procedure. As a result
693 * the REJECT_IND will be passed into the local procedure RX path and end up
694 * 'here'. See test case: test_conn_update_periph_loc_reject_central_overlap
695 * in unit test: tests/bluetooth/controller/ctrl_conn_update/src/main.c
696 *
697 * In the current implementation of LLCP there is no way of handling
698 * this transition from local initiated to remote initiated procedure and thus
699 * the only way to handle this 'corner' case is to allow the local procedure to
700 * complete and accept impact of not having it complete as a remote procedure.
701 *
702 * The impact being:
703 * -> since it runs as a local procedure it will block other local procedures
704 * from being initiated while non-complete. Since non-instant based procedures
705 * are allowed this is a limitation
706 * -> since procedure continues as local initiated the procedure timeout will
707 * be off (too short) by as much as the time between CONNECTION_PARAM_REQ
708 * and CONNECTION_UPDATE_IND pdus
709 *
710 * The work around for this is to ignore the REJECT_IND at this stage and
711 * ensure proper function of RX node retention mechanism.
712 * (see comment in ull_llcp_local.c::llcp_lr_rx() for details on this)
713 */
714 /* Fall through to ignore */
715 default:
716 /* Ignore other evts */
717 break;
718 }
719 }
720
lp_cu_execute_fsm(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)721 static void lp_cu_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
722 {
723 switch (ctx->state) {
724 case LP_CU_STATE_IDLE:
725 lp_cu_st_idle(conn, ctx, evt, param);
726 break;
727 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
728 case LP_CU_STATE_WAIT_TX_CONN_PARAM_REQ:
729 lp_cu_st_wait_tx_conn_param_req(conn, ctx, evt, param);
730 break;
731 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
732 #if defined(CONFIG_BT_CENTRAL)
733 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
734 case LP_CU_STATE_WAIT_RX_CONN_PARAM_RSP:
735 lp_cu_st_wait_rx_conn_param_rsp(conn, ctx, evt, param);
736 break;
737 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
738 case LP_CU_STATE_WAIT_TX_CONN_UPDATE_IND:
739 lp_cu_st_wait_tx_conn_update_ind(conn, ctx, evt, param);
740 break;
741 case LP_CU_STATE_WAIT_NTF_AVAIL:
742 lp_cu_st_wait_ntf_avail(conn, ctx, evt, param);
743 break;
744 #endif /* CONFIG_BT_CENTRAL */
745 #if defined(CONFIG_BT_PERIPHERAL)
746 case LP_CU_STATE_WAIT_RX_CONN_UPDATE_IND:
747 lp_cu_st_wait_rx_conn_update_ind(conn, ctx, evt, param);
748 break;
749 #endif /* CONFIG_BT_PERIPHERAL */
750 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
751 case LP_CU_STATE_WAIT_TX_REJECT_EXT_IND:
752 lp_cu_st_wait_tx_reject_ext_ind(conn, ctx, evt, param);
753 break;
754 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
755 case LP_CU_STATE_WAIT_INSTANT:
756 lp_cu_st_wait_instant(conn, ctx, evt, param);
757 break;
758 default:
759 /* Unknown state */
760 LL_ASSERT(0);
761 break;
762 }
763 }
764
llcp_lp_cu_rx(struct ll_conn * conn,struct proc_ctx * ctx,struct node_rx_pdu * rx)765 void llcp_lp_cu_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx)
766 {
767 struct pdu_data *pdu = (struct pdu_data *)rx->pdu;
768
769 switch (pdu->llctrl.opcode) {
770 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
771 case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP:
772 lp_cu_execute_fsm(conn, ctx, LP_CU_EVT_CONN_PARAM_RSP, pdu);
773 break;
774 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
775 case PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND:
776 lp_cu_execute_fsm(conn, ctx, LP_CU_EVT_CONN_UPDATE_IND, pdu);
777 break;
778 case PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP:
779 lp_cu_execute_fsm(conn, ctx, LP_CU_EVT_UNKNOWN, pdu);
780 break;
781 case PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND:
782 lp_cu_execute_fsm(conn, ctx, LP_CU_EVT_REJECT, pdu);
783 break;
784 default:
785 /* Invalid behaviour */
786 /* Invalid PDU received so terminate connection */
787 conn->llcp_terminate.reason_final = BT_HCI_ERR_LMP_PDU_NOT_ALLOWED;
788 lp_cu_complete(conn, ctx);
789 break;
790 }
791 }
792
llcp_lp_cu_run(struct ll_conn * conn,struct proc_ctx * ctx,void * param)793 void llcp_lp_cu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param)
794 {
795 lp_cu_execute_fsm(conn, ctx, LP_CU_EVT_RUN, param);
796 }
797
798 /*
799 * LLCP Remote Procedure Connection Update FSM
800 */
801
rp_cu_tx(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t opcode)802 static void rp_cu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t opcode)
803 {
804 struct node_tx *tx;
805 struct pdu_data *pdu;
806
807 /* Get pre-allocated tx node */
808 tx = ctx->node_ref.tx;
809 ctx->node_ref.tx = NULL;
810
811 if (!tx) {
812 /* Allocate tx node if non pre-alloc'ed */
813 tx = llcp_tx_alloc(conn, ctx);
814 LL_ASSERT(tx);
815 }
816
817 pdu = (struct pdu_data *)tx->pdu;
818
819 /* Encode LL Control PDU */
820 switch (opcode) {
821 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
822 case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP:
823 llcp_pdu_encode_conn_param_rsp(ctx, pdu);
824 break;
825 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
826 case PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND:
827 llcp_pdu_encode_conn_update_ind(ctx, pdu);
828 break;
829 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
830 case PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND:
831 llcp_pdu_encode_reject_ext_ind(pdu, ctx->data.cu.rejected_opcode,
832 ctx->data.cu.error);
833 break;
834 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
835 case PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP:
836 llcp_pdu_encode_unknown_rsp(ctx, pdu);
837 break;
838 default:
839 /* Unknown opcode */
840 LL_ASSERT(0);
841 break;
842 }
843
844 ctx->tx_opcode = pdu->llctrl.opcode;
845
846 /* Enqueue LL Control PDU towards LLL */
847 llcp_tx_enqueue(conn, tx);
848
849 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
850 if (ctx->proc == PROC_CONN_PARAM_REQ) {
851 /* Restart procedure response timeout timer */
852 llcp_rr_prt_restart(conn);
853 }
854 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
855 }
856
857 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
rp_cu_conn_param_req_ntf(struct ll_conn * conn,struct proc_ctx * ctx)858 static void rp_cu_conn_param_req_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
859 {
860 struct node_rx_pdu *ntf;
861 struct pdu_data *pdu;
862 uint8_t piggy_back;
863
864
865 /* Allocate ntf node */
866 ntf = ctx->node_ref.rx;
867 ctx->node_ref.rx = NULL;
868 LL_ASSERT(ntf);
869
870 piggy_back = (ntf->hdr.type != NODE_RX_TYPE_RETAIN);
871
872 ntf->hdr.type = NODE_RX_TYPE_DC_PDU;
873 ntf->hdr.handle = conn->lll.handle;
874 pdu = (struct pdu_data *)ntf->pdu;
875
876 llcp_pdu_encode_conn_param_req(ctx, pdu);
877
878 if (!piggy_back) {
879 /* Enqueue notification towards LL, unless piggy-backing,
880 * in which case this is done on the rx return path
881 */
882 ll_rx_put_sched(ntf->hdr.link, ntf);
883 }
884 }
885 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
886
rp_cu_complete(struct ll_conn * conn,struct proc_ctx * ctx)887 static void rp_cu_complete(struct ll_conn *conn, struct proc_ctx *ctx)
888 {
889 llcp_rr_complete(conn);
890 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
891 if (ctx->proc == PROC_CONN_PARAM_REQ) {
892 cpr_active_check_and_reset(conn);
893 }
894 #endif /* defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) */
895 ctx->state = RP_CU_STATE_IDLE;
896 }
897
rp_cu_send_conn_update_ind_finalize(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)898 static void rp_cu_send_conn_update_ind_finalize(struct ll_conn *conn, struct proc_ctx *ctx,
899 uint8_t evt, void *param)
900 {
901 /* Central role path, should not get here with !=NULL rx-node reference */
902 LL_ASSERT(ctx->node_ref.rx == NULL);
903 /* We pre-alloc NTF node */
904 ctx->node_ref.rx = llcp_ntf_alloc();
905
906 /* Signal put/sched on NTF - ie non-RX node piggy */
907 ctx->node_ref.rx->hdr.type = NODE_RX_TYPE_RETAIN;
908
909 cu_prepare_update_ind(conn, ctx);
910 rp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND);
911 ctx->rx_opcode = PDU_DATA_LLCTRL_TYPE_UNUSED;
912 ctx->state = RP_CU_STATE_WAIT_INSTANT;
913 }
914
rp_cu_send_conn_update_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)915 static void rp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
916 void *param)
917 {
918 if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
919 ctx->state = RP_CU_STATE_WAIT_TX_CONN_UPDATE_IND;
920 } else {
921 /* ensure alloc of TX node, before possibly waiting for NTF node */
922 ctx->node_ref.tx = llcp_tx_alloc(conn, ctx);
923 if (!llcp_ntf_alloc_is_available()) {
924 /* No RX node piggy, and no NTF avail, so go wait for one, before TX'ing */
925 ctx->state = RP_CU_STATE_WAIT_NTF_AVAIL;
926 } else {
927 rp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param);
928 }
929 }
930 }
931
rp_cu_st_wait_ntf_avail(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)932 static void rp_cu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
933 void *param)
934 {
935 switch (evt) {
936 case RP_CU_EVT_RUN:
937 if (llcp_ntf_alloc_is_available()) {
938 /* If NTF node is now avail, so pick it up and continue */
939 rp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param);
940 }
941 break;
942 default:
943 /* Ignore other evts */
944 break;
945 }
946 }
947
948 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
rp_cu_send_reject_ext_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)949 static void rp_cu_send_reject_ext_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
950 void *param)
951 {
952 if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
953 ctx->state = RP_CU_STATE_WAIT_TX_REJECT_EXT_IND;
954 } else {
955 rp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND);
956 rp_cu_complete(conn, ctx);
957 }
958 }
959
rp_cu_send_conn_param_rsp(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)960 static void rp_cu_send_conn_param_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
961 void *param)
962 {
963 if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
964 ctx->state = RP_CU_STATE_WAIT_TX_CONN_PARAM_RSP;
965 } else {
966 rp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP);
967 ctx->rx_opcode = PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND;
968 ctx->state = RP_CU_STATE_WAIT_RX_CONN_UPDATE_IND;
969 }
970 }
971
rp_cu_send_conn_param_req_ntf(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)972 static void rp_cu_send_conn_param_req_ntf(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
973 void *param)
974 {
975 if (!llcp_ntf_alloc_is_available()) {
976 ctx->state = RP_CU_STATE_WAIT_NTF_CONN_PARAM_REQ;
977 } else {
978 rp_cu_conn_param_req_ntf(conn, ctx);
979 ctx->state = RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY;
980 }
981 }
982 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
983
rp_cu_send_unknown_rsp(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)984 static void rp_cu_send_unknown_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
985 void *param)
986 {
987 if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
988 ctx->state = RP_CU_STATE_WAIT_TX_UNKNOWN_RSP;
989 } else {
990 rp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP);
991 rp_cu_complete(conn, ctx);
992 }
993 }
994
rp_cu_st_idle(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)995 static void rp_cu_st_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
996 {
997 switch (evt) {
998 case RP_CU_EVT_RUN:
999 switch (ctx->proc) {
1000 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
1001 case PROC_CONN_PARAM_REQ:
1002 ctx->state = RP_CU_STATE_WAIT_RX_CONN_PARAM_REQ;
1003 break;
1004 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
1005 case PROC_CONN_UPDATE:
1006 ctx->state = RP_CU_STATE_WAIT_RX_CONN_UPDATE_IND;
1007 break;
1008 default:
1009 /* Unknown procedure */
1010 LL_ASSERT(0);
1011 break;
1012 }
1013 break;
1014 default:
1015 /* Ignore other evts */
1016 break;
1017 }
1018 }
1019
1020 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
rp_cu_st_wait_conn_param_req_available(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1021 static void rp_cu_st_wait_conn_param_req_available(struct ll_conn *conn, struct proc_ctx *ctx,
1022 uint8_t evt, void *param)
1023 {
1024 /* Check if CPR is already active on other connection.
1025 * If so check if possible to send reject right away
1026 * otherwise stay in wait state in case CPR becomes
1027 * available before we can send send reject
1028 */
1029 switch (evt) {
1030 case RP_CU_EVT_CONN_PARAM_REQ:
1031 case RP_CU_EVT_RUN:
1032 if (cpr_active_is_set(conn)) {
1033 ctx->state = RP_CU_STATE_WAIT_CONN_PARAM_REQ_AVAILABLE;
1034
1035 if (!llcp_rr_ispaused(conn) && llcp_tx_alloc_peek(conn, ctx)) {
1036 /* We're good to reject immediately */
1037 ctx->data.cu.rejected_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ;
1038 ctx->data.cu.error = BT_HCI_ERR_UNSUPP_LL_PARAM_VAL;
1039 rp_cu_send_reject_ext_ind(conn, ctx, evt, param);
1040
1041 /* Possibly retained rx node to be released as we won't need it */
1042 llcp_rx_node_release(ctx);
1043 ctx->node_ref.rx = NULL;
1044
1045 break;
1046 }
1047 /* In case we have to defer NTF */
1048 llcp_rx_node_retain(ctx);
1049 } else {
1050 cpr_active_set(conn);
1051 const bool params_changed =
1052 cu_have_params_changed(conn, ctx->data.cu.interval_max,
1053 ctx->data.cu.latency, ctx->data.cu.timeout);
1054
1055 /* notify Host if conn parameters changed, else respond */
1056 if (params_changed) {
1057 rp_cu_conn_param_req_ntf(conn, ctx);
1058 ctx->state = RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY;
1059 } else {
1060 /* Possibly retained rx node to be released as we won't need it */
1061 llcp_rx_node_release(ctx);
1062 ctx->node_ref.rx = NULL;
1063 #if defined(CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE)
1064 /* Handle APM as a vendor specific user extension */
1065 if (conn->lll.role == BT_HCI_ROLE_PERIPHERAL &&
1066 DEFER_APM_CHECK(conn, ctx->data.cu.offsets,
1067 &ctx->data.cu.error)) {
1068 /* Wait for user response */
1069 ctx->state = RP_CU_STATE_WAIT_USER_REPLY;
1070 break;
1071 }
1072 #endif /* CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE */
1073 ctx->state = RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY_CONTINUE;
1074 }
1075 }
1076 default:
1077 /* Ignore other evts */
1078 break;
1079 }
1080 }
1081
rp_cu_st_wait_rx_conn_param_req(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1082 static void rp_cu_st_wait_rx_conn_param_req(struct ll_conn *conn, struct proc_ctx *ctx,
1083 uint8_t evt, void *param)
1084 {
1085 switch (evt) {
1086 case RP_CU_EVT_CONN_PARAM_REQ:
1087 llcp_pdu_decode_conn_param_req(ctx, param);
1088
1089 /* Perform Param check and reject if invalid (LL_REJECT_EXT_IND) */
1090 if (!cu_check_conn_parameters(conn, ctx)) {
1091 ctx->data.cu.rejected_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ;
1092 ctx->data.cu.error = BT_HCI_ERR_INVALID_LL_PARAM;
1093 rp_cu_send_reject_ext_ind(conn, ctx, evt, param);
1094 break;
1095 }
1096
1097 rp_cu_st_wait_conn_param_req_available(conn, ctx, evt, param);
1098 break;
1099 default:
1100 /* Ignore other evts */
1101 break;
1102 }
1103 }
1104
rp_cu_state_wait_ntf_conn_param_req(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1105 static void rp_cu_state_wait_ntf_conn_param_req(struct ll_conn *conn, struct proc_ctx *ctx,
1106 uint8_t evt, void *param)
1107 {
1108 switch (evt) {
1109 case RP_CU_EVT_RUN:
1110 rp_cu_send_conn_param_req_ntf(conn, ctx, evt, param);
1111 break;
1112 default:
1113 /* Ignore other evts */
1114 break;
1115 }
1116 }
1117
rp_cu_state_wait_conn_param_req_reply(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1118 static void rp_cu_state_wait_conn_param_req_reply(struct ll_conn *conn, struct proc_ctx *ctx,
1119 uint8_t evt, void *param)
1120 {
1121 switch (evt) {
1122 case RP_CU_EVT_CONN_PARAM_REQ_REPLY:
1123 /* Continue procedure in next prepare run */
1124 ctx->state = RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY_CONTINUE;
1125 break;
1126 case RP_CU_EVT_CONN_PARAM_REQ_NEG_REPLY:
1127 /* Send reject in next prepare run */
1128 ctx->data.cu.rejected_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ;
1129 ctx->state = RP_CU_STATE_WAIT_TX_REJECT_EXT_IND;
1130 break;
1131 default:
1132 /* Ignore other evts */
1133 break;
1134 }
1135 }
1136
rp_cu_state_wait_conn_param_req_reply_continue(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1137 static void rp_cu_state_wait_conn_param_req_reply_continue(struct ll_conn *conn,
1138 struct proc_ctx *ctx, uint8_t evt,
1139 void *param)
1140 {
1141 switch (evt) {
1142 case RP_CU_EVT_RUN:
1143 if (conn->lll.role == BT_HCI_ROLE_CENTRAL) {
1144 /* Ensure that node_ref does not indicate RX node for piggyback */
1145 ctx->node_ref.rx = NULL;
1146 rp_cu_send_conn_update_ind(conn, ctx, evt, param);
1147 } else if (conn->lll.role == BT_HCI_ROLE_PERIPHERAL) {
1148 if (!ctx->data.cu.error) {
1149 rp_cu_send_conn_param_rsp(conn, ctx, evt, param);
1150 } else {
1151 ctx->data.cu.rejected_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ;
1152 rp_cu_send_reject_ext_ind(conn, ctx, evt, param);
1153
1154 }
1155 } else {
1156 /* Unknown role */
1157 LL_ASSERT(0);
1158 }
1159 break;
1160 default:
1161 /* Ignore other evts */
1162 break;
1163 }
1164 }
1165
rp_cu_state_wait_tx_reject_ext_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1166 static void rp_cu_state_wait_tx_reject_ext_ind(struct ll_conn *conn, struct proc_ctx *ctx,
1167 uint8_t evt, void *param)
1168 {
1169 switch (evt) {
1170 case RP_CU_EVT_RUN:
1171 rp_cu_send_reject_ext_ind(conn, ctx, evt, param);
1172 break;
1173 default:
1174 /* Ignore other evts */
1175 break;
1176 }
1177 }
1178
rp_cu_st_wait_tx_conn_param_rsp(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1179 static void rp_cu_st_wait_tx_conn_param_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
1180 void *param)
1181 {
1182 switch (evt) {
1183 case RP_CU_EVT_RUN:
1184 rp_cu_send_conn_param_rsp(conn, ctx, evt, param);
1185 break;
1186 default:
1187 /* Ignore other evts */
1188 break;
1189 }
1190 }
1191
1192 #if defined(CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE)
rp_cu_st_wait_user_response(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1193 static void rp_cu_st_wait_user_response(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
1194 void *param)
1195 {
1196 switch (evt) {
1197 case RP_CU_EVT_CONN_PARAM_REQ_USER_REPLY:
1198 /* Continue procedure in next prepare run */
1199 ctx->state = RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY_CONTINUE;
1200 break;
1201 default:
1202 /* Ignore other evts */
1203 break;
1204 }
1205 }
1206 #endif /* CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE */
1207 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
1208
rp_cu_st_wait_tx_conn_update_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1209 static void rp_cu_st_wait_tx_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx,
1210 uint8_t evt, void *param)
1211 {
1212 switch (evt) {
1213 case RP_CU_EVT_RUN:
1214 rp_cu_send_conn_update_ind(conn, ctx, evt, param);
1215 break;
1216 default:
1217 /* Ignore other evts */
1218 break;
1219 }
1220 }
1221
rp_cu_check_instant(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1222 static void rp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
1223 void *param)
1224 {
1225 uint16_t event_counter = ull_conn_event_counter(conn);
1226
1227 if (is_instant_reached_or_passed(ctx->data.cu.instant, event_counter)) {
1228 bool notify;
1229
1230 /* Procedure is complete when the instant has passed, and the
1231 * new connection event parameters have been applied.
1232 */
1233 cu_update_conn_parameters(conn, ctx);
1234
1235 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
1236 if (ctx->proc == PROC_CONN_PARAM_REQ) {
1237 /* Stop procedure response timeout timer */
1238 llcp_rr_prt_stop(conn);
1239 }
1240 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
1241
1242 notify = cu_should_notify_host(ctx);
1243 if (notify) {
1244 ctx->data.cu.error = BT_HCI_ERR_SUCCESS;
1245 cu_ntf(conn, ctx);
1246 } else {
1247 /* Release RX node kept for NTF */
1248 llcp_rx_node_release(ctx);
1249 ctx->node_ref.rx = NULL;
1250 }
1251 rp_cu_complete(conn, ctx);
1252 }
1253 }
1254
rp_cu_st_wait_rx_conn_update_ind(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1255 static void rp_cu_st_wait_rx_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx,
1256 uint8_t evt, void *param)
1257 {
1258 switch (evt) {
1259 case RP_CU_EVT_CONN_UPDATE_IND:
1260 switch (conn->lll.role) {
1261 case BT_HCI_ROLE_CENTRAL:
1262 ctx->unknown_response.type = PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND;
1263 rp_cu_send_unknown_rsp(conn, ctx, evt, param);
1264 break;
1265 case BT_HCI_ROLE_PERIPHERAL:
1266 llcp_pdu_decode_conn_update_ind(ctx, param);
1267
1268 /* Valid PDU */
1269 if (cu_check_conn_ind_parameters(conn, ctx)) {
1270 if (is_instant_not_passed(ctx->data.cu.instant,
1271 ull_conn_event_counter(conn))) {
1272 /* Keep RX node to use for NTF */
1273 llcp_rx_node_retain(ctx);
1274
1275 ctx->state = RP_CU_STATE_WAIT_INSTANT;
1276
1277 /* In case we only just received it in time */
1278 rp_cu_check_instant(conn, ctx, evt, param);
1279 break;
1280 }
1281
1282 conn->llcp_terminate.reason_final = BT_HCI_ERR_INSTANT_PASSED;
1283 } else {
1284 conn->llcp_terminate.reason_final = BT_HCI_ERR_INVALID_LL_PARAM;
1285 }
1286
1287 llcp_rr_complete(conn);
1288 ctx->state = RP_CU_STATE_IDLE;
1289 break;
1290 default:
1291 /* Unknown role */
1292 LL_ASSERT(0);
1293 }
1294 default:
1295 /* Ignore other evts */
1296 break;
1297 }
1298 }
1299
rp_cu_st_wait_instant(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1300 static void rp_cu_st_wait_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
1301 void *param)
1302 {
1303 switch (evt) {
1304 case RP_CU_EVT_RUN:
1305 rp_cu_check_instant(conn, ctx, evt, param);
1306 break;
1307 default:
1308 /* Ignore other evts */
1309 break;
1310 }
1311 }
1312
rp_cu_execute_fsm(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t evt,void * param)1313 static void rp_cu_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
1314 {
1315 switch (ctx->state) {
1316 case RP_CU_STATE_IDLE:
1317 rp_cu_st_idle(conn, ctx, evt, param);
1318 break;
1319 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
1320 case RP_CU_STATE_WAIT_RX_CONN_PARAM_REQ:
1321 rp_cu_st_wait_rx_conn_param_req(conn, ctx, evt, param);
1322 break;
1323 case RP_CU_STATE_WAIT_CONN_PARAM_REQ_AVAILABLE:
1324 rp_cu_st_wait_conn_param_req_available(conn, ctx, evt, param);
1325 break;
1326 case RP_CU_STATE_WAIT_NTF_CONN_PARAM_REQ:
1327 rp_cu_state_wait_ntf_conn_param_req(conn, ctx, evt, param);
1328 break;
1329 case RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY:
1330 rp_cu_state_wait_conn_param_req_reply(conn, ctx, evt, param);
1331 break;
1332 case RP_CU_STATE_WAIT_CONN_PARAM_REQ_REPLY_CONTINUE:
1333 rp_cu_state_wait_conn_param_req_reply_continue(conn, ctx, evt, param);
1334 break;
1335 case RP_CU_STATE_WAIT_TX_REJECT_EXT_IND:
1336 rp_cu_state_wait_tx_reject_ext_ind(conn, ctx, evt, param);
1337 break;
1338 case RP_CU_STATE_WAIT_TX_CONN_PARAM_RSP:
1339 rp_cu_st_wait_tx_conn_param_rsp(conn, ctx, evt, param);
1340 break;
1341 #if defined(CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE)
1342 case RP_CU_STATE_WAIT_USER_REPLY:
1343 rp_cu_st_wait_user_response(conn, ctx, evt, param);
1344 break;
1345 #endif /* CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE */
1346 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
1347 case RP_CU_STATE_WAIT_TX_CONN_UPDATE_IND:
1348 rp_cu_st_wait_tx_conn_update_ind(conn, ctx, evt, param);
1349 break;
1350 case RP_CU_STATE_WAIT_RX_CONN_UPDATE_IND:
1351 rp_cu_st_wait_rx_conn_update_ind(conn, ctx, evt, param);
1352 break;
1353 case RP_CU_STATE_WAIT_INSTANT:
1354 rp_cu_st_wait_instant(conn, ctx, evt, param);
1355 break;
1356 case RP_CU_STATE_WAIT_NTF_AVAIL:
1357 rp_cu_st_wait_ntf_avail(conn, ctx, evt, param);
1358 break;
1359 default:
1360 /* Unknown state */
1361 LL_ASSERT(0);
1362 break;
1363 }
1364 }
1365
llcp_rp_cu_rx(struct ll_conn * conn,struct proc_ctx * ctx,struct node_rx_pdu * rx)1366 void llcp_rp_cu_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx)
1367 {
1368 struct pdu_data *pdu = (struct pdu_data *)rx->pdu;
1369
1370 switch (pdu->llctrl.opcode) {
1371 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
1372 case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ:
1373 rp_cu_execute_fsm(conn, ctx, RP_CU_EVT_CONN_PARAM_REQ, pdu);
1374 break;
1375 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
1376 case PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND:
1377 rp_cu_execute_fsm(conn, ctx, RP_CU_EVT_CONN_UPDATE_IND, pdu);
1378 break;
1379 default:
1380 /* Invalid behaviour */
1381 /* Invalid PDU received so terminate connection */
1382 conn->llcp_terminate.reason_final = BT_HCI_ERR_LMP_PDU_NOT_ALLOWED;
1383 rp_cu_complete(conn, ctx);
1384 break;
1385 }
1386 }
1387
llcp_rp_cu_run(struct ll_conn * conn,struct proc_ctx * ctx,void * param)1388 void llcp_rp_cu_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param)
1389 {
1390 rp_cu_execute_fsm(conn, ctx, RP_CU_EVT_RUN, param);
1391 }
1392
llcp_rp_cu_awaiting_instant(struct proc_ctx * ctx)1393 bool llcp_rp_cu_awaiting_instant(struct proc_ctx *ctx)
1394 {
1395 return (ctx->state == RP_CU_STATE_WAIT_INSTANT);
1396 }
1397
llcp_lp_cu_awaiting_instant(struct proc_ctx * ctx)1398 bool llcp_lp_cu_awaiting_instant(struct proc_ctx *ctx)
1399 {
1400 return (ctx->state == LP_CU_STATE_WAIT_INSTANT);
1401 }
1402
1403 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
llcp_rp_conn_param_req_reply(struct ll_conn * conn,struct proc_ctx * ctx)1404 void llcp_rp_conn_param_req_reply(struct ll_conn *conn, struct proc_ctx *ctx)
1405 {
1406 rp_cu_execute_fsm(conn, ctx, RP_CU_EVT_CONN_PARAM_REQ_REPLY, NULL);
1407 }
1408
llcp_rp_conn_param_req_neg_reply(struct ll_conn * conn,struct proc_ctx * ctx)1409 void llcp_rp_conn_param_req_neg_reply(struct ll_conn *conn, struct proc_ctx *ctx)
1410 {
1411 rp_cu_execute_fsm(conn, ctx, RP_CU_EVT_CONN_PARAM_REQ_NEG_REPLY, NULL);
1412 }
1413
1414 #if defined(CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE)
llcp_rp_conn_param_req_apm_awaiting_reply(struct proc_ctx * ctx)1415 bool llcp_rp_conn_param_req_apm_awaiting_reply(struct proc_ctx *ctx)
1416 {
1417 return (ctx->state == RP_CU_STATE_WAIT_USER_REPLY);
1418 }
1419
llcp_rp_conn_param_req_apm_reply(struct ll_conn * conn,struct proc_ctx * ctx)1420 void llcp_rp_conn_param_req_apm_reply(struct ll_conn *conn, struct proc_ctx *ctx)
1421 {
1422 rp_cu_execute_fsm(conn, ctx, RP_CU_EVT_CONN_PARAM_REQ_USER_REPLY, NULL);
1423 }
1424 #endif /* CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE */
1425 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
1426