Mercurial > hg > audiostuff
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 ------------------------------------------------------------*/ |