blob: 1be35e7da4169608760e793a8a90e91913418d8c [file] [log] [blame]
Harald Welteb795f032020-05-14 11:42:53 +02001
2#include <osmocom/core/utils.h>
3
Harald Welted55a2092022-11-29 22:33:54 +01004#include <osmocom/isdn/i460_mux.h>
Harald Welteb795f032020-05-14 11:42:53 +02005
Harald Welteb3b474d2020-08-02 11:54:56 +02006static void bits_cb(struct osmo_i460_subchan *schan, void *user_data,
7 const ubit_t *bits, unsigned int num_bits)
Harald Welteb795f032020-05-14 11:42:53 +02008{
9 char *str = user_data;
10 printf("demux_bits_cb '%s': %s\n", str, osmo_ubit_dump(bits, num_bits));
11}
12
13
14const struct osmo_i460_schan_desc scd64 = {
15 .rate = OSMO_I460_RATE_64k,
16 .bit_offset = 0,
17 .demux = {
18 .num_bits = 40,
19 .out_cb_bits = bits_cb,
20 .out_cb_bytes = NULL,
21 .user_data = "64k",
22 },
23};
24
25const struct osmo_i460_schan_desc scd32_0 = {
26 .rate = OSMO_I460_RATE_32k,
27 .bit_offset = 0,
28 .demux = {
29 .num_bits = 40,
30 .out_cb_bits = bits_cb,
31 .out_cb_bytes = NULL,
32 .user_data = "32k_0",
33 },
34};
35const struct osmo_i460_schan_desc scd32_4 = {
36 .rate = OSMO_I460_RATE_32k,
37 .bit_offset = 4,
38 .demux = {
39 .num_bits = 40,
40 .out_cb_bits = bits_cb,
41 .out_cb_bytes = NULL,
42 .user_data = "32k_4",
43 },
44};
45
46const struct osmo_i460_schan_desc scd16_0 = {
47 .rate = OSMO_I460_RATE_16k,
48 .bit_offset = 0,
49 .demux = {
50 .num_bits = 40,
51 .out_cb_bits = bits_cb,
52 .out_cb_bytes = NULL,
53 .user_data = "16k_0",
54 },
55};
56const struct osmo_i460_schan_desc scd16_2 = {
57 .rate = OSMO_I460_RATE_16k,
58 .bit_offset = 2,
59 .demux = {
60 .num_bits = 40,
61 .out_cb_bits = bits_cb,
62 .out_cb_bytes = NULL,
63 .user_data = "16k_2",
64 },
65};
66const struct osmo_i460_schan_desc scd16_4 = {
67 .rate = OSMO_I460_RATE_16k,
68 .bit_offset = 4,
69 .demux = {
70 .num_bits = 40,
71 .out_cb_bits = bits_cb,
72 .out_cb_bytes = NULL,
73 .user_data = "16k_4",
74 },
75};
76const struct osmo_i460_schan_desc scd16_6 = {
77 .rate = OSMO_I460_RATE_16k,
78 .bit_offset = 6,
79 .demux = {
80 .num_bits = 40,
81 .out_cb_bits = bits_cb,
82 .out_cb_bytes = NULL,
83 .user_data = "16k_6",
84 },
85};
86
87const struct osmo_i460_schan_desc scd8_0 = {
88 .rate = OSMO_I460_RATE_8k,
89 .bit_offset = 0,
90 .demux = {
91 .num_bits = 40,
92 .out_cb_bits = bits_cb,
93 .out_cb_bytes = NULL,
94 .user_data = "8k_0",
95 },
96};
97const struct osmo_i460_schan_desc scd8_1 = {
98 .rate = OSMO_I460_RATE_8k,
99 .bit_offset = 1,
100 .demux = {
101 .num_bits = 40,
102 .out_cb_bits = bits_cb,
103 .out_cb_bytes = NULL,
104 .user_data = "8k_1",
105 },
106};
107const struct osmo_i460_schan_desc scd8_2 = {
108 .rate = OSMO_I460_RATE_8k,
109 .bit_offset = 2,
110 .demux = {
111 .num_bits = 40,
112 .out_cb_bits = bits_cb,
113 .out_cb_bytes = NULL,
114 .user_data = "8k_2",
115 },
116};
117const struct osmo_i460_schan_desc scd8_3 = {
118 .rate = OSMO_I460_RATE_8k,
119 .bit_offset = 3,
120 .demux = {
121 .num_bits = 40,
122 .out_cb_bits = bits_cb,
123 .out_cb_bytes = NULL,
124 .user_data = "8k_3",
125 },
126};
127const struct osmo_i460_schan_desc scd8_4 = {
128 .rate = OSMO_I460_RATE_8k,
129 .bit_offset = 4,
130 .demux = {
131 .num_bits = 40,
132 .out_cb_bits = bits_cb,
133 .out_cb_bytes = NULL,
134 .user_data = "8k_4",
135 },
136};
137const struct osmo_i460_schan_desc scd8_5 = {
138 .rate = OSMO_I460_RATE_8k,
139 .bit_offset = 5,
140 .demux = {
141 .num_bits = 40,
142 .out_cb_bits = bits_cb,
143 .out_cb_bytes = NULL,
144 .user_data = "8k_5",
145 },
146};
147const struct osmo_i460_schan_desc scd8_6 = {
148 .rate = OSMO_I460_RATE_8k,
149 .bit_offset = 6,
150 .demux = {
151 .num_bits = 40,
152 .out_cb_bits = bits_cb,
153 .out_cb_bytes = NULL,
154 .user_data = "8k_6",
155 },
156};
157const struct osmo_i460_schan_desc scd8_7 = {
158 .rate = OSMO_I460_RATE_8k,
159 .bit_offset = 7,
160 .demux = {
161 .num_bits = 40,
162 .out_cb_bits = bits_cb,
163 .out_cb_bytes = NULL,
164 .user_data = "8k_7",
165 },
166};
167
168static void test_no_subchan(void)
169{
170 struct osmo_i460_timeslot _ts, *ts = &_ts;
171
172 /* Initialization */
173 printf("\n==> %s\n", __func__);
174 osmo_i460_ts_init(ts);
175
176 /* feed in some data; expect nothing to happen */
177 const uint8_t nothing[128] = { 0, };
178 osmo_i460_demux_in(ts, nothing, sizeof(nothing));
179
180 /* pull bytes out of mux (should be all 0xff) */
181 uint8_t buf[128];
182 osmo_i460_mux_out(ts, buf, sizeof(buf));
183 printf("out: %s\n", osmo_hexdump(buf, sizeof(buf)));
184}
185
186static struct msgb *gen_alternating_bitmsg(unsigned int num_bits)
187{
188 struct msgb *msg = msgb_alloc(num_bits, "mux-in");
189 int i;
190 for (i = 0; i < num_bits; i++)
191 msgb_put_u8(msg, i & 1);
192 return msg;
193}
194
195static void test_64k_subchan(void)
196{
197 struct osmo_i460_timeslot _ts, *ts = &_ts;
198
199 /* Initialization */
200 printf("\n==> %s\n", __func__);
201 osmo_i460_ts_init(ts);
202 osmo_i460_subchan_add(NULL, ts, &scd64);
203
204 /* demux */
205 uint8_t sequence[128];
206 int i;
207 for (i = 0; i < sizeof(sequence); i++)
208 sequence[i] = i;
209 osmo_i460_demux_in(ts, sequence, sizeof(sequence));
210
211 /* mux */
212 struct msgb *msg = gen_alternating_bitmsg(128);
213 osmo_i460_mux_enqueue(&ts->schan[0], msg);
214
215 uint8_t buf[16];
216 osmo_i460_mux_out(ts, buf, sizeof(buf));
217 printf("mux_out: %s\n", osmo_hexdump(buf, sizeof(buf)));
218
219 osmo_i460_subchan_del(&ts->schan[0]);
220}
221
222static void test_32k_subchan(void)
223{
224 struct osmo_i460_timeslot _ts, *ts = &_ts;
225
226 /* Initialization */
227 printf("\n==> %s\n", __func__);
228 osmo_i460_ts_init(ts);
229 osmo_i460_subchan_add(NULL, ts, &scd32_0);
230 osmo_i460_subchan_add(NULL, ts, &scd32_4);
231
232 /* demux */
233 uint8_t sequence[10];
234 int i;
235 for (i = 0; i < sizeof(sequence); i++)
236 sequence[i] = 0;
Harald Welteb795f032020-05-14 11:42:53 +0200237 sequence[1] = 0xf0;
Harald Welte44964982020-08-02 21:54:30 +0200238 sequence[0] = 0x0f;
Harald Welteb795f032020-05-14 11:42:53 +0200239 sequence[2] = 0xff;
240 osmo_i460_demux_in(ts, sequence, sizeof(sequence));
241
242 /* mux */
243
244 /* test with only a single channel active */
245 for (i = 0; i < 2; i++) {
246 struct msgb *msg = gen_alternating_bitmsg(128);
247 osmo_i460_mux_enqueue(&ts->schan[i], msg);
248 printf("%s-single-%u\n", __func__, i);
249
250 uint8_t buf[16];
251 int j;
252 for (j = 0; j < 3; j++) {
253 osmo_i460_mux_out(ts, buf, sizeof(buf));
254 printf("mux_out: %s\n", osmo_hexdump(buf, sizeof(buf)));
255 }
256 }
257
258 for (i = 0; i < 4; i++)
259 osmo_i460_subchan_del(&ts->schan[i]);
260}
261
262
263
264static void test_16k_subchan(void)
265{
266 struct osmo_i460_timeslot _ts, *ts = &_ts;
267
268 /* Initialization */
269 printf("\n==> %s\n", __func__);
270 osmo_i460_ts_init(ts);
271 osmo_i460_subchan_add(NULL, ts, &scd16_0);
272 osmo_i460_subchan_add(NULL, ts, &scd16_2);
273 osmo_i460_subchan_add(NULL, ts, &scd16_4);
274 osmo_i460_subchan_add(NULL, ts, &scd16_6);
275
276 /* demux */
277 uint8_t sequence[20];
278 int i;
279 for (i = 0; i < sizeof(sequence); i++)
280 sequence[i] = 0;
Harald Welte44964982020-08-02 21:54:30 +0200281 sequence[0] = 0xC0;
282 sequence[1] = 0x30;
283 sequence[2] = 0x0c;
284 sequence[3] = 0x03;
Harald Welteb795f032020-05-14 11:42:53 +0200285 sequence[4] = 0xff;
286 osmo_i460_demux_in(ts, sequence, sizeof(sequence));
287
288 /* mux */
289
290 /* test with only a single channel active */
291 for (i = 0; i < 4; i++) {
292 struct msgb *msg = gen_alternating_bitmsg(128);
293 osmo_i460_mux_enqueue(&ts->schan[i], msg);
294 printf("%s-single-%u\n", __func__, i);
295
296 uint8_t buf[16];
297 int j;
298 for (j = 0; j < 5; j++) {
299 osmo_i460_mux_out(ts, buf, sizeof(buf));
300 printf("mux_out: %s\n", osmo_hexdump(buf, sizeof(buf)));
301 }
302 }
303
304 for (i = 0; i < 4; i++)
305 osmo_i460_subchan_del(&ts->schan[i]);
306}
307
308
309static void test_8k_subchan(void)
310{
311 struct osmo_i460_timeslot _ts, *ts = &_ts;
312
313 /* Initialization */
314 printf("\n==> %s\n", __func__);
315 osmo_i460_ts_init(ts);
316 osmo_i460_subchan_add(NULL, ts, &scd8_0);
317 osmo_i460_subchan_add(NULL, ts, &scd8_1);
318 osmo_i460_subchan_add(NULL, ts, &scd8_2);
319 osmo_i460_subchan_add(NULL, ts, &scd8_3);
320 osmo_i460_subchan_add(NULL, ts, &scd8_4);
321 osmo_i460_subchan_add(NULL, ts, &scd8_5);
322 osmo_i460_subchan_add(NULL, ts, &scd8_6);
323 osmo_i460_subchan_add(NULL, ts, &scd8_7);
324
325 /* demux */
326 uint8_t sequence[40];
327 int i;
328 for (i = 0; i < sizeof(sequence); i++)
329 sequence[i] = 0;
330 i = 0;
Harald Welteb795f032020-05-14 11:42:53 +0200331 sequence[i++] = 0x80;
Harald Welte44964982020-08-02 21:54:30 +0200332 sequence[i++] = 0x40;
333 sequence[i++] = 0x20;
334 sequence[i++] = 0x10;
Harald Welteb795f032020-05-14 11:42:53 +0200335 sequence[i++] = 0xf0;
Harald Welte44964982020-08-02 21:54:30 +0200336 sequence[i++] = 0x08;
337 sequence[i++] = 0x04;
338 sequence[i++] = 0x02;
339 sequence[i++] = 0x01;
340 sequence[i++] = 0x0f;
Harald Welteb795f032020-05-14 11:42:53 +0200341 sequence[i++] = 0xff;
342 osmo_i460_demux_in(ts, sequence, sizeof(sequence));
343
344 /* mux */
345
346 /* test with only a single channel active */
347 for (i = 0; i < 8; i++) {
348 struct msgb *msg = gen_alternating_bitmsg(64);
349 osmo_i460_mux_enqueue(&ts->schan[i], msg);
350 printf("%s-single-%u\n", __func__, i);
351
352 uint8_t buf[16];
353 int j;
354 for (j = 0; j < 5; j++) {
355 osmo_i460_mux_out(ts, buf, sizeof(buf));
356 printf("mux_out: %s\n", osmo_hexdump(buf, sizeof(buf)));
357 }
358 }
359
360 for (i = 0; i < 8; i++)
361 osmo_i460_subchan_del(&ts->schan[i]);
362}
363
364/* activate only one sub-channel; expect unused bits to be '1' */
365static void test_unused_subchan(void)
366{
367 struct osmo_i460_timeslot _ts, *ts = &_ts;
368
369 /* Initialization */
370 printf("\n==> %s\n", __func__);
371 osmo_i460_ts_init(ts);
372 osmo_i460_subchan_add(NULL, ts, &scd16_0);
373
374 /* mux */
375 struct msgb *msg = gen_alternating_bitmsg(128);
376 memset(msgb_data(msg), 0, msgb_length(msg));
377 osmo_i460_mux_enqueue(&ts->schan[0], msg);
378 printf("%s-single\n", __func__);
379
380 uint8_t buf[16];
381 int j;
382 for (j = 0; j < 5; j++) {
383 osmo_i460_mux_out(ts, buf, sizeof(buf));
384 printf("mux_out: %s\n", osmo_hexdump(buf, sizeof(buf)));
385 }
386
387 osmo_i460_subchan_del(&ts->schan[0]);
388}
389
390int main(int argc, char **argv)
391{
392 test_no_subchan();
393 test_64k_subchan();
394 test_32k_subchan();
395 test_16k_subchan();
396 test_8k_subchan();
397 test_unused_subchan();
Oliver Smith55934c42021-01-21 11:57:48 +0100398 return 0;
Harald Welteb795f032020-05-14 11:42:53 +0200399}