1 /*
2  * Copyright (c) 2020 Demant
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #include <zephyr/types.h>
12 #include <zephyr/ztest.h>
13 #include <zephyr/ztest_error_hook.h>
14 
15 #include <zephyr/toolchain.h>
16 #include <zephyr/sys/util.h>
17 
18 #include <zephyr/kernel.h>
19 
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/conn.h>
22 #include <zephyr/bluetooth/hci.h>
23 
24 #include "util/memq.h"
25 
26 #include "pdu_df.h"
27 #include "lll/pdu_vendor.h"
28 #include "pdu.h"
29 
30 #include "ll.h"
31 #include "lll.h"
32 #include "lll_conn_iso.h"
33 #include "lll_iso_tx.h"
34 #include "isoal.h"
35 #include "ull_iso_types.h"
36 
37 #include "isoal_test_common.h"
38 #include "isoal_test_debug.h"
39 
40 
41 #if defined(DEBUG_TEST)
42 /**
43  * Print contents of a RX PDU
44  * @param[in] pdu_meta Pointer to PDU structure including meta information
45  */
isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx * pdu_meta)46 void isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx *pdu_meta)
47 {
48 	zassert_not_null(pdu_meta, "");
49 
50 	struct pdu_iso *pdu;
51 	uint8_t seg_length;
52 
53 	pdu = pdu_meta->pdu;
54 	seg_length = 0;
55 
56 	PRINT("\n");
57 	PRINT("PDU %04u (%10u) | %12s [%10s] %03u: ",
58 		(uint32_t) pdu_meta->meta->payload_number,
59 		(uint32_t) pdu_meta->meta->timestamp,
60 		LLID_TO_STR(pdu_meta->pdu->ll_id),
61 		DU_ERR_TO_STR(pdu_meta->meta->status),
62 		pdu_meta->pdu->len);
63 
64 	for (uint8_t i = 0U; i < pdu->len; i++) {
65 		if (seg_length == 0U && pdu->ll_id == PDU_BIS_LLID_FRAMED) {
66 			seg_length = pdu->payload[i + 1U];
67 			PRINT("[%s %s %03u]",
68 				pdu->payload[i] & BIT(0) ? "C" : "S",
69 				pdu->payload[i] & BIT(1) ? "C" : "-",
70 				pdu->payload[i + 1U]);
71 			if ((pdu->payload[i] & BIT(0)) == 0U) {
72 				PRINT("(%8uus)",
73 					((uint32_t)pdu->payload[i + 2U] +
74 					((uint32_t)pdu->payload[i + 3U] << 8) +
75 					((uint32_t)pdu->payload[i + 4U] << 16)));
76 			}
77 
78 			PRINT(" / ");
79 			PRINT("[%02x %02x]",
80 				pdu->payload[i],
81 				pdu->payload[i + 1U]);
82 			if ((pdu->payload[i] & BIT(0)) == 0U) {
83 				PRINT("(%02x %02x %02x)",
84 					(uint32_t)pdu->payload[i + 4U],
85 					(uint32_t)pdu->payload[i + 3U],
86 					(uint32_t)pdu->payload[i + 2U]);
87 			}
88 
89 			PRINT(" : ");
90 			seg_length -= pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE;
91 			i += PDU_ISO_SEG_HDR_SIZE +
92 				(pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE);
93 		}
94 
95 		PRINT("%02x ", pdu->payload[i]);
96 		seg_length--;
97 		if (seg_length == 0 && pdu->ll_id == PDU_BIS_LLID_FRAMED) {
98 			PRINT("\n%44s", "");
99 		}
100 	}
101 	PRINT("\n");
102 	PRINT("\n");
103 }
104 
105 /**
106  * Print contents of RX SDU
107  * @param sink_ctx Sink context provided when SDU is emitted
108  * @param sdu_frag Information on emitted fragment
109  * @param sdu      Information collated for SDu
110  */
isoal_test_debug_print_rx_sdu(const struct isoal_sink * sink_ctx,const struct isoal_emitted_sdu_frag * sdu_frag,const struct isoal_emitted_sdu * sdu)111 void isoal_test_debug_print_rx_sdu(const struct isoal_sink             *sink_ctx,
112 				   const struct isoal_emitted_sdu_frag *sdu_frag,
113 				   const struct isoal_emitted_sdu      *sdu)
114 {
115 	zassert_not_null(sink_ctx, "");
116 	zassert_not_null(sdu_frag, "");
117 	zassert_not_null(sdu, "");
118 
119 	uint8_t *buf = ((struct rx_sdu_frag_buffer *)sdu_frag->sdu.contents.dbuf)->sdu;
120 	uint16_t len = sdu_frag->sdu_frag_size;
121 
122 	PRINT("\n");
123 	PRINT("SDU %04d (%10d) | %12s [%10s] %03d: ",
124 		sdu_frag->sdu.sn,
125 		sdu_frag->sdu.timestamp,
126 		STATE_TO_STR(sdu_frag->sdu_state),
127 		DU_ERR_TO_STR(sdu_frag->sdu.status),
128 		len);
129 	for (int i = 0; i < len; i++) {
130 		PRINT("%02x ", buf[i]);
131 	}
132 	PRINT("\n");
133 
134 	PRINT("    %17s   %12s [%10s] %03d  ",
135 		"Collated-",
136 		(sdu->total_sdu_size != len ||
137 			sdu->collated_status != sdu_frag->sdu.status ?
138 				"!! DIFF !!" : ""),
139 		DU_ERR_TO_STR(sdu->collated_status),
140 		sdu->total_sdu_size);
141 	PRINT("\n");
142 	PRINT("\n");
143 }
144 
145 /**
146  * Print contents of a TX PDU
147  * @param[in] node_tx Pointer to PDU structure including meta information
148  */
isoal_test_debug_print_tx_pdu(struct node_tx_iso * node_tx)149 void isoal_test_debug_print_tx_pdu(struct node_tx_iso *node_tx)
150 {
151 	struct pdu_iso *pdu;
152 	uint8_t seg_length;
153 
154 	zassert_not_null(node_tx, "");
155 
156 	pdu = (struct pdu_iso *)node_tx->pdu;
157 	seg_length = 0;
158 
159 	zassert_not_null(pdu, "");
160 
161 	PRINT("\n");
162 	PRINT("PDU %04u (    %02u    ) | %12s | %03u: ",
163 		(uint32_t) node_tx->payload_count,
164 		 node_tx->sdu_fragments,
165 		LLID_TO_STR(pdu->ll_id),
166 		pdu->len);
167 
168 	for (int i = 0; i < pdu->len; i++) {
169 		if (seg_length == 0 && pdu->ll_id == PDU_BIS_LLID_FRAMED) {
170 			seg_length = pdu->payload[i+1];
171 			PRINT("[%s %s %03u]",
172 				pdu->payload[i] & BIT(0) ? "C" : "S",
173 				pdu->payload[i] & BIT(1) ? "C" : "-",
174 				pdu->payload[i+1]);
175 			if ((pdu->payload[i] & BIT(0)) == 0) {
176 				PRINT("(%8uus)",
177 					((uint32_t)pdu->payload[i+2] +
178 					((uint32_t)pdu->payload[i+3] << 8) +
179 					((uint32_t)pdu->payload[i+4] << 16)));
180 			}
181 			PRINT(" / ");
182 			PRINT("[%02x %02x]",
183 				pdu->payload[i],
184 				pdu->payload[i+1]);
185 			if ((pdu->payload[i] & BIT(0)) == 0) {
186 				PRINT("(%02x %02x %02x)",
187 					(uint32_t)pdu->payload[i+4],
188 					(uint32_t)pdu->payload[i+3],
189 					(uint32_t)pdu->payload[i+2]);
190 			}
191 			PRINT(" : ");
192 			seg_length -= pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE;
193 			i = i + PDU_ISO_SEG_HDR_SIZE +
194 				(pdu->payload[i] & BIT(0) ? 0 : PDU_ISO_SEG_TIMEOFFSET_SIZE);
195 		}
196 		PRINT("%02x ", pdu->payload[i]);
197 		seg_length--;
198 		if (seg_length == 0 && pdu->ll_id == PDU_BIS_LLID_FRAMED) {
199 			PRINT("\n%44s", "");
200 		}
201 	}
202 	PRINT("\n");
203 	PRINT("\n");
204 }
205 
206 /**
207  * Print contents of TX SDU
208  * @param[in] sink_ctx Sink context provided when SDU is emitted
209  * @param[in] buf      SDU data buffer pointer
210  */
isoal_test_debug_print_tx_sdu(struct isoal_sdu_tx * tx_sdu)211 void isoal_test_debug_print_tx_sdu(struct isoal_sdu_tx *tx_sdu)
212 {
213 	uint8_t *buf;
214 	uint16_t len;
215 
216 	zassert_not_null(tx_sdu, "");
217 
218 	buf = tx_sdu->dbuf;
219 	len = tx_sdu->size;
220 
221 	PRINT("\n");
222 	PRINT("SDU %04u (%10u) | %12s | %03u: ",
223 		tx_sdu->packet_sn,
224 		tx_sdu->time_stamp,
225 		STATE_TO_STR(tx_sdu->sdu_state),
226 		len);
227 	for (int i = 0; i < len; i++) {
228 		PRINT("%02x ", buf[i]);
229 	}
230 	PRINT("\n");
231 	PRINT("Cntr TS. <%10u>\n", tx_sdu->cntr_time_stamp);
232 	PRINT("    Ref. <%10u>\n", tx_sdu->grp_ref_point);
233 	PRINT("   Event <%10u>\n", (uint32_t)tx_sdu->target_event);
234 	PRINT("\n");
235 }
236 #else /* DEBUG_TEST */
isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx * pdu_meta)237 void isoal_test_debug_print_rx_pdu(struct isoal_pdu_rx *pdu_meta) {}
isoal_test_debug_print_rx_sdu(const struct isoal_sink * sink_ctx,const struct isoal_emitted_sdu_frag * sdu_frag,const struct isoal_emitted_sdu * sdu)238 void isoal_test_debug_print_rx_sdu(const struct isoal_sink             *sink_ctx,
239 				   const struct isoal_emitted_sdu_frag *sdu_frag,
240 				   const struct isoal_emitted_sdu      *sdu)
241 {
242 
243 }
isoal_test_debug_print_tx_pdu(struct node_tx_iso * node_tx)244 void isoal_test_debug_print_tx_pdu(struct node_tx_iso *node_tx) {}
isoal_test_debug_print_tx_sdu(struct isoal_sdu_tx * tx_sdu)245 void isoal_test_debug_print_tx_sdu(struct isoal_sdu_tx *tx_sdu) {}
246 #endif /* DEBUG_TEST */
247 
248 #if defined(DEBUG_TRACE)
249 /**
250  * Print function trace
251  * @param func   Function name
252  * @param status Status
253  */
isoal_test_debug_trace_func_call(const uint8_t * func,const uint8_t * status)254 void isoal_test_debug_trace_func_call(const uint8_t *func, const uint8_t *status)
255 {
256 	PRINT("%s :: %s\n", func, status);
257 }
258 #else /* DEBUG_TRACE */
isoal_test_debug_trace_func_call(const uint8_t * func,const uint8_t * status)259 void isoal_test_debug_trace_func_call(const uint8_t *func, const uint8_t *status) {}
260 #endif /* DEBUG_TRACE */
261