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