1 /*
2  * Copyright (c) 2020 Demant
3  * Copyright (c) 2020 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/types.h>
9 #include <zephyr/ztest.h>
10 #include <stdlib.h>
11 
12 #include <zephyr/bluetooth/hci.h>
13 #include <zephyr/sys/slist.h>
14 #include <zephyr/sys/util.h>
15 
16 #include "hal/ccm.h"
17 
18 #include "util/util.h"
19 #include "util/mem.h"
20 #include "util/memq.h"
21 #include "util/dbuf.h"
22 
23 #include "pdu_df.h"
24 #include "lll/pdu_vendor.h"
25 #include "pdu.h"
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_iso_types.h"
39 #include "ull_conn_iso_types.h"
40 #include "ull_conn_iso_internal.h"
41 #include "ull_conn_types.h"
42 
43 #include "ull_internal.h"
44 #include "ull_conn_internal.h"
45 #include "ull_llcp_internal.h"
46 #include "ull_llcp.h"
47 
48 #include "helper_pdu.h"
49 #include "helper_util.h"
50 
51 static struct ll_conn *emul_conn_pool[CONFIG_BT_MAX_CONN];
52 
53 static uint32_t event_active[CONFIG_BT_MAX_CONN];
54 sys_slist_t ut_rx_q;
55 static sys_slist_t lt_tx_q;
56 static uint32_t no_of_ctx_buffers_at_test_setup;
57 
58 #define PDU_DC_LL_HEADER_SIZE (offsetof(struct pdu_data, lldata))
59 #define NODE_RX_HEADER_SIZE (offsetof(struct node_rx_pdu, pdu))
60 #define NODE_RX_STRUCT_OVERHEAD (NODE_RX_HEADER_SIZE)
61 #define PDU_DATA_SIZE sizeof(struct pdu_data)
62 #define PDU_RX_NODE_SIZE WB_UP(NODE_RX_STRUCT_OVERHEAD + PDU_DATA_SIZE)
63 
64 helper_pdu_encode_func_t *const helper_pdu_encode[] = {
65 	[LL_VERSION_IND] = helper_pdu_encode_version_ind,
66 	[LL_LE_PING_REQ] = helper_pdu_encode_ping_req,
67 	[LL_LE_PING_RSP] = helper_pdu_encode_ping_rsp,
68 	[LL_FEATURE_REQ] = helper_pdu_encode_feature_req,
69 	[LL_PERIPH_FEAT_XCHG] = helper_pdu_encode_peripheral_feature_req,
70 	[LL_FEATURE_RSP] = helper_pdu_encode_feature_rsp,
71 	[LL_MIN_USED_CHANS_IND] = helper_pdu_encode_min_used_chans_ind,
72 	[LL_REJECT_IND] = helper_pdu_encode_reject_ind,
73 	[LL_REJECT_EXT_IND] = helper_pdu_encode_reject_ext_ind,
74 	[LL_ENC_REQ] = helper_pdu_encode_enc_req,
75 	[LL_ENC_RSP] = helper_pdu_encode_enc_rsp,
76 	[LL_START_ENC_REQ] = helper_pdu_encode_start_enc_req,
77 	[LL_START_ENC_RSP] = helper_pdu_encode_start_enc_rsp,
78 	[LL_PAUSE_ENC_REQ] = helper_pdu_encode_pause_enc_req,
79 	[LL_PAUSE_ENC_RSP] = helper_pdu_encode_pause_enc_rsp,
80 	[LL_PHY_REQ] = helper_pdu_encode_phy_req,
81 	[LL_PHY_RSP] = helper_pdu_encode_phy_rsp,
82 	[LL_PHY_UPDATE_IND] = helper_pdu_encode_phy_update_ind,
83 	[LL_UNKNOWN_RSP] = helper_pdu_encode_unknown_rsp,
84 	[LL_CONNECTION_UPDATE_IND] = helper_pdu_encode_conn_update_ind,
85 	[LL_CONNECTION_PARAM_REQ] = helper_pdu_encode_conn_param_req,
86 	[LL_CONNECTION_PARAM_RSP] = helper_pdu_encode_conn_param_rsp,
87 	[LL_TERMINATE_IND] = helper_pdu_encode_terminate_ind,
88 	[LL_CHAN_MAP_UPDATE_IND] = helper_pdu_encode_channel_map_update_ind,
89 	[LL_LENGTH_REQ] = helper_pdu_encode_length_req,
90 	[LL_LENGTH_RSP] = helper_pdu_encode_length_rsp,
91 	[LL_CTE_REQ] = helper_pdu_encode_cte_req,
92 	[LL_CTE_RSP] = helper_pdu_encode_cte_rsp,
93 	[LL_CLOCK_ACCURACY_REQ] = helper_pdu_encode_sca_req,
94 	[LL_CLOCK_ACCURACY_RSP] = helper_pdu_encode_sca_rsp,
95 	[LL_CIS_REQ] = helper_pdu_encode_cis_req,
96 	[LL_CIS_RSP] = helper_pdu_encode_cis_rsp,
97 	[LL_CIS_IND] = helper_pdu_encode_cis_ind,
98 	[LL_CIS_TERMINATE_IND] = helper_pdu_encode_cis_terminate_ind,
99 	[LL_PERIODIC_SYNC_IND] = helper_pdu_encode_periodic_sync_ind,
100 	[LL_ZERO] = helper_pdu_encode_zero,
101 };
102 
103 helper_pdu_verify_func_t *const helper_pdu_verify[] = {
104 	[LL_VERSION_IND] = helper_pdu_verify_version_ind,
105 	[LL_LE_PING_REQ] = helper_pdu_verify_ping_req,
106 	[LL_LE_PING_RSP] = helper_pdu_verify_ping_rsp,
107 	[LL_FEATURE_REQ] = helper_pdu_verify_feature_req,
108 	[LL_PERIPH_FEAT_XCHG] = helper_pdu_verify_peripheral_feature_req,
109 	[LL_FEATURE_RSP] = helper_pdu_verify_feature_rsp,
110 	[LL_MIN_USED_CHANS_IND] = helper_pdu_verify_min_used_chans_ind,
111 	[LL_REJECT_IND] = helper_pdu_verify_reject_ind,
112 	[LL_REJECT_EXT_IND] = helper_pdu_verify_reject_ext_ind,
113 	[LL_ENC_REQ] = helper_pdu_verify_enc_req,
114 	[LL_ENC_RSP] = helper_pdu_verify_enc_rsp,
115 	[LL_START_ENC_REQ] = helper_pdu_verify_start_enc_req,
116 	[LL_START_ENC_RSP] = helper_pdu_verify_start_enc_rsp,
117 	[LL_PAUSE_ENC_REQ] = helper_pdu_verify_pause_enc_req,
118 	[LL_PAUSE_ENC_RSP] = helper_pdu_verify_pause_enc_rsp,
119 	[LL_PHY_REQ] = helper_pdu_verify_phy_req,
120 	[LL_PHY_RSP] = helper_pdu_verify_phy_rsp,
121 	[LL_PHY_UPDATE_IND] = helper_pdu_verify_phy_update_ind,
122 	[LL_UNKNOWN_RSP] = helper_pdu_verify_unknown_rsp,
123 	[LL_CONNECTION_UPDATE_IND] = helper_pdu_verify_conn_update_ind,
124 	[LL_CONNECTION_PARAM_REQ] = helper_pdu_verify_conn_param_req,
125 	[LL_CONNECTION_PARAM_RSP] = helper_pdu_verify_conn_param_rsp,
126 	[LL_TERMINATE_IND] = helper_pdu_verify_terminate_ind,
127 	[LL_CHAN_MAP_UPDATE_IND] = helper_pdu_verify_channel_map_update_ind,
128 	[LL_LENGTH_REQ] = helper_pdu_verify_length_req,
129 	[LL_LENGTH_RSP] = helper_pdu_verify_length_rsp,
130 	[LL_CTE_REQ] = helper_pdu_verify_cte_req,
131 	[LL_CTE_RSP] = helper_pdu_verify_cte_rsp,
132 	[LL_CLOCK_ACCURACY_REQ] = helper_pdu_verify_sca_req,
133 	[LL_CLOCK_ACCURACY_RSP] = helper_pdu_verify_sca_rsp,
134 	[LL_CIS_REQ] = helper_pdu_verify_cis_req,
135 	[LL_CIS_RSP] = helper_pdu_verify_cis_rsp,
136 	[LL_CIS_IND] = helper_pdu_verify_cis_ind,
137 	[LL_CIS_TERMINATE_IND] = helper_pdu_verify_cis_terminate_ind,
138 	[LL_PERIODIC_SYNC_IND] = helper_pdu_verify_periodic_sync_ind,
139 };
140 
141 helper_pdu_ntf_verify_func_t *const helper_pdu_ntf_verify[] = {
142 	[LL_VERSION_IND] = NULL,
143 	[LL_LE_PING_REQ] = NULL,
144 	[LL_LE_PING_RSP] = NULL,
145 	[LL_FEATURE_REQ] = NULL,
146 	[LL_PERIPH_FEAT_XCHG] = NULL,
147 	[LL_FEATURE_RSP] = NULL,
148 	[LL_MIN_USED_CHANS_IND] = NULL,
149 	[LL_REJECT_IND] = NULL,
150 	[LL_REJECT_EXT_IND] = NULL,
151 	[LL_ENC_REQ] = helper_pdu_ntf_verify_enc_req,
152 	[LL_ENC_RSP] = NULL,
153 	[LL_START_ENC_REQ] = NULL,
154 	[LL_START_ENC_RSP] = NULL,
155 	[LL_PHY_REQ] = NULL,
156 	[LL_PHY_RSP] = NULL,
157 	[LL_PHY_UPDATE_IND] = NULL,
158 	[LL_UNKNOWN_RSP] = NULL,
159 	[LL_CONNECTION_UPDATE_IND] = NULL,
160 	[LL_CONNECTION_PARAM_REQ] = NULL,
161 	[LL_CONNECTION_PARAM_RSP] = NULL,
162 	[LL_TERMINATE_IND] = NULL,
163 	[LL_CHAN_MAP_UPDATE_IND] = NULL,
164 	[LL_LENGTH_REQ] = NULL,
165 	[LL_LENGTH_RSP] = NULL,
166 	[LL_CTE_REQ] = NULL,
167 	[LL_CTE_RSP] = helper_pdu_ntf_verify_cte_rsp,
168 	[LL_CTE_RSP] = NULL,
169 	[LL_CLOCK_ACCURACY_REQ] = NULL,
170 	[LL_CLOCK_ACCURACY_RSP] = NULL,
171 	[LL_CIS_REQ] = NULL,
172 	[LL_CIS_RSP] = NULL,
173 	[LL_CIS_IND] = NULL,
174 	[LL_CIS_TERMINATE_IND] = NULL,
175 	[LL_PERIODIC_SYNC_IND] = NULL,
176 };
177 
178 helper_node_encode_func_t *const helper_node_encode[] = {
179 	[LL_VERSION_IND] = NULL,
180 	[LL_LE_PING_REQ] = NULL,
181 	[LL_LE_PING_RSP] = NULL,
182 	[LL_FEATURE_REQ] = NULL,
183 	[LL_PERIPH_FEAT_XCHG] = NULL,
184 	[LL_FEATURE_RSP] = NULL,
185 	[LL_MIN_USED_CHANS_IND] = NULL,
186 	[LL_REJECT_IND] = NULL,
187 	[LL_REJECT_EXT_IND] = NULL,
188 	[LL_ENC_REQ] = NULL,
189 	[LL_ENC_RSP] = NULL,
190 	[LL_START_ENC_REQ] = NULL,
191 	[LL_START_ENC_RSP] = NULL,
192 	[LL_PHY_REQ] = NULL,
193 	[LL_PHY_RSP] = NULL,
194 	[LL_PHY_UPDATE_IND] = NULL,
195 	[LL_UNKNOWN_RSP] = NULL,
196 	[LL_CONNECTION_UPDATE_IND] = NULL,
197 	[LL_CONNECTION_PARAM_REQ] = NULL,
198 	[LL_CONNECTION_PARAM_RSP] = NULL,
199 	[LL_TERMINATE_IND] = NULL,
200 	[LL_CHAN_MAP_UPDATE_IND] = NULL,
201 	[LL_CTE_REQ] = NULL,
202 	[LL_CTE_RSP] = helper_node_encode_cte_rsp,
203 	[LL_CLOCK_ACCURACY_REQ] = NULL,
204 	[LL_CLOCK_ACCURACY_RSP] = NULL,
205 	[LL_CIS_REQ] = NULL,
206 	[LL_CIS_RSP] = NULL,
207 	[LL_CIS_IND] = NULL,
208 	[LL_CIS_TERMINATE_IND] = NULL,
209 	[LL_PERIODIC_SYNC_IND] = NULL,
210 };
211 
212 helper_node_verify_func_t *const helper_node_verify[] = {
213 	[NODE_PHY_UPDATE] = helper_node_verify_phy_update,
214 	[NODE_CONN_UPDATE] = helper_node_verify_conn_update,
215 	[NODE_ENC_REFRESH] = helper_node_verify_enc_refresh,
216 	[NODE_CTE_RSP] = helper_node_verify_cte_rsp,
217 	[NODE_CIS_REQUEST] = helper_node_verify_cis_request,
218 	[NODE_CIS_ESTABLISHED] = helper_node_verify_cis_established,
219 	[NODE_PEER_SCA_UPDATE] = helper_node_verify_peer_sca_update,
220 };
221 
222 /*
223  * for debugging purpose only
224  */
test_print_conn(struct ll_conn * conn)225 void test_print_conn(struct ll_conn *conn)
226 {
227 	printf("------------------>\n");
228 	printf("Mock structure\n");
229 	printf("     Role: %d\n", conn->lll.role);
230 	printf("     event-count: %d\n", conn->lll.event_counter);
231 	printf("LLCP structure\n");
232 	printf("     Local state: %d\n", conn->llcp.local.state);
233 	printf("     Remote state: %d\n", conn->llcp.remote.state);
234 	printf("     Collision: %d\n", conn->llcp.remote.collision);
235 	printf("     Reject: %d\n", conn->llcp.remote.reject_opcode);
236 	printf("--------------------->\n");
237 }
238 
test_ctx_buffers_cnt(void)239 uint16_t test_ctx_buffers_cnt(void)
240 {
241 	return no_of_ctx_buffers_at_test_setup;
242 }
243 
find_idx(struct ll_conn * conn)244 static uint8_t find_idx(struct ll_conn *conn)
245 {
246 	for (uint8_t i = 0; i < CONFIG_BT_MAX_CONN; i++) {
247 		if (emul_conn_pool[i] == conn) {
248 			return i;
249 		}
250 	}
251 	zassert_true(0, "Invalid connection object");
252 	return 0xFF;
253 }
254 
test_setup(struct ll_conn * conn)255 void test_setup(struct ll_conn *conn)
256 {
257 	ull_conn_init();
258 
259 	/**/
260 	memset(conn, 0x00, sizeof(*conn));
261 
262 	/* Initialize the upper test rx queue */
263 	sys_slist_init(&ut_rx_q);
264 
265 	/* Initialize the lower tester tx queue */
266 	sys_slist_init(&lt_tx_q);
267 
268 	/* Initialize the control procedure code */
269 	ull_cp_init();
270 
271 	/* Initialize the ULL TX Q */
272 	ull_tx_q_init(&conn->tx_q);
273 
274 	/* Initialize the connection object */
275 	ull_llcp_init(conn);
276 
277 	ll_reset();
278 	conn->lll.event_counter = 0;
279 	conn->lll.interval = 6;
280 	conn->supervision_timeout = 600;
281 	event_active[0] = 0;
282 
283 	memset(emul_conn_pool, 0x00, sizeof(emul_conn_pool));
284 	emul_conn_pool[0] = conn;
285 
286 	no_of_ctx_buffers_at_test_setup = llcp_ctx_buffers_free();
287 
288 }
289 
test_setup_idx(struct ll_conn * conn,uint8_t idx)290 void test_setup_idx(struct ll_conn *conn, uint8_t idx)
291 {
292 	if (idx == 0) {
293 		test_setup(conn);
294 		return;
295 	}
296 
297 	memset(conn, 0x00, sizeof(*conn));
298 
299 	/* Initialize the ULL TX Q */
300 	ull_tx_q_init(&conn->tx_q);
301 
302 	/* Initialize the connection object */
303 	ull_llcp_init(conn);
304 
305 	conn->lll.event_counter = 0;
306 	event_active[idx] = 0;
307 	emul_conn_pool[idx] = conn;
308 }
309 
test_set_role(struct ll_conn * conn,uint8_t role)310 void test_set_role(struct ll_conn *conn, uint8_t role)
311 {
312 	conn->lll.role = role;
313 }
314 
event_prepare(struct ll_conn * conn)315 void event_prepare(struct ll_conn *conn)
316 {
317 	struct lll_conn *lll = &conn->lll;
318 	uint32_t *evt_active = &(event_active[find_idx(conn)]);
319 
320 	/* Can only be called with no active event */
321 	zassert_equal(*evt_active, 0, "Called inside an active event");
322 	*evt_active = 1;
323 
324 	/*** ULL Prepare ***/
325 
326 	/* Event counter */
327 	conn->event_counter = lll->event_counter + lll->latency_prepare;
328 
329 	/* Handle any LL Control Procedures */
330 	ull_cp_run(conn);
331 
332 	/*** LLL Prepare ***/
333 
334 	/* Save the latency for use in event */
335 	lll->latency_prepare += lll->latency;
336 
337 	/* Calc current event counter value */
338 	uint16_t event_counter = lll->event_counter + lll->latency_prepare;
339 
340 	/* Store the next event counter value */
341 	lll->event_counter = event_counter + 1;
342 
343 	lll->latency_prepare = 0;
344 }
345 
event_tx_ack(struct ll_conn * conn,struct node_tx * tx)346 void event_tx_ack(struct ll_conn *conn, struct node_tx *tx)
347 {
348 	uint32_t *evt_active = &(event_active[find_idx(conn)]);
349 	/* Can only be called with active event */
350 	zassert_equal(*evt_active, 1, "Called outside an active event");
351 
352 	ull_cp_tx_ack(conn, tx);
353 }
354 
event_done(struct ll_conn * conn)355 void event_done(struct ll_conn *conn)
356 {
357 	struct node_rx_pdu *rx;
358 	uint32_t *evt_active = &(event_active[find_idx(conn)]);
359 
360 	/* Can only be called with active event */
361 	zassert_equal(*evt_active, 1, "Called outside an active event");
362 	*evt_active = 0;
363 
364 	/* Notify all control procedures that wait with Host notifications for instant to be on
365 	 * air. This is done here because UT does not maintain actual connection events.
366 	 */
367 	ull_cp_tx_ntf(conn);
368 
369 	while ((rx = (struct node_rx_pdu *)sys_slist_get(&lt_tx_q))) {
370 
371 		/* Mark buffer for release */
372 		rx->hdr.type = NODE_RX_TYPE_RELEASE;
373 
374 		ull_cp_rx(conn, NULL, rx);
375 
376 		if (rx->hdr.type == NODE_RX_TYPE_RELEASE) {
377 			/* Only release if node was not hi-jacked by LLCP */
378 			ll_rx_release(rx);
379 		} else if (rx->hdr.type != NODE_RX_TYPE_RETAIN) {
380 			/* Otherwise put/sched to emulate ull_cp_rx return path */
381 			ll_rx_put_sched(rx->hdr.link, rx);
382 		}
383 	}
384 }
385 
event_counter(struct ll_conn * conn)386 uint16_t event_counter(struct ll_conn *conn)
387 {
388 	uint16_t event_counter;
389 	uint32_t *evt_active = &(event_active[find_idx(conn)]);
390 
391 	/* Calculate current event counter */
392 	event_counter = ull_conn_event_counter(conn);
393 
394 	/* If event_counter is called inside an event_prepare()/event_done() pair
395 	 * return the current event counter value (i.e. -1);
396 	 * otherwise return the next event counter value
397 	 */
398 	if (*evt_active) {
399 		event_counter--;
400 	}
401 
402 	return event_counter;
403 }
404 
405 static struct node_rx_pdu *rx_malloc_store;
406 
lt_tx_real(const char * file,uint32_t line,enum helper_pdu_opcode opcode,struct ll_conn * conn,void * param)407 void lt_tx_real(const char *file, uint32_t line, enum helper_pdu_opcode opcode,
408 		struct ll_conn *conn, void *param)
409 {
410 	struct pdu_data *pdu;
411 	struct node_rx_pdu *rx;
412 
413 	rx = malloc(PDU_RX_NODE_SIZE);
414 	zassert_not_null(rx, "Out of memory.\nCalled at %s:%d\n", file, line);
415 
416 	/* Remember RX node to allow for correct release */
417 	rx_malloc_store = rx;
418 
419 	/* Encode node_rx_pdu if required by particular procedure */
420 	if (helper_node_encode[opcode]) {
421 		helper_node_encode[opcode](rx, param);
422 	}
423 
424 	pdu = (struct pdu_data *)rx->pdu;
425 	zassert_not_null(helper_pdu_encode[opcode], "PDU encode function cannot be NULL\n");
426 	helper_pdu_encode[opcode](pdu, param);
427 
428 	sys_slist_append(&lt_tx_q, (sys_snode_t *)rx);
429 }
430 
lt_tx_real_no_encode(const char * file,uint32_t line,struct pdu_data * pdu,struct ll_conn * conn,void * param)431 void lt_tx_real_no_encode(const char *file, uint32_t line, struct pdu_data *pdu,
432 			  struct ll_conn *conn, void *param)
433 {
434 	struct node_rx_pdu *rx;
435 
436 	rx = malloc(PDU_RX_NODE_SIZE);
437 	zassert_not_null(rx, "Out of memory.\nCalled at %s:%d\n", file, line);
438 
439 	/* Remember RX node to allow for correct release */
440 	rx_malloc_store = rx;
441 
442 	memcpy((struct pdu_data *)rx->pdu, pdu, sizeof(struct pdu_data));
443 	sys_slist_append(&lt_tx_q, (sys_snode_t *)rx);
444 }
445 
release_ntf(struct node_rx_pdu * ntf)446 void release_ntf(struct node_rx_pdu *ntf)
447 {
448 	if (ntf == rx_malloc_store) {
449 		free(ntf);
450 		return;
451 	}
452 
453 	ntf->hdr.next = NULL;
454 	ll_rx_mem_release((void **)&ntf);
455 }
456 
lt_rx_real(const char * file,uint32_t line,enum helper_pdu_opcode opcode,struct ll_conn * conn,struct node_tx ** tx_ref,void * param)457 void lt_rx_real(const char *file, uint32_t line, enum helper_pdu_opcode opcode,
458 		struct ll_conn *conn, struct node_tx **tx_ref, void *param)
459 {
460 	struct node_tx *tx;
461 	struct pdu_data *pdu;
462 
463 	tx = ull_tx_q_dequeue(&conn->tx_q);
464 
465 	zassert_not_null(tx, "Tx Q empty.\nCalled at %s:%d\n", file, line);
466 
467 	pdu = (struct pdu_data *)tx->pdu;
468 	if (helper_pdu_verify[opcode]) {
469 		helper_pdu_verify[opcode](file, line, pdu, param);
470 	}
471 
472 	*tx_ref = tx;
473 }
474 
lt_rx_q_is_empty_real(const char * file,uint32_t line,struct ll_conn * conn)475 void lt_rx_q_is_empty_real(const char *file, uint32_t line, struct ll_conn *conn)
476 {
477 	struct node_tx *tx;
478 
479 	tx = ull_tx_q_dequeue(&conn->tx_q);
480 	zassert_is_null(tx, "Tx Q not empty.\nCalled at %s:%d\n", file, line);
481 }
482 
ut_rx_pdu_real(const char * file,uint32_t line,enum helper_pdu_opcode opcode,struct node_rx_pdu ** ntf_ref,void * param)483 void ut_rx_pdu_real(const char *file, uint32_t line, enum helper_pdu_opcode opcode,
484 		    struct node_rx_pdu **ntf_ref, void *param)
485 {
486 	struct pdu_data *pdu;
487 	struct node_rx_pdu *ntf;
488 
489 	ntf = (struct node_rx_pdu *)sys_slist_get(&ut_rx_q);
490 	zassert_not_null(ntf, "Ntf Q empty.\nCalled at %s:%d\n", file, line);
491 
492 	zassert_equal(ntf->hdr.type, NODE_RX_TYPE_DC_PDU,
493 		      "Ntf node is of the wrong type.\nCalled at %s:%d\n", file, line);
494 
495 	pdu = (struct pdu_data *)ntf->pdu;
496 	if (helper_pdu_ntf_verify[opcode]) {
497 		helper_pdu_ntf_verify[opcode](file, line, pdu, param);
498 	} else if (helper_pdu_verify[opcode]) {
499 		helper_pdu_verify[opcode](file, line, pdu, param);
500 	}
501 
502 	*ntf_ref = ntf;
503 }
504 
ut_rx_node_real(const char * file,uint32_t line,enum helper_node_opcode opcode,struct node_rx_pdu ** ntf_ref,void * param)505 void ut_rx_node_real(const char *file, uint32_t line, enum helper_node_opcode opcode,
506 		     struct node_rx_pdu **ntf_ref, void *param)
507 {
508 	struct node_rx_pdu *ntf;
509 
510 	ntf = (struct node_rx_pdu *)sys_slist_get(&ut_rx_q);
511 	zassert_not_null(ntf, "Ntf Q empty.\nCalled at %s:%d\n", file, line);
512 
513 	zassert_not_equal(ntf->hdr.type, NODE_RX_TYPE_DC_PDU,
514 			  "Ntf node is of the wrong type.\nCalled at %s:%d\n", file, line);
515 
516 	if (helper_node_verify[opcode]) {
517 		helper_node_verify[opcode](file, line, ntf, param);
518 	}
519 
520 	*ntf_ref = ntf;
521 }
522 
ut_rx_q_is_empty_real(const char * file,uint32_t line)523 void ut_rx_q_is_empty_real(const char *file, uint32_t line)
524 {
525 	struct node_rx_pdu *ntf;
526 
527 	ntf = (struct node_rx_pdu *)sys_slist_get(&ut_rx_q);
528 	zassert_is_null(ntf, "Ntf Q not empty.\nCalled at %s:%d\n", file, line);
529 }
530 
encode_pdu(enum helper_pdu_opcode opcode,struct pdu_data * pdu,void * param)531 void encode_pdu(enum helper_pdu_opcode opcode, struct pdu_data *pdu, void *param)
532 {
533 	zassert_not_null(helper_pdu_encode[opcode], "PDU encode function cannot be NULL\n");
534 	helper_pdu_encode[opcode](pdu, param);
535 }
536