comparison spandsp-0.0.3/spandsp-0.0.3/tests/hdlc_tests.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
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.30 2006/11/19 14:07:27 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 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include <stdio.h>
41 #include <inttypes.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #if defined(HAVE_TGMATH_H)
45 #include <tgmath.h>
46 #endif
47 #if defined(HAVE_MATH_H)
48 #include <math.h>
49 #endif
50 #include <tiffio.h>
51
52 #include "spandsp.h"
53
54 int ref_len;
55 uint8_t buf[1000];
56
57 int frame_handled;
58 int frame_len_errors;
59 int frame_data_errors;
60 int underflow_reported;
61
62 hdlc_rx_state_t rx;
63 hdlc_tx_state_t tx;
64
65 int frames_sent;
66 int bytes_sent;
67 uint64_t start;
68 uint64_t end;
69
70 /* Use a local random generator, so the results are consistent across platforms. We have hard coded
71 correct results for a message sequence generated by this particular PRNG. */
72 static int my_rand(void)
73 {
74 static int rndnum = 1234567;
75
76 return (rndnum = 1664525U*rndnum + 1013904223U) >> 8;
77 }
78 /*- End of function --------------------------------------------------------*/
79
80 static int cook_up_msg(uint8_t *buf)
81 {
82 int i;
83 int len;
84
85 /* Use medium length messages, with some randomised length variation. */
86 /* TODO: this doesn't exercise extremely short or long messages. */
87 len = (my_rand() & 0x3F) + 100;
88 for (i = 0; i < len; i++)
89 buf[i] = my_rand();
90 return len;
91 }
92 /*- End of function --------------------------------------------------------*/
93
94 static void frame_handler(void *user_data, int ok, const uint8_t *pkt, int len)
95 {
96 if (len < 0)
97 {
98 /* Special conditions */
99 switch (len)
100 {
101 case PUTBIT_TRAINING_FAILED:
102 printf("Training failed\n");
103 break;
104 case PUTBIT_TRAINING_SUCCEEDED:
105 printf("Training succeeded\n");
106 break;
107 case PUTBIT_CARRIER_UP:
108 printf("Carrier up\n");
109 break;
110 case PUTBIT_CARRIER_DOWN:
111 printf("Carrier down\n");
112 break;
113 case PUTBIT_FRAMING_OK:
114 //printf("Framing OK\n");
115 break;
116 case PUTBIT_ABORT:
117 printf("Abort\n");
118 break;
119 default:
120 printf("Eh!\n");
121 break;
122 }
123 return;
124 }
125 if (len != ref_len)
126 {
127 printf("Len error - %d %d\n", len, ref_len);
128 frame_len_errors++;
129 return;
130 }
131 if (memcmp(pkt, buf, len))
132 {
133 printf("Frame data error\n");
134 frame_data_errors++;
135 return;
136 }
137 frame_handled = TRUE;
138 }
139 /*- End of function --------------------------------------------------------*/
140
141 static void underflow_handler(void *user_data)
142 {
143 //printf("Underflow reported\n");
144 underflow_reported = TRUE;
145 }
146 /*- End of function --------------------------------------------------------*/
147
148 static void check_result(void)
149 {
150 hdlc_rx_stats_t rx_stats;
151
152 hdlc_rx_get_stats(&rx, &rx_stats);
153 printf("%lu bytes\n", rx_stats.bytes);
154 printf("%lu good frames\n", rx_stats.good_frames);
155 printf("%lu CRC errors\n", rx_stats.crc_errors);
156 printf("%lu length errors\n", rx_stats.length_errors);
157 printf("%lu aborts\n", rx_stats.aborts);
158 printf("%d frame length errors\n", frame_len_errors);
159 printf("%d frame data errors\n", frame_data_errors);
160 printf("Test duration %" PRIu64 " ticks\n", end - start);
161 if (rx_stats.bytes != bytes_sent
162 ||
163 rx_stats.good_frames != frames_sent
164 ||
165 rx_stats.crc_errors != 0
166 ||
167 rx_stats.length_errors != 0
168 ||
169 rx_stats.aborts != 0
170 ||
171 frame_len_errors != 0
172 ||
173 frame_data_errors != 0)
174 {
175 printf("Tests failed.\n");
176 exit(2);
177 }
178 printf("Test passed.\n\n");
179 }
180 /*- End of function --------------------------------------------------------*/
181
182 int main(int argc, char *argv[])
183 {
184 int i;
185 int j;
186 int len;
187 int nextbyte;
188 int progress;
189 int progress_delay;
190
191 printf("HDLC module tests\n");
192
193 /* Try a few random messages through the CRC logic. */
194 printf("Testing the CRC-16 routines\n");
195 for (i = 0; i < 100; i++)
196 {
197 ref_len = cook_up_msg(buf);
198 len = crc_itu16_append(buf, ref_len);
199 if (!crc_itu16_check(buf, len))
200 {
201 printf("CRC-16 failure\n");
202 exit(2);
203 }
204 }
205 printf("Test passed.\n\n");
206
207 printf("Testing the CRC-32 routines\n");
208 for (i = 0; i < 100; i++)
209 {
210 ref_len = cook_up_msg(buf);
211 len = crc_itu32_append(buf, ref_len);
212 if (!crc_itu32_check(buf, len))
213 {
214 printf("CRC-32 failure\n");
215 exit(2);
216 }
217 }
218 printf("Test passed.\n\n");
219
220 /* Now try sending HDLC messages with CRC-16 */
221 printf("Testing with CRC-16 (byte by byte)\n");
222 frame_len_errors = 0;
223 frame_data_errors = 0;
224 hdlc_tx_init(&tx, FALSE, 1, FALSE, underflow_handler, NULL);
225 hdlc_rx_init(&rx, FALSE, FALSE, 5, frame_handler, NULL);
226 underflow_reported = FALSE;
227
228 start = rdtscll();
229 hdlc_tx_preamble(&tx, 40);
230 /* Push an initial message so we should NOT get an underflow after the preamble. */
231 ref_len = cook_up_msg(buf);
232 hdlc_tx_frame(&tx, buf, ref_len);
233 frame_handled = FALSE;
234 frames_sent = 0;
235 bytes_sent = 0;
236 for (i = 0; i < 1000000; i++)
237 {
238 nextbyte = hdlc_tx_get_byte(&tx);
239 hdlc_rx_put_byte(&rx, nextbyte);
240 if (underflow_reported)
241 {
242 underflow_reported = FALSE;
243 nextbyte = hdlc_tx_get_byte(&tx);
244 hdlc_rx_put_byte(&rx, nextbyte);
245 frames_sent++;
246 bytes_sent += ref_len;
247 if (!frame_handled)
248 {
249 printf("Frame not received.\n");
250 printf("Tests failed.\n");
251 exit(2);
252 }
253 ref_len = cook_up_msg(buf);
254 hdlc_tx_frame(&tx, buf, ref_len);
255 frame_handled = FALSE;
256 }
257 }
258 end = rdtscll();
259 check_result();
260
261 /* Now try sending HDLC messages with CRC-16 bit by bit */
262 printf("Testing with CRC-16 (bit by bit)\n");
263 frame_len_errors = 0;
264 frame_data_errors = 0;
265 hdlc_tx_init(&tx, FALSE, 2, FALSE, underflow_handler, NULL);
266 hdlc_rx_init(&rx, FALSE, FALSE, 5, frame_handler, NULL);
267 underflow_reported = FALSE;
268
269 start = rdtscll();
270 hdlc_tx_preamble(&tx, 40);
271 /* Don't push an initial message so we should get an underflow after the preamble. */
272 /* Lie for the first message, as there isn't really one */
273 frame_handled = TRUE;
274 frames_sent = 0;
275 bytes_sent = 0;
276 ref_len = 0;
277 for (i = 0; i < 8*1000000; i++)
278 {
279 nextbyte = hdlc_tx_get_bit(&tx);
280 hdlc_rx_put_bit(&rx, nextbyte);
281 if (underflow_reported)
282 {
283 underflow_reported = FALSE;
284 for (j = 0; j < 20; j++)
285 {
286 nextbyte = hdlc_tx_get_bit(&tx);
287 hdlc_rx_put_bit(&rx, nextbyte);
288 }
289 if (ref_len)
290 {
291 frames_sent++;
292 bytes_sent += ref_len;
293 }
294 if (!frame_handled)
295 {
296 printf("Frame not received.\n");
297 printf("Tests failed.\n");
298 exit(2);
299 }
300 ref_len = cook_up_msg(buf);
301 hdlc_tx_frame(&tx, buf, ref_len);
302 frame_handled = FALSE;
303 }
304 }
305 end = rdtscll();
306 check_result();
307
308 /* Now try sending HDLC messages with CRC-32 */
309 printf("Testing with CRC-32 (byte by byte)\n");
310 frame_len_errors = 0;
311 frame_data_errors = 0;
312 hdlc_tx_init(&tx, TRUE, 1, FALSE, underflow_handler, NULL);
313 hdlc_rx_init(&rx, TRUE, FALSE, 1, frame_handler, NULL);
314 underflow_reported = FALSE;
315
316 start = rdtscll();
317 hdlc_tx_preamble(&tx, 40);
318 /* Don't push an initial message so we should get an underflow after the preamble. */
319 /* Lie for the first message, as there isn't really one */
320 frame_handled = TRUE;
321 frames_sent = 0;
322 bytes_sent = 0;
323 ref_len = 0;
324 for (i = 0; i < 1000000; i++)
325 {
326 nextbyte = hdlc_tx_get_byte(&tx);
327 hdlc_rx_put_byte(&rx, nextbyte);
328 if (underflow_reported)
329 {
330 underflow_reported = FALSE;
331 nextbyte = hdlc_tx_get_byte(&tx);
332 hdlc_rx_put_byte(&rx, nextbyte);
333 if (ref_len)
334 {
335 frames_sent++;
336 bytes_sent += ref_len;
337 }
338 if (!frame_handled)
339 {
340 printf("Frame not received.\n");
341 printf("Tests failed.\n");
342 exit(2);
343 }
344 ref_len = cook_up_msg(buf);
345 hdlc_tx_frame(&tx, buf, ref_len);
346 frame_handled = FALSE;
347 }
348 }
349 end = rdtscll();
350 check_result();
351
352 /* Now try progressive mode with CRC-16 */
353 printf("Testing progressive mode with CRC-16 (byte by byte)\n");
354 frame_len_errors = 0;
355 frame_data_errors = 0;
356 hdlc_tx_init(&tx, TRUE, 1, TRUE, underflow_handler, NULL);
357 hdlc_rx_init(&rx, TRUE, FALSE, 1, frame_handler, NULL);
358 underflow_reported = FALSE;
359
360 start = rdtscll();
361 hdlc_tx_preamble(&tx, 40);
362 /* Don't push an initial message so we should get an underflow after the preamble. */
363 /* Lie for the first message, as there isn't really one */
364 frame_handled = TRUE;
365 progress = 9999;
366 progress_delay = 9999;
367 frames_sent = 0;
368 bytes_sent = 0;
369 ref_len = 0;
370 for (i = 0; i < 1000000; i++)
371 {
372 nextbyte = hdlc_tx_get_byte(&tx);
373 hdlc_rx_put_byte(&rx, nextbyte);
374 if (underflow_reported)
375 {
376 underflow_reported = FALSE;
377 nextbyte = hdlc_tx_get_byte(&tx);
378 hdlc_rx_put_byte(&rx, nextbyte);
379 if (ref_len)
380 {
381 frames_sent++;
382 bytes_sent += ref_len;
383 }
384 if (!frame_handled)
385 {
386 printf("Frame not received.\n");
387 printf("Tests failed.\n");
388 exit(2);
389 }
390 ref_len = cook_up_msg(buf);
391 hdlc_tx_frame(&tx, buf, 10);
392 progress = 10;
393 progress_delay = 8;
394 frame_handled = FALSE;
395 }
396 if (progress < ref_len && progress_delay-- <= 0)
397 {
398 if (hdlc_tx_frame(&tx, buf + progress, (progress + 10 <= ref_len) ? 10 : ref_len - progress) < 0)
399 {
400 printf("Failed to add progressively\n");
401 exit(2);
402 }
403 progress += 10;
404 progress_delay = 8;
405 }
406 }
407 end = rdtscll();
408 check_result();
409
410 printf("Tests passed.\n");
411 return 0;
412 }
413 /*- End of function --------------------------------------------------------*/
414 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.