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