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/mayfly.h"
21 #include "util/dbuf.h"
22 
23 #include "pdu_df.h"
24 #include "lll/pdu_vendor.h"
25 #include "pdu.h"
26 
27 #include "ll.h"
28 #include "ll_settings.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_llcp.h"
45 #include "ull_llcp_internal.h"
46 #include "ull_conn_internal.h"
47 
48 #include <soc.h>
49 #include "hal/debug.h"
50 
51 static struct proc_ctx *lr_dequeue(struct ll_conn *conn);
52 
53 /* LLCP Local Request FSM State */
54 enum lr_state {
55 	LR_STATE_IDLE,
56 	LR_STATE_ACTIVE,
57 	LR_STATE_DISCONNECT,
58 	LR_STATE_TERMINATE,
59 };
60 
61 /* LLCP Local Request FSM Event */
62 enum {
63 	/* Procedure run */
64 	LR_EVT_RUN,
65 
66 	/* Procedure completed */
67 	LR_EVT_COMPLETE,
68 
69 	/* Link connected */
70 	LR_EVT_CONNECT,
71 
72 	/* Link disconnected */
73 	LR_EVT_DISCONNECT,
74 };
75 
llcp_lr_check_done(struct ll_conn * conn,struct proc_ctx * ctx)76 void llcp_lr_check_done(struct ll_conn *conn, struct proc_ctx *ctx)
77 {
78 	if (ctx->done) {
79 		struct proc_ctx *ctx_header;
80 
81 		ctx_header = llcp_lr_peek(conn);
82 		LL_ASSERT(ctx_header == ctx);
83 
84 		lr_dequeue(conn);
85 
86 		llcp_proc_ctx_release(ctx);
87 	}
88 }
89 
90 /*
91  * LLCP Local Request Shared Data Locking
92  */
93 
shared_data_access_lock(void)94 static ALWAYS_INLINE uint32_t shared_data_access_lock(void)
95 {
96 	bool enabled;
97 
98 	if (mayfly_is_running()) {
99 		/* We are in Mayfly context, nothing to be done */
100 		return false;
101 	}
102 
103 	/* We are in thread context and have to disable TICKER_USER_ID_ULL_HIGH */
104 	enabled = mayfly_is_enabled(TICKER_USER_ID_THREAD, TICKER_USER_ID_ULL_HIGH) != 0U;
105 	mayfly_enable(TICKER_USER_ID_THREAD, TICKER_USER_ID_ULL_HIGH, 0U);
106 
107 	return enabled;
108 }
109 
shared_data_access_unlock(bool key)110 static ALWAYS_INLINE void shared_data_access_unlock(bool key)
111 {
112 	if (key) {
113 		/* We are in thread context and have to reenable TICKER_USER_ID_ULL_HIGH */
114 		mayfly_enable(TICKER_USER_ID_THREAD, TICKER_USER_ID_ULL_HIGH, 1U);
115 	}
116 }
117 
118 /*
119  * LLCP Local Request FSM
120  */
121 
lr_set_state(struct ll_conn * conn,enum lr_state state)122 static void lr_set_state(struct ll_conn *conn, enum lr_state state)
123 {
124 	conn->llcp.local.state = state;
125 }
126 
llcp_lr_enqueue(struct ll_conn * conn,struct proc_ctx * ctx)127 void llcp_lr_enqueue(struct ll_conn *conn, struct proc_ctx *ctx)
128 {
129 	/* This function is called from both Thread and Mayfly (ISR),
130 	 * make sure only a single context have access at a time.
131 	 */
132 
133 	bool key = shared_data_access_lock();
134 
135 	sys_slist_append(&conn->llcp.local.pend_proc_list, &ctx->node);
136 
137 	shared_data_access_unlock(key);
138 }
139 
lr_dequeue(struct ll_conn * conn)140 static struct proc_ctx *lr_dequeue(struct ll_conn *conn)
141 {
142 	/* This function is called from both Thread and Mayfly (ISR),
143 	 * make sure only a single context have access at a time.
144 	 */
145 
146 	struct proc_ctx *ctx;
147 
148 	bool key = shared_data_access_lock();
149 
150 	ctx = (struct proc_ctx *)sys_slist_get(&conn->llcp.local.pend_proc_list);
151 
152 	shared_data_access_unlock(key);
153 
154 	return ctx;
155 }
156 
llcp_lr_peek(struct ll_conn * conn)157 struct proc_ctx *llcp_lr_peek(struct ll_conn *conn)
158 {
159 	/* This function is called from both Thread and Mayfly (ISR),
160 	 * make sure only a single context have access at a time.
161 	 */
162 	struct proc_ctx *ctx;
163 
164 	bool key = shared_data_access_lock();
165 
166 	ctx = (struct proc_ctx *)sys_slist_peek_head(&conn->llcp.local.pend_proc_list);
167 
168 	shared_data_access_unlock(key);
169 
170 	return ctx;
171 }
172 
llcp_lr_peek_proc(struct ll_conn * conn,uint8_t proc)173 struct proc_ctx *llcp_lr_peek_proc(struct ll_conn *conn, uint8_t proc)
174 {
175 	/* This function is called from both Thread and Mayfly (ISR),
176 	 * make sure only a single context have access at a time.
177 	 */
178 
179 	struct proc_ctx *ctx, *tmp;
180 
181 	bool key = shared_data_access_lock();
182 
183 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&conn->llcp.local.pend_proc_list, ctx, tmp, node) {
184 		if (ctx->proc == proc) {
185 			break;
186 		}
187 	}
188 
189 	shared_data_access_unlock(key);
190 
191 	return ctx;
192 }
193 
llcp_lr_ispaused(struct ll_conn * conn)194 bool llcp_lr_ispaused(struct ll_conn *conn)
195 {
196 	return conn->llcp.local.pause == 1U;
197 }
198 
llcp_lr_pause(struct ll_conn * conn)199 void llcp_lr_pause(struct ll_conn *conn)
200 {
201 	conn->llcp.local.pause = 1U;
202 }
203 
llcp_lr_resume(struct ll_conn * conn)204 void llcp_lr_resume(struct ll_conn *conn)
205 {
206 	conn->llcp.local.pause = 0U;
207 }
208 
llcp_lr_prt_restart(struct ll_conn * conn)209 void llcp_lr_prt_restart(struct ll_conn *conn)
210 {
211 	conn->llcp.local.prt_expire = conn->llcp.prt_reload;
212 }
213 
llcp_lr_prt_restart_with_value(struct ll_conn * conn,uint16_t value)214 void llcp_lr_prt_restart_with_value(struct ll_conn *conn, uint16_t value)
215 {
216 	conn->llcp.local.prt_expire = value;
217 }
218 
llcp_lr_prt_stop(struct ll_conn * conn)219 void llcp_lr_prt_stop(struct ll_conn *conn)
220 {
221 	conn->llcp.local.prt_expire = 0U;
222 }
223 
llcp_lr_flush_procedures(struct ll_conn * conn)224 void llcp_lr_flush_procedures(struct ll_conn *conn)
225 {
226 	struct proc_ctx *ctx;
227 
228 	/* Flush all pending procedures */
229 	ctx = lr_dequeue(conn);
230 	while (ctx) {
231 		llcp_nodes_release(conn, ctx);
232 		llcp_proc_ctx_release(ctx);
233 		ctx = lr_dequeue(conn);
234 	}
235 }
236 
llcp_lr_rx(struct ll_conn * conn,struct proc_ctx * ctx,memq_link_t * link,struct node_rx_pdu * rx)237 void llcp_lr_rx(struct ll_conn *conn, struct proc_ctx *ctx, memq_link_t *link,
238 		struct node_rx_pdu *rx)
239 {
240 	/* Store RX node and link */
241 	ctx->node_ref.rx = rx;
242 	ctx->node_ref.link = link;
243 
244 	switch (ctx->proc) {
245 #if defined(CONFIG_BT_CTLR_LE_PING)
246 	case PROC_LE_PING:
247 		llcp_lp_comm_rx(conn, ctx, rx);
248 		break;
249 #endif /* CONFIG_BT_CTLR_LE_PING */
250 	case PROC_FEATURE_EXCHANGE:
251 		llcp_lp_comm_rx(conn, ctx, rx);
252 		break;
253 #if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
254 	case PROC_MIN_USED_CHANS:
255 		llcp_lp_comm_rx(conn, ctx, rx);
256 		break;
257 #endif /* CONFIG_BT_CTLR_MIN_USED_CHAN */
258 	case PROC_VERSION_EXCHANGE:
259 		llcp_lp_comm_rx(conn, ctx, rx);
260 		break;
261 #if defined(CONFIG_BT_CTLR_LE_ENC) && defined(CONFIG_BT_CENTRAL)
262 	case PROC_ENCRYPTION_START:
263 	case PROC_ENCRYPTION_PAUSE:
264 		llcp_lp_enc_rx(conn, ctx, rx);
265 		break;
266 #endif /* CONFIG_BT_CTLR_LE_ENC && CONFIG_BT_CENTRAL */
267 #ifdef CONFIG_BT_CTLR_PHY
268 	case PROC_PHY_UPDATE:
269 		llcp_lp_pu_rx(conn, ctx, rx);
270 		break;
271 #endif /* CONFIG_BT_CTLR_PHY */
272 	case PROC_CONN_UPDATE:
273 	case PROC_CONN_PARAM_REQ:
274 		llcp_lp_cu_rx(conn, ctx, rx);
275 		break;
276 	case PROC_TERMINATE:
277 		llcp_lp_comm_rx(conn, ctx, rx);
278 		break;
279 #if defined(CONFIG_BT_CENTRAL)
280 	case PROC_CHAN_MAP_UPDATE:
281 		llcp_lp_chmu_rx(conn, ctx, rx);
282 		break;
283 #endif /* CONFIG_BT_CENTRAL */
284 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
285 	case PROC_DATA_LENGTH_UPDATE:
286 		llcp_lp_comm_rx(conn, ctx, rx);
287 		break;
288 #endif /* CONFIG_BT_CTLR_DATA_LENGTH */
289 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
290 	case PROC_CTE_REQ:
291 		llcp_lp_comm_rx(conn, ctx, rx);
292 		break;
293 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
294 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
295 	case PROC_CIS_TERMINATE:
296 		llcp_lp_comm_rx(conn, ctx, rx);
297 		break;
298 #endif /* defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
299 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO)
300 	case PROC_CIS_CREATE:
301 		llcp_lp_cc_rx(conn, ctx, rx);
302 		break;
303 #endif /* defined(CONFIG_BT_CTLR_CENTRAL_ISO) */
304 #if defined(CONFIG_BT_CTLR_SCA_UPDATE)
305 	case PROC_SCA_UPDATE:
306 		llcp_lp_comm_rx(conn, ctx, rx);
307 		break;
308 #endif /* CONFIG_BT_CTLR_SCA_UPDATE */
309 	default:
310 		/* Unknown procedure */
311 		LL_ASSERT(0);
312 		break;
313 	}
314 
315 	llcp_lr_check_done(conn, ctx);
316 }
317 
llcp_lr_tx_ack(struct ll_conn * conn,struct proc_ctx * ctx,struct node_tx * tx)318 void llcp_lr_tx_ack(struct ll_conn *conn, struct proc_ctx *ctx, struct node_tx *tx)
319 {
320 	switch (ctx->proc) {
321 #if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
322 	case PROC_MIN_USED_CHANS:
323 		llcp_lp_comm_tx_ack(conn, ctx, tx);
324 		break;
325 #endif /* CONFIG_BT_CTLR_MIN_USED_CHAN */
326 	case PROC_TERMINATE:
327 		llcp_lp_comm_tx_ack(conn, ctx, tx);
328 		break;
329 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
330 	case PROC_DATA_LENGTH_UPDATE:
331 		llcp_lp_comm_tx_ack(conn, ctx, tx);
332 		break;
333 #endif /* CONFIG_BT_CTLR_DATA_LENGTH */
334 #ifdef CONFIG_BT_CTLR_PHY
335 	case PROC_PHY_UPDATE:
336 		llcp_lp_pu_tx_ack(conn, ctx, tx);
337 		break;
338 #endif /* CONFIG_BT_CTLR_PHY */
339 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
340 	case PROC_CIS_TERMINATE:
341 		llcp_lp_comm_tx_ack(conn, ctx, tx);
342 		break;
343 #endif /* defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
344 	default:
345 		break;
346 		/* Ignore tx_ack */
347 	}
348 
349 	/* Clear TX node reference */
350 	ctx->node_ref.tx_ack = NULL;
351 
352 	llcp_lr_check_done(conn, ctx);
353 }
354 
llcp_lr_tx_ntf(struct ll_conn * conn,struct proc_ctx * ctx)355 void llcp_lr_tx_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
356 {
357 	switch (ctx->proc) {
358 #if defined(CONFIG_BT_CTLR_PHY)
359 	case PROC_PHY_UPDATE:
360 		llcp_lp_pu_tx_ntf(conn, ctx);
361 		break;
362 #endif /* CONFIG_BT_CTLR_PHY */
363 	default:
364 		/* Ignore other procedures */
365 		break;
366 	}
367 
368 	llcp_lr_check_done(conn, ctx);
369 }
370 
lr_act_run(struct ll_conn * conn)371 static void lr_act_run(struct ll_conn *conn)
372 {
373 	struct proc_ctx *ctx;
374 
375 	ctx = llcp_lr_peek(conn);
376 
377 	switch (ctx->proc) {
378 #if defined(CONFIG_BT_CTLR_LE_PING)
379 	case PROC_LE_PING:
380 		llcp_lp_comm_run(conn, ctx, NULL);
381 		break;
382 #endif /* CONFIG_BT_CTLR_LE_PING */
383 	case PROC_FEATURE_EXCHANGE:
384 		llcp_lp_comm_run(conn, ctx, NULL);
385 		break;
386 #if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
387 	case PROC_MIN_USED_CHANS:
388 		llcp_lp_comm_run(conn, ctx, NULL);
389 		break;
390 #endif /* CONFIG_BT_CTLR_MIN_USED_CHAN */
391 	case PROC_VERSION_EXCHANGE:
392 		llcp_lp_comm_run(conn, ctx, NULL);
393 		break;
394 #if defined(CONFIG_BT_CTLR_LE_ENC) && defined(CONFIG_BT_CENTRAL)
395 	case PROC_ENCRYPTION_START:
396 	case PROC_ENCRYPTION_PAUSE:
397 		llcp_lp_enc_run(conn, ctx, NULL);
398 		break;
399 #endif /* CONFIG_BT_CTLR_LE_ENC && CONFIG_BT_CENTRAL */
400 #ifdef CONFIG_BT_CTLR_PHY
401 	case PROC_PHY_UPDATE:
402 		llcp_lp_pu_run(conn, ctx, NULL);
403 		break;
404 #endif /* CONFIG_BT_CTLR_PHY */
405 	case PROC_CONN_UPDATE:
406 	case PROC_CONN_PARAM_REQ:
407 		llcp_lp_cu_run(conn, ctx, NULL);
408 		break;
409 	case PROC_TERMINATE:
410 		llcp_lp_comm_run(conn, ctx, NULL);
411 		break;
412 #if defined(CONFIG_BT_CENTRAL)
413 	case PROC_CHAN_MAP_UPDATE:
414 		llcp_lp_chmu_run(conn, ctx, NULL);
415 		break;
416 #endif /* CONFIG_BT_CENTRAL */
417 #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
418 	case PROC_DATA_LENGTH_UPDATE:
419 		llcp_lp_comm_run(conn, ctx, NULL);
420 		break;
421 #endif /* CONFIG_BT_CTLR_DATA_LENGTH */
422 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
423 	case PROC_CTE_REQ:
424 		/* 3rd partam null? */
425 		llcp_lp_comm_run(conn, ctx, NULL);
426 		break;
427 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
428 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO)
429 	case PROC_CIS_CREATE:
430 		llcp_lp_cc_run(conn, ctx, NULL);
431 		break;
432 #endif /* CONFIG_BT_CTLR_CENTRAL_ISO */
433 #if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
434 	case PROC_CIS_TERMINATE:
435 		llcp_lp_comm_run(conn, ctx, NULL);
436 		break;
437 #endif /* defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
438 #if defined(CONFIG_BT_CTLR_SCA_UPDATE)
439 	case PROC_SCA_UPDATE:
440 		llcp_lp_comm_run(conn, ctx, NULL);
441 		break;
442 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
443 	default:
444 		/* Unknown procedure */
445 		LL_ASSERT(0);
446 		break;
447 	}
448 
449 	llcp_lr_check_done(conn, ctx);
450 }
451 
lr_act_complete(struct ll_conn * conn)452 static void lr_act_complete(struct ll_conn *conn)
453 {
454 	struct proc_ctx *ctx;
455 
456 	ctx = llcp_lr_peek(conn);
457 	LL_ASSERT(ctx != NULL);
458 
459 	/* Stop procedure response timeout timer */
460 	llcp_lr_prt_stop(conn);
461 
462 	/* Mark the procedure as safe to delete */
463 	ctx->done = 1U;
464 }
465 
lr_act_connect(struct ll_conn * conn)466 static void lr_act_connect(struct ll_conn *conn)
467 {
468 	/* Empty on purpose */
469 }
470 
lr_act_disconnect(struct ll_conn * conn)471 static void lr_act_disconnect(struct ll_conn *conn)
472 {
473 	llcp_lr_flush_procedures(conn);
474 }
475 
lr_st_disconnect(struct ll_conn * conn,uint8_t evt,void * param)476 static void lr_st_disconnect(struct ll_conn *conn, uint8_t evt, void *param)
477 {
478 	switch (evt) {
479 	case LR_EVT_CONNECT:
480 		lr_act_connect(conn);
481 		lr_set_state(conn, LR_STATE_IDLE);
482 		break;
483 	default:
484 		/* Ignore other evts */
485 		break;
486 	}
487 }
488 
lr_st_idle(struct ll_conn * conn,uint8_t evt,void * param)489 static void lr_st_idle(struct ll_conn *conn, uint8_t evt, void *param)
490 {
491 	struct proc_ctx *ctx;
492 
493 	switch (evt) {
494 	case LR_EVT_RUN:
495 		ctx = llcp_lr_peek(conn);
496 		if (ctx) {
497 			/*
498 			 * since the call to lr_act_run may release the context we need to remember
499 			 * which procedure we are running
500 			 */
501 			const enum llcp_proc curr_proc = ctx->proc;
502 			lr_act_run(conn);
503 			if (curr_proc != PROC_TERMINATE) {
504 				lr_set_state(conn, LR_STATE_ACTIVE);
505 			} else {
506 				lr_set_state(conn, LR_STATE_TERMINATE);
507 			}
508 		}
509 		break;
510 	case LR_EVT_DISCONNECT:
511 		lr_act_disconnect(conn);
512 		lr_set_state(conn, LR_STATE_DISCONNECT);
513 		break;
514 	case LR_EVT_COMPLETE:
515 		/* Some procedures like CTE request may be completed without actual run due to
516 		 * change in conditions while the procedure was waiting in a queue.
517 		 */
518 		lr_act_complete(conn);
519 		break;
520 	default:
521 		/* Ignore other evts */
522 		break;
523 	}
524 }
525 
lr_st_active(struct ll_conn * conn,uint8_t evt,void * param)526 static void lr_st_active(struct ll_conn *conn, uint8_t evt, void *param)
527 {
528 	switch (evt) {
529 	case LR_EVT_RUN:
530 		if (llcp_lr_peek(conn)) {
531 			lr_act_run(conn);
532 		}
533 		break;
534 	case LR_EVT_COMPLETE:
535 		lr_act_complete(conn);
536 		lr_set_state(conn, LR_STATE_IDLE);
537 		break;
538 	case LR_EVT_DISCONNECT:
539 		lr_act_disconnect(conn);
540 		lr_set_state(conn, LR_STATE_DISCONNECT);
541 		break;
542 	default:
543 		/* Ignore other evts */
544 		break;
545 	}
546 }
547 
lr_st_terminate(struct ll_conn * conn,uint8_t evt,void * param)548 static void lr_st_terminate(struct ll_conn *conn, uint8_t evt, void *param)
549 {
550 	switch (evt) {
551 	case LR_EVT_RUN:
552 		if (llcp_lr_peek(conn)) {
553 			lr_act_run(conn);
554 		}
555 		break;
556 	case LR_EVT_COMPLETE:
557 		lr_act_complete(conn);
558 		lr_set_state(conn, LR_STATE_IDLE);
559 		break;
560 	case LR_EVT_DISCONNECT:
561 		lr_act_disconnect(conn);
562 		lr_set_state(conn, LR_STATE_DISCONNECT);
563 		break;
564 	default:
565 		/* Ignore other evts */
566 		break;
567 	}
568 }
569 
lr_execute_fsm(struct ll_conn * conn,uint8_t evt,void * param)570 static void lr_execute_fsm(struct ll_conn *conn, uint8_t evt, void *param)
571 {
572 	switch (conn->llcp.local.state) {
573 	case LR_STATE_DISCONNECT:
574 		lr_st_disconnect(conn, evt, param);
575 		break;
576 	case LR_STATE_IDLE:
577 		lr_st_idle(conn, evt, param);
578 		break;
579 	case LR_STATE_ACTIVE:
580 		lr_st_active(conn, evt, param);
581 		break;
582 	case LR_STATE_TERMINATE:
583 		lr_st_terminate(conn, evt, param);
584 		break;
585 	default:
586 		/* Unknown state */
587 		LL_ASSERT(0);
588 	}
589 }
590 
llcp_lr_init(struct ll_conn * conn)591 void llcp_lr_init(struct ll_conn *conn)
592 {
593 	lr_set_state(conn, LR_STATE_DISCONNECT);
594 	conn->llcp.local.prt_expire = 0U;
595 }
596 
llcp_lr_run(struct ll_conn * conn)597 void llcp_lr_run(struct ll_conn *conn)
598 {
599 	lr_execute_fsm(conn, LR_EVT_RUN, NULL);
600 }
601 
llcp_lr_complete(struct ll_conn * conn)602 void llcp_lr_complete(struct ll_conn *conn)
603 {
604 	lr_execute_fsm(conn, LR_EVT_COMPLETE, NULL);
605 }
606 
llcp_lr_connect(struct ll_conn * conn)607 void llcp_lr_connect(struct ll_conn *conn)
608 {
609 	lr_execute_fsm(conn, LR_EVT_CONNECT, NULL);
610 }
611 
llcp_lr_disconnect(struct ll_conn * conn)612 void llcp_lr_disconnect(struct ll_conn *conn)
613 {
614 	lr_execute_fsm(conn, LR_EVT_DISCONNECT, NULL);
615 }
616 
llcp_lr_terminate(struct ll_conn * conn)617 void llcp_lr_terminate(struct ll_conn *conn)
618 {
619 
620 	llcp_lr_flush_procedures(conn);
621 	llcp_lr_prt_stop(conn);
622 	llcp_rr_set_incompat(conn, 0U);
623 	lr_set_state(conn, LR_STATE_IDLE);
624 }
625 
626 #ifdef ZTEST_UNITTEST
627 
llcp_lr_is_disconnected(struct ll_conn * conn)628 bool llcp_lr_is_disconnected(struct ll_conn *conn)
629 {
630 	return conn->llcp.local.state == LR_STATE_DISCONNECT;
631 }
632 
llcp_lr_is_idle(struct ll_conn * conn)633 bool llcp_lr_is_idle(struct ll_conn *conn)
634 {
635 	return conn->llcp.local.state == LR_STATE_IDLE;
636 }
637 
llcp_lr_dequeue(struct ll_conn * conn)638 struct proc_ctx *llcp_lr_dequeue(struct ll_conn *conn)
639 {
640 	return lr_dequeue(conn);
641 }
642 
643 #endif
644