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