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