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_settings.h"
28 #include "ll_feat.h"
29
30 #include "lll.h"
31 #include "lll/lll_df_types.h"
32 #include "lll_conn.h"
33 #include "lll_conn_iso.h"
34
35 #include "ull_tx_queue.h"
36
37 #include "isoal.h"
38 #include "ull_internal.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_types.h"
44 #include "ull_conn_internal.h"
45 #include "ull_llcp.h"
46 #include "ull_llcp_features.h"
47 #include "ull_llcp_internal.h"
48
49 #include <soc.h>
50 #include "hal/debug.h"
51
52 static struct proc_ctx *rr_dequeue(struct ll_conn *conn);
53
54 /* LLCP Remote Request FSM State */
55 enum rr_state {
56 RR_STATE_IDLE,
57 RR_STATE_REJECT,
58 RR_STATE_UNSUPPORTED,
59 RR_STATE_ACTIVE,
60 RR_STATE_DISCONNECT,
61 RR_STATE_TERMINATE,
62 };
63
64 /* LLCP Remote Request FSM Event */
65 enum {
66 /* Procedure prepare */
67 RR_EVT_PREPARE,
68
69 /* Procedure run */
70 RR_EVT_RUN,
71
72 /* Procedure completed */
73 RR_EVT_COMPLETE,
74
75 /* Link connected */
76 RR_EVT_CONNECT,
77
78 /* Link disconnected */
79 RR_EVT_DISCONNECT,
80 };
81
proc_with_instant(struct proc_ctx * ctx)82 static bool proc_with_instant(struct proc_ctx *ctx)
83 {
84 switch (ctx->proc) {
85 case PROC_UNKNOWN:
86 case PROC_FEATURE_EXCHANGE:
87 case PROC_MIN_USED_CHANS:
88 case PROC_LE_PING:
89 case PROC_VERSION_EXCHANGE:
90 case PROC_ENCRYPTION_START:
91 case PROC_ENCRYPTION_PAUSE:
92 case PROC_TERMINATE:
93 case PROC_DATA_LENGTH_UPDATE:
94 case PROC_CTE_REQ:
95 case PROC_CIS_TERMINATE:
96 case PROC_CIS_CREATE:
97 case PROC_SCA_UPDATE:
98 return 0U;
99 case PROC_PHY_UPDATE:
100 case PROC_CONN_UPDATE:
101 case PROC_CONN_PARAM_REQ:
102 case PROC_CHAN_MAP_UPDATE:
103 return 1U;
104 default:
105 /* Unknown procedure */
106 LL_ASSERT(0);
107 break;
108 }
109
110 return 0U;
111 }
112
llcp_rr_check_done(struct ll_conn * conn,struct proc_ctx * ctx)113 void llcp_rr_check_done(struct ll_conn *conn, struct proc_ctx *ctx)
114 {
115 if (ctx->done) {
116 struct proc_ctx *ctx_header;
117
118 ctx_header = llcp_rr_peek(conn);
119 LL_ASSERT(ctx_header == ctx);
120
121 /* If we have a node rx it must not be marked RETAIN as
122 * the memory referenced would leak
123 */
124 LL_ASSERT(ctx->node_ref.rx == NULL ||
125 ctx->node_ref.rx->hdr.type != NODE_RX_TYPE_RETAIN);
126
127 rr_dequeue(conn);
128
129 llcp_proc_ctx_release(ctx);
130 }
131 }
132 /*
133 * LLCP Remote Request FSM
134 */
135
rr_set_state(struct ll_conn * conn,enum rr_state state)136 static void rr_set_state(struct ll_conn *conn, enum rr_state state)
137 {
138 conn->llcp.remote.state = state;
139 }
140
llcp_rr_set_incompat(struct ll_conn * conn,enum proc_incompat incompat)141 void llcp_rr_set_incompat(struct ll_conn *conn, enum proc_incompat incompat)
142 {
143 conn->llcp.remote.incompat = incompat;
144 }
145
llcp_rr_set_paused_cmd(struct ll_conn * conn,enum llcp_proc proc)146 void llcp_rr_set_paused_cmd(struct ll_conn *conn, enum llcp_proc proc)
147 {
148 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP) || defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
149 conn->llcp.remote.paused_cmd = proc;
150 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP || CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
151 }
152
llcp_rr_get_paused_cmd(struct ll_conn * conn)153 enum llcp_proc llcp_rr_get_paused_cmd(struct ll_conn *conn)
154 {
155 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP) || defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
156 return conn->llcp.remote.paused_cmd;
157 #else
158 return PROC_NONE;
159 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP || CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
160 }
161
rr_get_incompat(struct ll_conn * conn)162 static enum proc_incompat rr_get_incompat(struct ll_conn *conn)
163 {
164 return conn->llcp.remote.incompat;
165 }
166
rr_set_collision(struct ll_conn * conn,bool collision)167 static void rr_set_collision(struct ll_conn *conn, bool collision)
168 {
169 conn->llcp.remote.collision = collision;
170 }
171
llcp_rr_get_collision(struct ll_conn * conn)172 bool llcp_rr_get_collision(struct ll_conn *conn)
173 {
174 return conn->llcp.remote.collision;
175 }
176
rr_enqueue(struct ll_conn * conn,struct proc_ctx * ctx)177 static void rr_enqueue(struct ll_conn *conn, struct proc_ctx *ctx)
178 {
179 sys_slist_append(&conn->llcp.remote.pend_proc_list, &ctx->node);
180 }
181
rr_dequeue(struct ll_conn * conn)182 static struct proc_ctx *rr_dequeue(struct ll_conn *conn)
183 {
184 struct proc_ctx *ctx;
185
186 ctx = (struct proc_ctx *)sys_slist_get(&conn->llcp.remote.pend_proc_list);
187 return ctx;
188 }
189
llcp_rr_peek(struct ll_conn * conn)190 struct proc_ctx *llcp_rr_peek(struct ll_conn *conn)
191 {
192 struct proc_ctx *ctx;
193
194 ctx = (struct proc_ctx *)sys_slist_peek_head(&conn->llcp.remote.pend_proc_list);
195 return ctx;
196 }
197
llcp_rr_ispaused(struct ll_conn * conn)198 bool llcp_rr_ispaused(struct ll_conn *conn)
199 {
200 return (conn->llcp.remote.pause == 1U);
201 }
202
llcp_rr_pause(struct ll_conn * conn)203 void llcp_rr_pause(struct ll_conn *conn)
204 {
205 conn->llcp.remote.pause = 1U;
206 }
207
llcp_rr_resume(struct ll_conn * conn)208 void llcp_rr_resume(struct ll_conn *conn)
209 {
210 conn->llcp.remote.pause = 0U;
211 }
212
llcp_rr_prt_restart(struct ll_conn * conn)213 void llcp_rr_prt_restart(struct ll_conn *conn)
214 {
215 conn->llcp.remote.prt_expire = conn->llcp.prt_reload;
216 }
217
llcp_rr_prt_stop(struct ll_conn * conn)218 void llcp_rr_prt_stop(struct ll_conn *conn)
219 {
220 conn->llcp.remote.prt_expire = 0U;
221 }
222
llcp_rr_flush_procedures(struct ll_conn * conn)223 void llcp_rr_flush_procedures(struct ll_conn *conn)
224 {
225 struct proc_ctx *ctx;
226
227 /* Flush all pending procedures */
228 ctx = rr_dequeue(conn);
229 while (ctx) {
230 llcp_nodes_release(conn, ctx);
231 llcp_proc_ctx_release(ctx);
232 ctx = rr_dequeue(conn);
233 }
234 }
235
llcp_rr_rx(struct ll_conn * conn,struct proc_ctx * ctx,memq_link_t * link,struct node_rx_pdu * rx)236 void llcp_rr_rx(struct ll_conn *conn, struct proc_ctx *ctx, memq_link_t *link,
237 struct node_rx_pdu *rx)
238 {
239 /* Store RX node and link */
240 ctx->node_ref.rx = rx;
241 ctx->node_ref.link = link;
242
243 switch (ctx->proc) {
244 case PROC_UNKNOWN:
245 /* Do nothing */
246 break;
247 #if defined(CONFIG_BT_CTLR_LE_PING)
248 case PROC_LE_PING:
249 llcp_rp_comm_rx(conn, ctx, rx);
250 break;
251 #endif /* CONFIG_BT_CTLR_LE_PING */
252 case PROC_FEATURE_EXCHANGE:
253 llcp_rp_comm_rx(conn, ctx, rx);
254 break;
255 #if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
256 case PROC_MIN_USED_CHANS:
257 llcp_rp_comm_rx(conn, ctx, rx);
258 break;
259 #endif /* CONFIG_BT_CTLR_MIN_USED_CHAN */
260 case PROC_VERSION_EXCHANGE:
261 llcp_rp_comm_rx(conn, ctx, rx);
262 break;
263 #if defined(CONFIG_BT_CTLR_LE_ENC) && defined(CONFIG_BT_PERIPHERAL)
264 case PROC_ENCRYPTION_START:
265 case PROC_ENCRYPTION_PAUSE:
266 llcp_rp_enc_rx(conn, ctx, rx);
267 break;
268 #endif /* CONFIG_BT_CTLR_LE_ENC && CONFIG_BT_PERIPHERAL */
269 #ifdef CONFIG_BT_CTLR_PHY
270 case PROC_PHY_UPDATE:
271 llcp_rp_pu_rx(conn, ctx, rx);
272 break;
273 #endif /* CONFIG_BT_CTLR_PHY */
274 case PROC_CONN_UPDATE:
275 case PROC_CONN_PARAM_REQ:
276 llcp_rp_cu_rx(conn, ctx, rx);
277 break;
278 case PROC_TERMINATE:
279 llcp_rp_comm_rx(conn, ctx, rx);
280 break;
281 #if defined(CONFIG_BT_PERIPHERAL)
282 case PROC_CHAN_MAP_UPDATE:
283 llcp_rp_chmu_rx(conn, ctx, rx);
284 break;
285 #endif /* CONFIG_BT_PERIPHERAL */
286 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
287 case PROC_DATA_LENGTH_UPDATE:
288 llcp_rp_comm_rx(conn, ctx, rx);
289 break;
290 #endif /* CONFIG_BT_CTLR_DATA_LENGTH */
291 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
292 case PROC_CTE_REQ:
293 llcp_rp_comm_rx(conn, ctx, rx);
294 break;
295 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
296 #if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
297 case PROC_CIS_CREATE:
298 llcp_rp_cc_rx(conn, ctx, rx);
299 break;
300 #endif /* CONFIG_BT_PERIPHERAL && CONFIG_BT_CTLR_PERIPHERAL_ISO */
301 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
302 case PROC_CIS_TERMINATE:
303 llcp_rp_comm_rx(conn, ctx, rx);
304 break;
305 #endif /* CONFIG_BT_CTLR_CENTRAL_ISO || CONFIG_BT_CTLR_PERIPHERAL_ISO */
306 #if defined(CONFIG_BT_CTLR_SCA_UPDATE)
307 case PROC_SCA_UPDATE:
308 llcp_rp_comm_rx(conn, ctx, rx);
309 break;
310 #endif /* CONFIG_BT_CTLR_SCA_UPDATE */
311 default:
312 /* Unknown procedure */
313 LL_ASSERT(0);
314 break;
315 }
316
317 /* If rx node was not retained clear reference */
318 if (ctx->node_ref.rx && ctx->node_ref.rx->hdr.type != NODE_RX_TYPE_RETAIN) {
319 ctx->node_ref.rx = NULL;
320 }
321
322 llcp_rr_check_done(conn, ctx);
323 }
324
llcp_rr_tx_ack(struct ll_conn * conn,struct proc_ctx * ctx,struct node_tx * tx)325 void llcp_rr_tx_ack(struct ll_conn *conn, struct proc_ctx *ctx, struct node_tx *tx)
326 {
327 switch (ctx->proc) {
328 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
329 case PROC_DATA_LENGTH_UPDATE:
330 llcp_rp_comm_tx_ack(conn, ctx, tx);
331 break;
332 #endif /* CONFIG_BT_CTLR_DATA_LENGTH */
333 #ifdef CONFIG_BT_CTLR_PHY
334 case PROC_PHY_UPDATE:
335 llcp_rp_pu_tx_ack(conn, ctx, tx);
336 break;
337 #endif /* CONFIG_BT_CTLR_PHY */
338 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
339 case PROC_CTE_REQ:
340 llcp_rp_comm_tx_ack(conn, ctx, tx);
341 break;
342 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
343 #if defined(CONFIG_BT_CTLR_SCA_UPDATE)
344 case PROC_SCA_UPDATE:
345 llcp_rp_comm_tx_ack(conn, ctx, tx);
346 break;
347 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
348 default:
349 /* Ignore tx_ack */
350 break;
351 }
352
353 /* Clear TX node reference */
354 ctx->node_ref.tx_ack = NULL;
355
356 llcp_rr_check_done(conn, ctx);
357 }
358
llcp_rr_tx_ntf(struct ll_conn * conn,struct proc_ctx * ctx)359 void llcp_rr_tx_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
360 {
361 switch (ctx->proc) {
362 #ifdef CONFIG_BT_CTLR_PHY
363 case PROC_PHY_UPDATE:
364 llcp_rp_pu_tx_ntf(conn, ctx);
365 break;
366 #endif /* CONFIG_BT_CTLR_PHY */
367 default:
368 /* Ignore other procedures */
369 break;
370 }
371
372 llcp_rr_check_done(conn, ctx);
373 }
374
rr_act_run(struct ll_conn * conn)375 static void rr_act_run(struct ll_conn *conn)
376 {
377 struct proc_ctx *ctx;
378
379 ctx = llcp_rr_peek(conn);
380
381 switch (ctx->proc) {
382 #if defined(CONFIG_BT_CTLR_LE_PING)
383 case PROC_LE_PING:
384 llcp_rp_comm_run(conn, ctx, NULL);
385 break;
386 #endif /* CONFIG_BT_CTLR_LE_PING */
387 case PROC_FEATURE_EXCHANGE:
388 llcp_rp_comm_run(conn, ctx, NULL);
389 break;
390 #if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
391 case PROC_MIN_USED_CHANS:
392 llcp_rp_comm_run(conn, ctx, NULL);
393 break;
394 #endif /* CONFIG_BT_CTLR_MIN_USED_CHAN */
395 case PROC_VERSION_EXCHANGE:
396 llcp_rp_comm_run(conn, ctx, NULL);
397 break;
398 #if defined(CONFIG_BT_CTLR_LE_ENC) && defined(CONFIG_BT_PERIPHERAL)
399 case PROC_ENCRYPTION_START:
400 case PROC_ENCRYPTION_PAUSE:
401 llcp_rp_enc_run(conn, ctx, NULL);
402 break;
403 #endif /* CONFIG_BT_CTLR_LE_ENC && CONFIG_BT_PERIPHERAL */
404 #ifdef CONFIG_BT_CTLR_PHY
405 case PROC_PHY_UPDATE:
406 llcp_rp_pu_run(conn, ctx, NULL);
407 break;
408 #endif /* CONFIG_BT_CTLR_PHY */
409 case PROC_CONN_UPDATE:
410 case PROC_CONN_PARAM_REQ:
411 llcp_rp_cu_run(conn, ctx, NULL);
412 break;
413 case PROC_TERMINATE:
414 llcp_rp_comm_run(conn, ctx, NULL);
415 break;
416 #if defined(CONFIG_BT_PERIPHERAL)
417 case PROC_CHAN_MAP_UPDATE:
418 llcp_rp_chmu_run(conn, ctx, NULL);
419 break;
420 #endif /* CONFIG_BT_PERIPHERAL */
421 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
422 case PROC_DATA_LENGTH_UPDATE:
423 llcp_rp_comm_run(conn, ctx, NULL);
424 break;
425 #endif /* CONFIG_BT_CTLR_DATA_LENGTH */
426 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
427 case PROC_CTE_REQ:
428 llcp_rp_comm_run(conn, ctx, NULL);
429 break;
430 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
431 #if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
432 case PROC_CIS_CREATE:
433 llcp_rp_cc_run(conn, ctx, NULL);
434 break;
435 #endif /* CONFIG_BT_PERIPHERAL && CONFIG_BT_CTLR_PERIPHERAL_ISO */
436 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
437 case PROC_CIS_TERMINATE:
438 llcp_rp_comm_run(conn, ctx, NULL);
439 break;
440 #endif /* CONFIG_BT_CTLR_CENTRAL_ISO || CONFIG_BT_CTLR_PERIPHERAL_ISO */
441 #if defined(CONFIG_BT_CTLR_SCA_UPDATE)
442 case PROC_SCA_UPDATE:
443 llcp_rp_comm_run(conn, ctx, NULL);
444 break;
445 #endif /* CONFIG_BT_CTLR_SCA_UPDATE */
446 default:
447 /* Unknown procedure */
448 LL_ASSERT(0);
449 break;
450 }
451
452 llcp_rr_check_done(conn, ctx);
453 }
454
rr_tx(struct ll_conn * conn,struct proc_ctx * ctx,uint8_t opcode)455 static void rr_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t opcode)
456 {
457 struct node_tx *tx;
458 struct pdu_data *pdu;
459 struct proc_ctx *ctx_local;
460 uint8_t reject_code;
461
462 /* Allocate tx node */
463 tx = llcp_tx_alloc(conn, ctx);
464 LL_ASSERT(tx);
465
466 pdu = (struct pdu_data *)tx->pdu;
467
468 /* Encode LL Control PDU */
469 switch (opcode) {
470 case PDU_DATA_LLCTRL_TYPE_REJECT_IND:
471 ctx_local = llcp_lr_peek(conn);
472 if (ctx_local->proc == ctx->proc ||
473 (ctx_local->proc == PROC_CONN_UPDATE &&
474 ctx->proc == PROC_CONN_PARAM_REQ)) {
475 reject_code = BT_HCI_ERR_LL_PROC_COLLISION;
476 } else {
477 reject_code = BT_HCI_ERR_DIFF_TRANS_COLLISION;
478 }
479
480 if (conn->llcp.fex.valid && feature_ext_rej_ind(conn)) {
481 llcp_pdu_encode_reject_ext_ind(pdu, conn->llcp.remote.reject_opcode,
482 reject_code);
483 } else {
484 llcp_pdu_encode_reject_ind(pdu, reject_code);
485 }
486 break;
487 case PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP:
488 llcp_pdu_encode_unknown_rsp(ctx, pdu);
489 break;
490 default:
491 LL_ASSERT(0);
492 }
493
494 ctx->tx_opcode = pdu->llctrl.opcode;
495
496 /* Enqueue LL Control PDU towards LLL */
497 llcp_tx_enqueue(conn, tx);
498 }
499
rr_act_reject(struct ll_conn * conn)500 static void rr_act_reject(struct ll_conn *conn)
501 {
502 struct proc_ctx *ctx = llcp_rr_peek(conn);
503
504 LL_ASSERT(ctx != NULL);
505
506 if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
507 rr_set_state(conn, RR_STATE_REJECT);
508 } else {
509 rr_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_REJECT_IND);
510
511 ctx->done = 1U;
512 rr_set_state(conn, RR_STATE_IDLE);
513 }
514 }
515
rr_act_unsupported(struct ll_conn * conn)516 static void rr_act_unsupported(struct ll_conn *conn)
517 {
518 struct proc_ctx *ctx = llcp_rr_peek(conn);
519
520 LL_ASSERT(ctx != NULL);
521
522 if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
523 rr_set_state(conn, RR_STATE_UNSUPPORTED);
524 } else {
525 rr_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP);
526
527 ctx->done = 1U;
528 rr_set_state(conn, RR_STATE_IDLE);
529 }
530 }
531
rr_act_complete(struct ll_conn * conn)532 static void rr_act_complete(struct ll_conn *conn)
533 {
534 struct proc_ctx *ctx;
535
536 rr_set_collision(conn, 0U);
537
538 ctx = llcp_rr_peek(conn);
539 LL_ASSERT(ctx != NULL);
540
541 /* Stop procedure response timeout timer */
542 llcp_rr_prt_stop(conn);
543
544 /* Mark the procedure as safe to delete */
545 ctx->done = 1U;
546 }
547
rr_act_connect(struct ll_conn * conn)548 static void rr_act_connect(struct ll_conn *conn)
549 {
550 /* Empty on purpose */
551 }
552
rr_act_disconnect(struct ll_conn * conn)553 static void rr_act_disconnect(struct ll_conn *conn)
554 {
555 /*
556 * we may have been disconnected in the
557 * middle of a control procedure, in which
558 * case we need to release all contexts
559 */
560 llcp_rr_flush_procedures(conn);
561 }
562
rr_st_disconnect(struct ll_conn * conn,uint8_t evt,void * param)563 static void rr_st_disconnect(struct ll_conn *conn, uint8_t evt, void *param)
564 {
565 switch (evt) {
566 case RR_EVT_CONNECT:
567 rr_act_connect(conn);
568 rr_set_state(conn, RR_STATE_IDLE);
569 break;
570 default:
571 /* Ignore other evts */
572 break;
573 }
574 }
575
rr_st_idle(struct ll_conn * conn,uint8_t evt,void * param)576 static void rr_st_idle(struct ll_conn *conn, uint8_t evt, void *param)
577 {
578 struct proc_ctx *ctx;
579 struct proc_ctx *ctx_local;
580
581 switch (evt) {
582 case RR_EVT_PREPARE:
583 ctx = llcp_rr_peek(conn);
584 if (ctx) {
585 const enum proc_incompat incompat = rr_get_incompat(conn);
586 const bool periph = !!(conn->lll.role == BT_HCI_ROLE_PERIPHERAL);
587 const bool central = !!(conn->lll.role == BT_HCI_ROLE_CENTRAL);
588 const bool with_instant = proc_with_instant(ctx);
589
590 if (ctx->proc == PROC_TERMINATE) {
591 /* Peer terminate overrides all */
592
593 /* Run remote procedure */
594 rr_act_run(conn);
595 rr_set_state(conn, RR_STATE_TERMINATE);
596 } else if (ctx->proc == PROC_UNKNOWN) {
597 /* Unsupported procedure */
598
599 /* Send LL_UNKNOWN_RSP */
600 struct node_rx_pdu *rx = (struct node_rx_pdu *)param;
601 struct pdu_data *pdu = (struct pdu_data *)rx->pdu;
602
603 ctx->unknown_response.type = pdu->llctrl.opcode;
604 rr_act_unsupported(conn);
605 } else if (!with_instant || incompat == INCOMPAT_NO_COLLISION) {
606 /* No collision
607 * => Run procedure
608 *
609 * Local incompatible procedure request is kept pending.
610 */
611
612 /*
613 * Pause local incompatible procedure
614 * in case we run a procedure with instant
615 */
616 rr_set_collision(conn, with_instant);
617
618 /* Run remote procedure */
619 rr_act_run(conn);
620 rr_set_state(conn, RR_STATE_ACTIVE);
621 } else if (periph && incompat == INCOMPAT_RESOLVABLE) {
622 /* Peripheral collision
623 * => Run procedure
624 *
625 * Local periph procedure completes with error.
626 */
627 /* Local procedure */
628 ctx_local = llcp_lr_peek(conn);
629 if (ctx_local) {
630 /* Make sure local procedure stops expecting PDUs except
631 * implicit UNKNOWN_RSP and REJECTs
632 */
633 ctx_local->rx_opcode = PDU_DATA_LLCTRL_TYPE_UNUSED;
634 }
635
636 /*
637 * Block/'hold back' future incompatible local procedures
638 * in case we run a procedure with instant
639 */
640 rr_set_collision(conn, with_instant);
641
642 /* Run remote procedure */
643 rr_act_run(conn);
644 rr_set_state(conn, RR_STATE_ACTIVE);
645 } else if (central && incompat == INCOMPAT_RESOLVABLE) {
646 /* Central collision
647 * => Send reject
648 *
649 * Local central incompatible procedure continues unaffected.
650 */
651
652 /* Send reject */
653 struct node_rx_pdu *rx = (struct node_rx_pdu *)param;
654 struct pdu_data *pdu = (struct pdu_data *)rx->pdu;
655
656 conn->llcp.remote.reject_opcode = pdu->llctrl.opcode;
657 rr_act_reject(conn);
658 } else if (incompat == INCOMPAT_RESERVED) {
659 /* Protocol violation.
660 * => Disconnect
661 * See Bluetooth Core Specification Version 5.3 Vol 6, Part B
662 * section 5.3 (page 2879) for error codes
663 */
664
665 ctx_local = llcp_lr_peek(conn);
666
667 if (ctx_local->proc == ctx->proc ||
668 (ctx_local->proc == PROC_CONN_UPDATE &&
669 ctx->proc == PROC_CONN_PARAM_REQ)) {
670 conn->llcp_terminate.reason_final =
671 BT_HCI_ERR_LL_PROC_COLLISION;
672 } else {
673 conn->llcp_terminate.reason_final =
674 BT_HCI_ERR_DIFF_TRANS_COLLISION;
675 }
676 }
677 }
678 break;
679 case RR_EVT_DISCONNECT:
680 rr_act_disconnect(conn);
681 rr_set_state(conn, RR_STATE_DISCONNECT);
682 break;
683 default:
684 /* Ignore other evts */
685 break;
686 }
687 }
688
rr_st_reject(struct ll_conn * conn,uint8_t evt,void * param)689 static void rr_st_reject(struct ll_conn *conn, uint8_t evt, void *param)
690 {
691 rr_act_reject(conn);
692 }
693
rr_st_unsupported(struct ll_conn * conn,uint8_t evt,void * param)694 static void rr_st_unsupported(struct ll_conn *conn, uint8_t evt, void *param)
695 {
696 rr_act_unsupported(conn);
697 }
698
rr_st_active(struct ll_conn * conn,uint8_t evt,void * param)699 static void rr_st_active(struct ll_conn *conn, uint8_t evt, void *param)
700 {
701 switch (evt) {
702 case RR_EVT_RUN:
703 if (llcp_rr_peek(conn)) {
704 rr_act_run(conn);
705 }
706 break;
707 case RR_EVT_COMPLETE:
708 rr_act_complete(conn);
709 rr_set_state(conn, RR_STATE_IDLE);
710 break;
711 case RR_EVT_DISCONNECT:
712 rr_act_disconnect(conn);
713 rr_set_state(conn, RR_STATE_DISCONNECT);
714 break;
715 default:
716 /* Ignore other evts */
717 break;
718 }
719 }
720
rr_st_terminate(struct ll_conn * conn,uint8_t evt,void * param)721 static void rr_st_terminate(struct ll_conn *conn, uint8_t evt, void *param)
722 {
723 switch (evt) {
724 case RR_EVT_RUN:
725 if (llcp_rr_peek(conn)) {
726 rr_act_run(conn);
727 }
728 break;
729 case RR_EVT_COMPLETE:
730 rr_act_complete(conn);
731 rr_set_state(conn, RR_STATE_IDLE);
732 break;
733 case RR_EVT_DISCONNECT:
734 rr_act_disconnect(conn);
735 rr_set_state(conn, RR_STATE_DISCONNECT);
736 break;
737 default:
738 /* Ignore other evts */
739 break;
740 }
741 }
742
rr_execute_fsm(struct ll_conn * conn,uint8_t evt,void * param)743 static void rr_execute_fsm(struct ll_conn *conn, uint8_t evt, void *param)
744 {
745 switch (conn->llcp.remote.state) {
746 case RR_STATE_DISCONNECT:
747 rr_st_disconnect(conn, evt, param);
748 break;
749 case RR_STATE_IDLE:
750 rr_st_idle(conn, evt, param);
751 break;
752 case RR_STATE_REJECT:
753 rr_st_reject(conn, evt, param);
754 break;
755 case RR_STATE_UNSUPPORTED:
756 rr_st_unsupported(conn, evt, param);
757 break;
758 case RR_STATE_ACTIVE:
759 rr_st_active(conn, evt, param);
760 break;
761 case RR_STATE_TERMINATE:
762 rr_st_terminate(conn, evt, param);
763 break;
764 default:
765 /* Unknown state */
766 LL_ASSERT(0);
767 }
768 }
769
llcp_rr_init(struct ll_conn * conn)770 void llcp_rr_init(struct ll_conn *conn)
771 {
772 rr_set_state(conn, RR_STATE_DISCONNECT);
773 conn->llcp.remote.prt_expire = 0U;
774 }
775
llcp_rr_prepare(struct ll_conn * conn,struct node_rx_pdu * rx)776 void llcp_rr_prepare(struct ll_conn *conn, struct node_rx_pdu *rx)
777 {
778 rr_execute_fsm(conn, RR_EVT_PREPARE, rx);
779 }
780
llcp_rr_run(struct ll_conn * conn)781 void llcp_rr_run(struct ll_conn *conn)
782 {
783 rr_execute_fsm(conn, RR_EVT_RUN, NULL);
784 }
785
llcp_rr_complete(struct ll_conn * conn)786 void llcp_rr_complete(struct ll_conn *conn)
787 {
788 rr_execute_fsm(conn, RR_EVT_COMPLETE, NULL);
789 }
790
llcp_rr_connect(struct ll_conn * conn)791 void llcp_rr_connect(struct ll_conn *conn)
792 {
793 rr_execute_fsm(conn, RR_EVT_CONNECT, NULL);
794 }
795
llcp_rr_disconnect(struct ll_conn * conn)796 void llcp_rr_disconnect(struct ll_conn *conn)
797 {
798 rr_execute_fsm(conn, RR_EVT_DISCONNECT, NULL);
799 }
800
801 /*
802 * Create procedure lookup table for any given PDU opcode, these are the opcodes
803 * that can initiate a new remote procedure.
804 *
805 * NOTE: All array elements that are not initialized explicitly are
806 * zero-initialized, which matches PROC_UNKNOWN.
807 *
808 * NOTE: When initializing an array of unknown size, the largest subscript for
809 * which an initializer is specified determines the size of the array being
810 * declared.
811 */
812 BUILD_ASSERT(0 == PROC_UNKNOWN, "PROC_UNKNOWN must have the value ZERO");
813
814 enum accept_role {
815 /* No role accepts this opcode */
816 ACCEPT_ROLE_NONE = 0,
817 /* Central role accepts this opcode */
818 ACCEPT_ROLE_CENTRAL = (1 << BT_HCI_ROLE_CENTRAL),
819 /* Peripheral role accepts this opcode */
820 ACCEPT_ROLE_PERIPHERAL = (1 << BT_HCI_ROLE_PERIPHERAL),
821 /* Both roles accepts this opcode */
822 ACCEPT_ROLE_BOTH = (ACCEPT_ROLE_CENTRAL | ACCEPT_ROLE_PERIPHERAL),
823 };
824
825 struct proc_role {
826 enum llcp_proc proc;
827 enum accept_role accept;
828 };
829
830 static const struct proc_role new_proc_lut[] = {
831 #if defined(CONFIG_BT_PERIPHERAL)
832 [PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND] = { PROC_CONN_UPDATE, ACCEPT_ROLE_PERIPHERAL },
833 [PDU_DATA_LLCTRL_TYPE_CHAN_MAP_IND] = { PROC_CHAN_MAP_UPDATE, ACCEPT_ROLE_PERIPHERAL },
834 #endif /* CONFIG_BT_PERIPHERAL */
835 [PDU_DATA_LLCTRL_TYPE_TERMINATE_IND] = { PROC_TERMINATE, ACCEPT_ROLE_BOTH },
836 #if defined(CONFIG_BT_CTLR_LE_ENC) && defined(CONFIG_BT_PERIPHERAL)
837 [PDU_DATA_LLCTRL_TYPE_ENC_REQ] = { PROC_ENCRYPTION_START, ACCEPT_ROLE_PERIPHERAL },
838 #endif /* CONFIG_BT_CTLR_LE_ENC && CONFIG_BT_PERIPHERAL */
839 [PDU_DATA_LLCTRL_TYPE_ENC_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
840 [PDU_DATA_LLCTRL_TYPE_START_ENC_REQ] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
841 [PDU_DATA_LLCTRL_TYPE_START_ENC_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
842 [PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
843 [PDU_DATA_LLCTRL_TYPE_FEATURE_REQ] = { PROC_FEATURE_EXCHANGE, ACCEPT_ROLE_PERIPHERAL },
844 [PDU_DATA_LLCTRL_TYPE_FEATURE_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
845 #if defined(CONFIG_BT_CTLR_LE_ENC) && defined(CONFIG_BT_PERIPHERAL)
846 [PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_REQ] = { PROC_ENCRYPTION_PAUSE, ACCEPT_ROLE_PERIPHERAL },
847 #endif /* CONFIG_BT_CTLR_LE_ENC && CONFIG_BT_PERIPHERAL */
848 [PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
849 [PDU_DATA_LLCTRL_TYPE_VERSION_IND] = { PROC_VERSION_EXCHANGE, ACCEPT_ROLE_BOTH },
850 [PDU_DATA_LLCTRL_TYPE_REJECT_IND] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
851 #if defined(CONFIG_BT_CTLR_PER_INIT_FEAT_XCHG) && defined(CONFIG_BT_CENTRAL)
852 [PDU_DATA_LLCTRL_TYPE_PER_INIT_FEAT_XCHG] = { PROC_FEATURE_EXCHANGE, ACCEPT_ROLE_CENTRAL },
853 #endif /* CONFIG_BT_CTLR_PER_INIT_FEAT_XCHG && CONFIG_BT_CENTRAL */
854 #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
855 [PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ] = { PROC_CONN_PARAM_REQ, ACCEPT_ROLE_BOTH },
856 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
857 [PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
858 [PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
859 #if defined(CONFIG_BT_CTLR_LE_PING)
860 [PDU_DATA_LLCTRL_TYPE_PING_REQ] = { PROC_LE_PING, ACCEPT_ROLE_BOTH },
861 #endif /* CONFIG_BT_CTLR_LE_PING */
862 [PDU_DATA_LLCTRL_TYPE_PING_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
863 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
864 [PDU_DATA_LLCTRL_TYPE_LENGTH_REQ] = { PROC_DATA_LENGTH_UPDATE, ACCEPT_ROLE_BOTH },
865 #endif /* CONFIG_BT_CTLR_DATA_LENGTH */
866 [PDU_DATA_LLCTRL_TYPE_LENGTH_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
867 #if defined(CONFIG_BT_CTLR_PHY)
868 [PDU_DATA_LLCTRL_TYPE_PHY_REQ] = { PROC_PHY_UPDATE, ACCEPT_ROLE_BOTH },
869 #endif /* CONFIG_BT_CTLR_PHY */
870 [PDU_DATA_LLCTRL_TYPE_PHY_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
871 [PDU_DATA_LLCTRL_TYPE_PHY_UPD_IND] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
872 #if defined(CONFIG_BT_CTLR_MIN_USED_CHAN) && defined(CONFIG_BT_CENTRAL)
873 [PDU_DATA_LLCTRL_TYPE_MIN_USED_CHAN_IND] = { PROC_MIN_USED_CHANS, ACCEPT_ROLE_CENTRAL },
874 #endif /* CONFIG_BT_CTLR_MIN_USED_CHAN && CONFIG_BT_CENTRAL */
875 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
876 [PDU_DATA_LLCTRL_TYPE_CTE_REQ] = { PROC_CTE_REQ, ACCEPT_ROLE_BOTH },
877 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
878 [PDU_DATA_LLCTRL_TYPE_CTE_RSP] = { PROC_UNKNOWN, ACCEPT_ROLE_NONE },
879 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
880 #if !defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
881 [PDU_DATA_LLCTRL_TYPE_CIS_TERMINATE_IND] = { PROC_CIS_TERMINATE, ACCEPT_ROLE_CENTRAL },
882 #else
883 #if !defined(CONFIG_BT_CTLR_CENTRAL_ISO)
884 [PDU_DATA_LLCTRL_TYPE_CIS_TERMINATE_IND] = { PROC_CIS_TERMINATE, ACCEPT_ROLE_PERIPHERAL },
885 #else
886 [PDU_DATA_LLCTRL_TYPE_CIS_TERMINATE_IND] = { PROC_CIS_TERMINATE, ACCEPT_ROLE_BOTH },
887 #endif /* !defined(CONFIG_BT_CTLR_CENTRAL_ISO) */
888 #endif /* !defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
889 #endif /* defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
890 #if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
891 [PDU_DATA_LLCTRL_TYPE_CIS_REQ] = { PROC_CIS_CREATE, ACCEPT_ROLE_PERIPHERAL },
892 #endif /* defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
893 #if defined(CONFIG_BT_CTLR_SCA_UPDATE)
894 [PDU_DATA_LLCTRL_TYPE_CLOCK_ACCURACY_REQ] = { PROC_SCA_UPDATE, ACCEPT_ROLE_BOTH },
895 #endif /* CONFIG_BT_CTLR_SCA_UPDATE */
896 };
897
llcp_rr_new(struct ll_conn * conn,memq_link_t * link,struct node_rx_pdu * rx,bool valid_pdu)898 void llcp_rr_new(struct ll_conn *conn, memq_link_t *link, struct node_rx_pdu *rx, bool valid_pdu)
899 {
900 struct proc_ctx *ctx;
901 struct pdu_data *pdu;
902 uint8_t proc = PROC_UNKNOWN;
903
904 pdu = (struct pdu_data *)rx->pdu;
905
906 /* Is this a valid opcode */
907 if (valid_pdu && pdu->llctrl.opcode < ARRAY_SIZE(new_proc_lut)) {
908 /* Lookup procedure */
909 uint8_t role_mask = (1 << conn->lll.role);
910 struct proc_role pr = new_proc_lut[pdu->llctrl.opcode];
911
912 if (pr.accept & role_mask) {
913 proc = pr.proc;
914 }
915 }
916
917 if (proc == PROC_TERMINATE) {
918 llcp_rr_terminate(conn);
919 llcp_lr_terminate(conn);
920 }
921
922 ctx = llcp_create_remote_procedure(proc);
923 if (!ctx) {
924 return;
925 }
926
927 /* Enqueue procedure */
928 rr_enqueue(conn, ctx);
929
930 /* Prepare procedure */
931 llcp_rr_prepare(conn, rx);
932
933 llcp_rr_check_done(conn, ctx);
934
935 /* Handle PDU */
936 ctx = llcp_rr_peek(conn);
937 if (ctx) {
938 llcp_rr_rx(conn, ctx, link, rx);
939 }
940 }
941
llcp_rr_terminate(struct ll_conn * conn)942 void llcp_rr_terminate(struct ll_conn *conn)
943 {
944 llcp_rr_flush_procedures(conn);
945 llcp_rr_prt_stop(conn);
946 rr_set_collision(conn, 0U);
947 rr_set_state(conn, RR_STATE_IDLE);
948 }
949
950 #ifdef ZTEST_UNITTEST
951
llcp_rr_is_disconnected(struct ll_conn * conn)952 bool llcp_rr_is_disconnected(struct ll_conn *conn)
953 {
954 return conn->llcp.remote.state == RR_STATE_DISCONNECT;
955 }
956
llcp_rr_is_idle(struct ll_conn * conn)957 bool llcp_rr_is_idle(struct ll_conn *conn)
958 {
959 return conn->llcp.remote.state == RR_STATE_IDLE;
960 }
961
llcp_rr_dequeue(struct ll_conn * conn)962 struct proc_ctx *llcp_rr_dequeue(struct ll_conn *conn)
963 {
964 return rr_dequeue(conn);
965 }
966
llcp_rr_enqueue(struct ll_conn * conn,struct proc_ctx * ctx)967 void llcp_rr_enqueue(struct ll_conn *conn, struct proc_ctx *ctx)
968 {
969 rr_enqueue(conn, ctx);
970 }
971
972 #endif
973