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