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