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