Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/hdlc_tests.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * hdlc_tests.c | |
5 * | |
6 * Written by Steve Underwood <steveu@coppice.org> | |
7 * | |
8 * Copyright (C) 2003 Steve Underwood | |
9 * | |
10 * All rights reserved. | |
11 * | |
12 * This program is free software; you can redistribute it and/or modify | |
13 * it under the terms of the GNU General Public License version 2, as | |
14 * published by the Free Software Foundation. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
24 * | |
25 * $Id: hdlc_tests.c,v 1.48 2008/11/30 05:43:37 steveu Exp $ | |
26 */ | |
27 | |
28 /*! \file */ | |
29 | |
30 /*! \page hdlc_tests_page HDLC tests | |
31 \section hdlc_tests_page_sec_1 What does it do? | |
32 The HDLC tests exercise the HDLC module, and verifies correct operation | |
33 using both 16 and 32 bit CRCs. | |
34 */ | |
35 | |
36 #if defined(HAVE_CONFIG_H) | |
37 #include "config.h" | |
38 #endif | |
39 | |
40 #include <stdlib.h> | |
41 #include <stdio.h> | |
42 #include <unistd.h> | |
43 #include <string.h> | |
44 | |
45 #include "spandsp.h" | |
46 #include "spandsp/private/hdlc.h" | |
47 | |
48 int ref_len; | |
49 uint8_t buf[1000]; | |
50 | |
51 int abort_reported; | |
52 int frame_handled; | |
53 int frame_failed; | |
54 int frame_len_errors; | |
55 int frame_data_errors; | |
56 int underflow_reported; | |
57 int framing_ok_reported; | |
58 int framing_ok_reports; | |
59 | |
60 hdlc_rx_state_t rx; | |
61 hdlc_tx_state_t tx; | |
62 | |
63 int frames_sent; | |
64 int bytes_sent; | |
65 uint64_t start; | |
66 uint64_t end; | |
67 | |
68 /* Use a local random generator, so the results are consistent across platforms. We have hard coded | |
69 correct results for a message sequence generated by this particular PRNG. */ | |
70 static int my_rand(void) | |
71 { | |
72 static int rndnum = 1234567; | |
73 | |
74 return (rndnum = 1664525U*rndnum + 1013904223U) >> 8; | |
75 } | |
76 /*- End of function --------------------------------------------------------*/ | |
77 | |
78 static int cook_up_msg(uint8_t *buf) | |
79 { | |
80 int i; | |
81 int len; | |
82 | |
83 /* Use medium length messages, with some randomised length variation. */ | |
84 /* TODO: this doesn't exercise extremely short or long messages. */ | |
85 len = (my_rand() & 0x3F) + 100; | |
86 for (i = 0; i < len; i++) | |
87 buf[i] = my_rand(); | |
88 return len; | |
89 } | |
90 /*- End of function --------------------------------------------------------*/ | |
91 | |
92 static void frame_handler(void *user_data, const uint8_t *pkt, int len, int ok) | |
93 { | |
94 if (len < 0) | |
95 { | |
96 /* Special conditions */ | |
97 printf("HDLC rx status is %s (%d)\n", signal_status_to_str(len), len); | |
98 switch (len) | |
99 { | |
100 case SIG_STATUS_FRAMING_OK: | |
101 framing_ok_reported = TRUE; | |
102 framing_ok_reports++; | |
103 break; | |
104 case SIG_STATUS_ABORT: | |
105 abort_reported = TRUE; | |
106 break; | |
107 } | |
108 return; | |
109 } | |
110 if (ok) | |
111 { | |
112 if (len != ref_len) | |
113 { | |
114 printf("Len error - %d %d\n", len, ref_len); | |
115 frame_len_errors++; | |
116 return; | |
117 } | |
118 if (memcmp(pkt, buf, len)) | |
119 { | |
120 printf("Frame data error\n"); | |
121 frame_data_errors++; | |
122 return; | |
123 } | |
124 frame_handled = TRUE; | |
125 } | |
126 else | |
127 { | |
128 frame_failed = TRUE; | |
129 } | |
130 } | |
131 /*- End of function --------------------------------------------------------*/ | |
132 | |
133 static void underflow_handler(void *user_data) | |
134 { | |
135 //printf("Underflow reported\n"); | |
136 underflow_reported = TRUE; | |
137 } | |
138 /*- End of function --------------------------------------------------------*/ | |
139 | |
140 static void check_result(void) | |
141 { | |
142 hdlc_rx_stats_t rx_stats; | |
143 | |
144 hdlc_rx_get_stats(&rx, &rx_stats); | |
145 printf("%lu bytes\n", rx_stats.bytes); | |
146 printf("%lu good frames\n", rx_stats.good_frames); | |
147 printf("%lu CRC errors\n", rx_stats.crc_errors); | |
148 printf("%lu length errors\n", rx_stats.length_errors); | |
149 printf("%lu aborts\n", rx_stats.aborts); | |
150 printf("%d frame length errors\n", frame_len_errors); | |
151 printf("%d frame data errors\n", frame_data_errors); | |
152 printf("Test duration %" PRIu64 " ticks\n", end - start); | |
153 if (rx_stats.bytes != bytes_sent | |
154 || | |
155 rx_stats.good_frames != frames_sent | |
156 || | |
157 rx_stats.crc_errors != 0 | |
158 || | |
159 rx_stats.length_errors != 0 | |
160 || | |
161 rx_stats.aborts != 0 | |
162 || | |
163 frame_len_errors != 0 | |
164 || | |
165 frame_data_errors != 0) | |
166 { | |
167 printf("Tests failed.\n"); | |
168 exit(2); | |
169 } | |
170 printf("Test passed.\n\n"); | |
171 } | |
172 /*- End of function --------------------------------------------------------*/ | |
173 | |
174 static int test_hdlc_modes(void) | |
175 { | |
176 int i; | |
177 int j; | |
178 int len; | |
179 int nextbyte; | |
180 int progress; | |
181 int progress_delay; | |
182 uint8_t bufx[100]; | |
183 | |
184 /* Try sending HDLC messages with CRC-16 */ | |
185 printf("Testing with CRC-16 (byte by byte)\n"); | |
186 frame_len_errors = 0; | |
187 frame_data_errors = 0; | |
188 hdlc_tx_init(&tx, FALSE, 1, FALSE, underflow_handler, NULL); | |
189 hdlc_rx_init(&rx, FALSE, FALSE, 5, frame_handler, NULL); | |
190 underflow_reported = FALSE; | |
191 | |
192 start = rdtscll(); | |
193 hdlc_tx_flags(&tx, 40); | |
194 /* Push an initial message so we should NOT get an underflow after the preamble. */ | |
195 ref_len = cook_up_msg(buf); | |
196 hdlc_tx_frame(&tx, buf, ref_len); | |
197 frame_handled = FALSE; | |
198 frame_failed = FALSE; | |
199 frames_sent = 0; | |
200 bytes_sent = 0; | |
201 for (i = 0; i < 1000000; i++) | |
202 { | |
203 nextbyte = hdlc_tx_get_byte(&tx); | |
204 hdlc_rx_put_byte(&rx, nextbyte); | |
205 if (underflow_reported) | |
206 { | |
207 underflow_reported = FALSE; | |
208 nextbyte = hdlc_tx_get_byte(&tx); | |
209 hdlc_rx_put_byte(&rx, nextbyte); | |
210 frames_sent++; | |
211 bytes_sent += ref_len; | |
212 if (!frame_handled) | |
213 { | |
214 printf("Frame not received.\n"); | |
215 return -1; | |
216 } | |
217 ref_len = cook_up_msg(buf); | |
218 hdlc_tx_frame(&tx, buf, ref_len); | |
219 frame_handled = FALSE; | |
220 } | |
221 } | |
222 end = rdtscll(); | |
223 check_result(); | |
224 | |
225 /* Now try sending HDLC messages with CRC-16 */ | |
226 printf("Testing with CRC-16 (chunk by chunk)\n"); | |
227 frame_len_errors = 0; | |
228 frame_data_errors = 0; | |
229 hdlc_tx_init(&tx, FALSE, 1, FALSE, underflow_handler, NULL); | |
230 hdlc_rx_init(&rx, FALSE, FALSE, 5, frame_handler, NULL); | |
231 underflow_reported = FALSE; | |
232 | |
233 start = rdtscll(); | |
234 hdlc_tx_flags(&tx, 40); | |
235 /* Push an initial message so we should NOT get an underflow after the preamble. */ | |
236 ref_len = cook_up_msg(buf); | |
237 hdlc_tx_frame(&tx, buf, ref_len); | |
238 frame_handled = FALSE; | |
239 frame_failed = FALSE; | |
240 frames_sent = 0; | |
241 bytes_sent = 0; | |
242 for (i = 0; i < 10000; i++) | |
243 { | |
244 len = hdlc_tx_get(&tx, bufx, 100); | |
245 hdlc_rx_put(&rx, bufx, len); | |
246 if (underflow_reported) | |
247 { | |
248 underflow_reported = FALSE; | |
249 len = hdlc_tx_get(&tx, bufx, 100); | |
250 hdlc_rx_put(&rx, bufx, len); | |
251 frames_sent++; | |
252 bytes_sent += ref_len; | |
253 if (!frame_handled) | |
254 { | |
255 printf("Frame not received.\n"); | |
256 return -1; | |
257 } | |
258 ref_len = cook_up_msg(buf); | |
259 hdlc_tx_frame(&tx, buf, ref_len); | |
260 frame_handled = FALSE; | |
261 } | |
262 } | |
263 end = rdtscll(); | |
264 check_result(); | |
265 | |
266 /* Now try sending HDLC messages with CRC-16 bit by bit */ | |
267 printf("Testing with CRC-16 (bit by bit)\n"); | |
268 frame_len_errors = 0; | |
269 frame_data_errors = 0; | |
270 hdlc_tx_init(&tx, FALSE, 2, FALSE, underflow_handler, NULL); | |
271 hdlc_rx_init(&rx, FALSE, FALSE, 5, frame_handler, NULL); | |
272 underflow_reported = FALSE; | |
273 | |
274 start = rdtscll(); | |
275 hdlc_tx_flags(&tx, 40); | |
276 /* Don't push an initial message so we should get an underflow after the preamble. */ | |
277 /* Lie for the first message, as there isn't really one */ | |
278 frame_handled = TRUE; | |
279 frame_failed = FALSE; | |
280 frames_sent = 0; | |
281 bytes_sent = 0; | |
282 ref_len = 0; | |
283 for (i = 0; i < 8*1000000; i++) | |
284 { | |
285 nextbyte = hdlc_tx_get_bit(&tx); | |
286 hdlc_rx_put_bit(&rx, nextbyte); | |
287 if (underflow_reported) | |
288 { | |
289 underflow_reported = FALSE; | |
290 for (j = 0; j < 20; j++) | |
291 { | |
292 nextbyte = hdlc_tx_get_bit(&tx); | |
293 hdlc_rx_put_bit(&rx, nextbyte); | |
294 } | |
295 if (ref_len) | |
296 { | |
297 frames_sent++; | |
298 bytes_sent += ref_len; | |
299 } | |
300 if (!frame_handled) | |
301 { | |
302 printf("Frame not received.\n"); | |
303 return -1; | |
304 } | |
305 ref_len = cook_up_msg(buf); | |
306 hdlc_tx_frame(&tx, buf, ref_len); | |
307 frame_handled = FALSE; | |
308 } | |
309 } | |
310 end = rdtscll(); | |
311 check_result(); | |
312 | |
313 /* Now try sending HDLC messages with CRC-32 */ | |
314 printf("Testing with CRC-32 (byte by byte)\n"); | |
315 frame_len_errors = 0; | |
316 frame_data_errors = 0; | |
317 hdlc_tx_init(&tx, TRUE, 1, FALSE, underflow_handler, NULL); | |
318 hdlc_rx_init(&rx, TRUE, FALSE, 1, frame_handler, NULL); | |
319 underflow_reported = FALSE; | |
320 | |
321 start = rdtscll(); | |
322 hdlc_tx_flags(&tx, 40); | |
323 /* Don't push an initial message so we should get an underflow after the preamble. */ | |
324 /* Lie for the first message, as there isn't really one */ | |
325 frame_handled = TRUE; | |
326 frame_failed = FALSE; | |
327 frames_sent = 0; | |
328 bytes_sent = 0; | |
329 ref_len = 0; | |
330 for (i = 0; i < 1000000; i++) | |
331 { | |
332 nextbyte = hdlc_tx_get_byte(&tx); | |
333 hdlc_rx_put_byte(&rx, nextbyte); | |
334 if (underflow_reported) | |
335 { | |
336 underflow_reported = FALSE; | |
337 nextbyte = hdlc_tx_get_byte(&tx); | |
338 hdlc_rx_put_byte(&rx, nextbyte); | |
339 if (ref_len) | |
340 { | |
341 frames_sent++; | |
342 bytes_sent += ref_len; | |
343 } | |
344 if (!frame_handled) | |
345 { | |
346 printf("Frame not received.\n"); | |
347 return -1; | |
348 } | |
349 ref_len = cook_up_msg(buf); | |
350 hdlc_tx_frame(&tx, buf, ref_len); | |
351 frame_handled = FALSE; | |
352 } | |
353 } | |
354 end = rdtscll(); | |
355 check_result(); | |
356 | |
357 /* Now try progressive mode with CRC-16 */ | |
358 printf("Testing progressive mode with CRC-16 (byte by byte)\n"); | |
359 frame_len_errors = 0; | |
360 frame_data_errors = 0; | |
361 hdlc_tx_init(&tx, TRUE, 1, TRUE, underflow_handler, NULL); | |
362 hdlc_rx_init(&rx, TRUE, FALSE, 1, frame_handler, NULL); | |
363 underflow_reported = FALSE; | |
364 | |
365 start = rdtscll(); | |
366 hdlc_tx_flags(&tx, 40); | |
367 /* Don't push an initial message so we should get an underflow after the preamble. */ | |
368 /* Lie for the first message, as there isn't really one */ | |
369 frame_handled = TRUE; | |
370 frame_failed = FALSE; | |
371 progress = 9999; | |
372 progress_delay = 9999; | |
373 frames_sent = 0; | |
374 bytes_sent = 0; | |
375 ref_len = 0; | |
376 for (i = 0; i < 1000000; i++) | |
377 { | |
378 nextbyte = hdlc_tx_get_byte(&tx); | |
379 hdlc_rx_put_byte(&rx, nextbyte); | |
380 if (underflow_reported) | |
381 { | |
382 underflow_reported = FALSE; | |
383 nextbyte = hdlc_tx_get_byte(&tx); | |
384 hdlc_rx_put_byte(&rx, nextbyte); | |
385 if (ref_len) | |
386 { | |
387 frames_sent++; | |
388 bytes_sent += ref_len; | |
389 } | |
390 if (!frame_handled) | |
391 { | |
392 printf("Frame not received.\n"); | |
393 return -1; | |
394 } | |
395 ref_len = cook_up_msg(buf); | |
396 hdlc_tx_frame(&tx, buf, 10); | |
397 progress = 10; | |
398 progress_delay = 8; | |
399 frame_handled = FALSE; | |
400 } | |
401 if (progress < ref_len && progress_delay-- <= 0) | |
402 { | |
403 if (hdlc_tx_frame(&tx, buf + progress, (progress + 10 <= ref_len) ? 10 : ref_len - progress) < 0) | |
404 { | |
405 printf("Failed to add progressively\n"); | |
406 return -1; | |
407 } | |
408 progress += 10; | |
409 progress_delay = 8; | |
410 } | |
411 } | |
412 end = rdtscll(); | |
413 check_result(); | |
414 | |
415 printf("Tests passed.\n"); | |
416 return 0; | |
417 } | |
418 /*- End of function --------------------------------------------------------*/ | |
419 | |
420 static int test_hdlc_frame_length_error_handling(void) | |
421 { | |
422 int i; | |
423 int j; | |
424 int nextbyte; | |
425 | |
426 printf("Testing frame length error handling using CRC-16 (bit by bit)\n"); | |
427 frame_len_errors = 0; | |
428 frame_data_errors = 0; | |
429 hdlc_tx_init(&tx, FALSE, 2, FALSE, underflow_handler, NULL); | |
430 hdlc_rx_init(&rx, FALSE, TRUE, 5, frame_handler, NULL); | |
431 hdlc_rx_set_max_frame_len(&rx, 100); | |
432 underflow_reported = FALSE; | |
433 framing_ok_reported = FALSE; | |
434 framing_ok_reports = 0; | |
435 | |
436 hdlc_tx_flags(&tx, 10); | |
437 /* Don't push an initial message so we should get an underflow after the preamble. */ | |
438 /* Lie for the first message, as there isn't really one */ | |
439 frame_handled = TRUE; | |
440 frame_failed = FALSE; | |
441 frames_sent = 0; | |
442 bytes_sent = 0; | |
443 ref_len = 0; | |
444 for (i = 0; i < 8*1000000; i++) | |
445 { | |
446 nextbyte = hdlc_tx_get_bit(&tx); | |
447 hdlc_rx_put_bit(&rx, nextbyte); | |
448 if (framing_ok_reported) | |
449 { | |
450 printf("Framing OK reported at bit %d (%d)\n", i, framing_ok_reports); | |
451 framing_ok_reported = FALSE; | |
452 } | |
453 if (underflow_reported) | |
454 { | |
455 underflow_reported = FALSE; | |
456 for (j = 0; j < 20; j++) | |
457 { | |
458 nextbyte = hdlc_tx_get_bit(&tx); | |
459 hdlc_rx_put_bit(&rx, nextbyte); | |
460 if (framing_ok_reported) | |
461 { | |
462 printf("Framing OK reported at bit %d (%d) - %d\n", i, framing_ok_reports, frame_handled); | |
463 framing_ok_reported = FALSE; | |
464 } | |
465 } | |
466 if (ref_len) | |
467 { | |
468 frames_sent++; | |
469 bytes_sent += ref_len; | |
470 } | |
471 if (!frame_handled) | |
472 { | |
473 /* We should get a failure when the length reaches 101 */ | |
474 if (ref_len == 101) | |
475 { | |
476 printf("Tests passed.\n"); | |
477 return 0; | |
478 } | |
479 if (frame_failed) | |
480 printf("Frame failed.\n"); | |
481 printf("Frame not received at length %d.\n", ref_len); | |
482 return -1; | |
483 } | |
484 else | |
485 { | |
486 /* We should get a failure when the length reaches 101 */ | |
487 if (ref_len > 100) | |
488 { | |
489 printf("Tests failed.\n"); | |
490 return -1; | |
491 } | |
492 } | |
493 ref_len++; | |
494 hdlc_tx_frame(&tx, buf, ref_len); | |
495 frame_handled = FALSE; | |
496 } | |
497 } | |
498 /* We shouldn't reach here */ | |
499 printf("Tests failed.\n"); | |
500 return -1; | |
501 } | |
502 /*- End of function --------------------------------------------------------*/ | |
503 | |
504 static int test_hdlc_crc_error_handling(void) | |
505 { | |
506 int i; | |
507 int j; | |
508 int nextbyte; | |
509 int corrupt; | |
510 | |
511 printf("Testing CRC error handling using CRC-16 (bit by bit)\n"); | |
512 frame_len_errors = 0; | |
513 frame_data_errors = 0; | |
514 hdlc_tx_init(&tx, FALSE, 2, FALSE, underflow_handler, NULL); | |
515 hdlc_rx_init(&rx, FALSE, TRUE, 5, frame_handler, NULL); | |
516 underflow_reported = FALSE; | |
517 framing_ok_reported = FALSE; | |
518 framing_ok_reports = 0; | |
519 | |
520 hdlc_tx_flags(&tx, 10); | |
521 /* Don't push an initial message so we should get an underflow after the preamble. */ | |
522 /* Lie for the first message, as there isn't really one */ | |
523 frame_handled = TRUE; | |
524 frame_failed = FALSE; | |
525 frames_sent = 0; | |
526 bytes_sent = 0; | |
527 ref_len = 100; | |
528 corrupt = FALSE; | |
529 for (i = 0; i < 8*1000000; i++) | |
530 { | |
531 nextbyte = hdlc_tx_get_bit(&tx); | |
532 hdlc_rx_put_bit(&rx, nextbyte); | |
533 if (framing_ok_reported) | |
534 { | |
535 printf("Framing OK reported at bit %d (%d)\n", i, framing_ok_reports); | |
536 framing_ok_reported = FALSE; | |
537 } | |
538 if (underflow_reported) | |
539 { | |
540 underflow_reported = FALSE; | |
541 for (j = 0; j < 20; j++) | |
542 { | |
543 nextbyte = hdlc_tx_get_bit(&tx); | |
544 hdlc_rx_put_bit(&rx, nextbyte); | |
545 if (framing_ok_reported) | |
546 { | |
547 printf("Framing OK reported at bit %d (%d) - %d\n", i, framing_ok_reports, frame_handled); | |
548 framing_ok_reported = FALSE; | |
549 } | |
550 } | |
551 if (ref_len) | |
552 { | |
553 frames_sent++; | |
554 bytes_sent += ref_len; | |
555 } | |
556 if (!frame_handled) | |
557 { | |
558 if (!corrupt) | |
559 { | |
560 printf("Frame not received when it should be correct.\n"); | |
561 return -1; | |
562 } | |
563 } | |
564 else | |
565 { | |
566 if (corrupt) | |
567 { | |
568 printf("Frame received when it should be corrupt.\n"); | |
569 return -1; | |
570 } | |
571 } | |
572 ref_len = cook_up_msg(buf); | |
573 hdlc_tx_frame(&tx, buf, ref_len); | |
574 if ((corrupt = rand() & 1)) | |
575 hdlc_tx_corrupt_frame(&tx); | |
576 frame_handled = FALSE; | |
577 } | |
578 } | |
579 | |
580 printf("Tests passed.\n"); | |
581 return 0; | |
582 } | |
583 /*- End of function --------------------------------------------------------*/ | |
584 | |
585 static int test_hdlc_abort_handling(void) | |
586 { | |
587 int i; | |
588 int j; | |
589 int nextbyte; | |
590 int abort; | |
591 | |
592 printf("Testing abort handling using CRC-16 (bit by bit)\n"); | |
593 frame_len_errors = 0; | |
594 frame_data_errors = 0; | |
595 hdlc_tx_init(&tx, FALSE, 2, FALSE, underflow_handler, NULL); | |
596 hdlc_rx_init(&rx, FALSE, TRUE, 0, frame_handler, NULL); | |
597 underflow_reported = FALSE; | |
598 framing_ok_reported = FALSE; | |
599 framing_ok_reports = 0; | |
600 | |
601 hdlc_tx_flags(&tx, 10); | |
602 /* Don't push an initial message so we should get an underflow after the preamble. */ | |
603 /* Lie for the first message, as there isn't really one */ | |
604 frame_handled = TRUE; | |
605 frame_failed = FALSE; | |
606 frames_sent = 0; | |
607 bytes_sent = 0; | |
608 ref_len = 0; | |
609 abort = FALSE; | |
610 abort_reported = FALSE; | |
611 for (i = 0; i < 8*1000000; i++) | |
612 { | |
613 nextbyte = hdlc_tx_get_bit(&tx); | |
614 hdlc_rx_put_bit(&rx, nextbyte); | |
615 if (framing_ok_reported) | |
616 { | |
617 printf("Framing OK reported at bit %d (%d)\n", i, framing_ok_reports); | |
618 framing_ok_reported = FALSE; | |
619 } | |
620 if (underflow_reported) | |
621 { | |
622 underflow_reported = FALSE; | |
623 for (j = 0; j < 20; j++) | |
624 { | |
625 nextbyte = hdlc_tx_get_bit(&tx); | |
626 hdlc_rx_put_bit(&rx, nextbyte); | |
627 if (framing_ok_reported) | |
628 { | |
629 printf("Framing OK reported at bit %d (%d) - %d\n", i, framing_ok_reports, frame_handled); | |
630 framing_ok_reported = FALSE; | |
631 } | |
632 } | |
633 if (ref_len) | |
634 { | |
635 frames_sent++; | |
636 bytes_sent += ref_len; | |
637 } | |
638 if (abort) | |
639 { | |
640 if (abort && !abort_reported) | |
641 { | |
642 printf("Abort not received when sent\n"); | |
643 return -1; | |
644 } | |
645 if (frame_handled) | |
646 { | |
647 if (frame_failed) | |
648 printf("Frame failed.\n"); | |
649 printf("Frame received when abort sent.\n"); | |
650 return -1; | |
651 } | |
652 } | |
653 else | |
654 { | |
655 if (abort_reported) | |
656 { | |
657 printf("Abort received when not sent\n"); | |
658 return -1; | |
659 } | |
660 if (!frame_handled) | |
661 { | |
662 if (frame_failed) | |
663 printf("Frame failed.\n"); | |
664 printf("Frame not received.\n"); | |
665 return -1; | |
666 } | |
667 } | |
668 ref_len = cook_up_msg(buf); | |
669 hdlc_tx_frame(&tx, buf, ref_len); | |
670 if ((abort = rand() & 1)) | |
671 hdlc_tx_abort(&tx); | |
672 frame_handled = FALSE; | |
673 abort_reported = FALSE; | |
674 } | |
675 } | |
676 | |
677 printf("Tests passed.\n"); | |
678 return 0; | |
679 } | |
680 /*- End of function --------------------------------------------------------*/ | |
681 | |
682 #if 0 | |
683 static int test_hdlc_octet_count_handling(void) | |
684 { | |
685 int i; | |
686 int j; | |
687 int nextbyte; | |
688 | |
689 printf("Testing the octet_counting handling using CRC-16 (bit by bit)\n"); | |
690 frame_len_errors = 0; | |
691 frame_data_errors = 0; | |
692 hdlc_tx_init(&tx, FALSE, 2, FALSE, underflow_handler, NULL); | |
693 hdlc_rx_init(&rx, FALSE, TRUE, 0, frame_handler, NULL); | |
694 //hdlc_rx_set_max_frame_len(&rx, 50); | |
695 hdlc_rx_set_octet_counting_report_interval(&rx, 16); | |
696 underflow_reported = FALSE; | |
697 framing_ok_reported = FALSE; | |
698 framing_ok_reports = 0; | |
699 | |
700 hdlc_tx_flags(&tx, 10); | |
701 /* Don't push an initial message so we should get an underflow after the preamble. */ | |
702 /* Lie for the first message, as there isn't really one */ | |
703 frame_handled = TRUE; | |
704 frame_failed = FALSE; | |
705 frames_sent = 0; | |
706 bytes_sent = 0; | |
707 ref_len = 0; | |
708 for (i = 0; i < 8*1000000; i++) | |
709 { | |
710 nextbyte = hdlc_tx_get_bit(&tx); | |
711 hdlc_rx_put_bit(&rx, nextbyte); | |
712 if (framing_ok_reported) | |
713 { | |
714 printf("Framing OK reported at bit %d (%d)\n", i, framing_ok_reports); | |
715 framing_ok_reported = FALSE; | |
716 } | |
717 if (underflow_reported) | |
718 { | |
719 underflow_reported = FALSE; | |
720 for (j = 0; j < 20; j++) | |
721 { | |
722 nextbyte = hdlc_tx_get_bit(&tx); | |
723 hdlc_rx_put_bit(&rx, nextbyte); | |
724 if (framing_ok_reported) | |
725 { | |
726 printf("Framing OK reported at bit %d (%d) - %d\n", i, framing_ok_reports, frame_handled); | |
727 framing_ok_reported = FALSE; | |
728 } | |
729 } | |
730 if (ref_len) | |
731 { | |
732 frames_sent++; | |
733 bytes_sent += ref_len; | |
734 } | |
735 if (!frame_handled) | |
736 { | |
737 if (frame_failed) | |
738 printf("Frame failed.\n"); | |
739 printf("Frame not received.\n"); | |
740 return -1; | |
741 } | |
742 ref_len = cook_up_msg(buf); | |
743 hdlc_tx_frame(&tx, buf, ref_len); | |
744 hdlc_tx_abort(&tx); | |
745 //hdlc_tx_corrupt_frame(&tx); | |
746 frame_handled = FALSE; | |
747 } | |
748 } | |
749 | |
750 printf("Tests passed.\n"); | |
751 return 0; | |
752 } | |
753 /*- End of function --------------------------------------------------------*/ | |
754 #endif | |
755 | |
756 static void hdlc_tests(void) | |
757 { | |
758 printf("HDLC module tests\n"); | |
759 | |
760 if (test_hdlc_modes()) | |
761 { | |
762 printf("Tests failed\n"); | |
763 exit(2); | |
764 } | |
765 if (test_hdlc_frame_length_error_handling()) | |
766 { | |
767 printf("Tests failed\n"); | |
768 exit(2); | |
769 } | |
770 if (test_hdlc_crc_error_handling()) | |
771 { | |
772 printf("Tests failed\n"); | |
773 exit(2); | |
774 } | |
775 if (test_hdlc_abort_handling()) | |
776 { | |
777 printf("Tests failed\n"); | |
778 exit(2); | |
779 } | |
780 #if 0 | |
781 if (test_hdlc_octet_count_handling()) | |
782 { | |
783 printf("Tests failed\n"); | |
784 exit(2); | |
785 } | |
786 #endif | |
787 printf("Tests passed.\n"); | |
788 } | |
789 /*- End of function --------------------------------------------------------*/ | |
790 | |
791 static void decode_handler(void *user_data, const uint8_t *pkt, int len, int ok) | |
792 { | |
793 int i; | |
794 | |
795 if (len < 0) | |
796 { | |
797 /* Special conditions */ | |
798 printf("HDLC rx status is %s (%d)\n", signal_status_to_str(len), len); | |
799 return; | |
800 } | |
801 if (ok) | |
802 { | |
803 printf("Good frame, len = %d\n", len); | |
804 printf("HDLC: "); | |
805 for (i = 0; i < len; i++) | |
806 printf("%02X ", pkt[i]); | |
807 printf("\n"); | |
808 } | |
809 else | |
810 { | |
811 printf("Bad frame, len = %d\n", len); | |
812 } | |
813 } | |
814 /*- End of function --------------------------------------------------------*/ | |
815 | |
816 static void decode_bitstream(const char *in_file_name) | |
817 { | |
818 char buf[1024]; | |
819 int bit; | |
820 hdlc_rx_state_t rx; | |
821 FILE *in; | |
822 | |
823 if ((in = fopen(in_file_name, "r")) == NULL) | |
824 { | |
825 fprintf(stderr, "Failed to open '%s'\n", in_file_name); | |
826 exit(2); | |
827 } | |
828 | |
829 hdlc_rx_init(&rx, FALSE, TRUE, 2, decode_handler, NULL); | |
830 while (fgets(buf, 1024, in)) | |
831 { | |
832 if (sscanf(buf, "Rx bit %*d - %d", &bit) == 1) | |
833 { | |
834 hdlc_rx_put_bit(&rx, bit); | |
835 } | |
836 } | |
837 fclose(in); | |
838 } | |
839 /*- End of function --------------------------------------------------------*/ | |
840 | |
841 int main(int argc, char *argv[]) | |
842 { | |
843 int opt; | |
844 const char *in_file_name; | |
845 | |
846 in_file_name = NULL; | |
847 while ((opt = getopt(argc, argv, "d:")) != -1) | |
848 { | |
849 switch (opt) | |
850 { | |
851 case 'd': | |
852 in_file_name = optarg; | |
853 break; | |
854 default: | |
855 //usage(); | |
856 exit(2); | |
857 break; | |
858 } | |
859 } | |
860 if (in_file_name) | |
861 decode_bitstream(in_file_name); | |
862 else | |
863 hdlc_tests(); | |
864 return 0; | |
865 } | |
866 /*- End of function --------------------------------------------------------*/ | |
867 /*- End of file ------------------------------------------------------------*/ |