comparison spandsp-0.0.6pre17/tests/tsb85_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 * tsb85_tests.c
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2008 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 Lesser General Public License version 2.1,
14 * as 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 Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: tsb85_tests.c,v 1.32 2009/05/30 15:23:14 steveu Exp $
26 */
27
28 /*! \file */
29
30 #if defined(HAVE_CONFIG_H)
31 #include <config.h>
32 #endif
33
34 #include <inttypes.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #if defined(HAVE_TGMATH_H)
40 #include <tgmath.h>
41 #endif
42 #if defined(HAVE_MATH_H)
43 #include <math.h>
44 #endif
45 #include "floating_fudge.h"
46 #include <assert.h>
47 #include <fcntl.h>
48 #include <time.h>
49 #include <unistd.h>
50 #include <sndfile.h>
51
52 #if defined(HAVE_LIBXML_XMLMEMORY_H)
53 #include <libxml/xmlmemory.h>
54 #endif
55 #if defined(HAVE_LIBXML_PARSER_H)
56 #include <libxml/parser.h>
57 #endif
58 #if defined(HAVE_LIBXML_XINCLUDE_H)
59 #include <libxml/xinclude.h>
60 #endif
61
62 //#if defined(WITH_SPANDSP_INTERNALS)
63 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
64 //#endif
65
66 #include "spandsp.h"
67 #include "spandsp-sim.h"
68
69 #include "fax_tester.h"
70 #include "fax_utils.h"
71
72 #define OUTPUT_TIFF_FILE_NAME "tsb85.tif"
73
74 #define OUTPUT_FILE_NAME_WAVE "tsb85.wav"
75
76 #define SAMPLES_PER_CHUNK 160
77
78 SNDFILE *out_handle;
79
80 int use_receiver_not_ready = FALSE;
81 int test_local_interrupt = FALSE;
82
83 const char *output_tiff_file_name;
84
85 fax_state_t *fax;
86 faxtester_state_t state;
87
88 uint8_t image[1000000];
89
90 uint8_t awaited[1000];
91 int awaited_len = 0;
92
93 char image_path[1024];
94
95 t30_exchanged_info_t expected_rx_info;
96
97 char next_tx_file[1000];
98
99 static int next_step(faxtester_state_t *s);
100
101 static int phase_b_handler(t30_state_t *s, void *user_data, int result)
102 {
103 int i;
104 int status;
105 const char *u;
106
107 i = (intptr_t) user_data;
108 status = T30_ERR_OK;
109 if ((u = t30_get_rx_ident(s)))
110 {
111 printf("%c: Phase B: remote ident '%s'\n", i, u);
112 if (expected_rx_info.ident[0] && strcmp(expected_rx_info.ident, u))
113 {
114 printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", i, expected_rx_info.ident);
115 status = T30_ERR_IDENT_UNACCEPTABLE;
116 }
117 }
118 else
119 {
120 if (expected_rx_info.ident[0])
121 {
122 printf("%c: Phase B: remote ident missing!\n", i);
123 status = T30_ERR_IDENT_UNACCEPTABLE;
124 }
125 }
126 if ((u = t30_get_rx_sub_address(s)))
127 {
128 printf("%c: Phase B: remote sub-address '%s'\n", i, u);
129 if (expected_rx_info.sub_address[0] && strcmp(expected_rx_info.sub_address, u))
130 {
131 printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", i, expected_rx_info.sub_address);
132 status = T30_ERR_SUB_UNACCEPTABLE;
133 }
134 }
135 else
136 {
137 if (expected_rx_info.sub_address[0])
138 {
139 printf("%c: Phase B: remote sub-address missing!\n", i);
140 status = T30_ERR_SUB_UNACCEPTABLE;
141 }
142 }
143 if ((u = t30_get_rx_polled_sub_address(s)))
144 {
145 printf("%c: Phase B: remote polled sub-address '%s'\n", i, u);
146 if (expected_rx_info.polled_sub_address[0] && strcmp(expected_rx_info.polled_sub_address, u))
147 {
148 printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", i, expected_rx_info.polled_sub_address);
149 status = T30_ERR_PSA_UNACCEPTABLE;
150 }
151 }
152 else
153 {
154 if (expected_rx_info.polled_sub_address[0])
155 {
156 printf("%c: Phase B: remote polled sub-address missing!\n", i);
157 status = T30_ERR_PSA_UNACCEPTABLE;
158 }
159 }
160 if ((u = t30_get_rx_selective_polling_address(s)))
161 {
162 printf("%c: Phase B: remote selective polling address '%s'\n", i, u);
163 if (expected_rx_info.selective_polling_address[0] && strcmp(expected_rx_info.selective_polling_address, u))
164 {
165 printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", i, expected_rx_info.selective_polling_address);
166 status = T30_ERR_SEP_UNACCEPTABLE;
167 }
168 }
169 else
170 {
171 if (expected_rx_info.selective_polling_address[0])
172 {
173 printf("%c: Phase B: remote selective polling address missing!\n", i);
174 status = T30_ERR_SEP_UNACCEPTABLE;
175 }
176 }
177 if ((u = t30_get_rx_sender_ident(s)))
178 {
179 printf("%c: Phase B: remote sender ident '%s'\n", i, u);
180 if (expected_rx_info.sender_ident[0] && strcmp(expected_rx_info.sender_ident, u))
181 {
182 printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", i, expected_rx_info.sender_ident);
183 status = T30_ERR_SID_UNACCEPTABLE;
184 }
185 }
186 else
187 {
188 if (expected_rx_info.sender_ident[0])
189 {
190 printf("%c: Phase B: remote sender ident missing!\n", i);
191 status = T30_ERR_SID_UNACCEPTABLE;
192 }
193 }
194 if ((u = t30_get_rx_password(s)))
195 {
196 printf("%c: Phase B: remote password '%s'\n", i, u);
197 if (expected_rx_info.password[0] && strcmp(expected_rx_info.password, u))
198 {
199 printf("%c: Phase B: remote password incorrect! - expected '%s'\n", i, expected_rx_info.password);
200 status = T30_ERR_PWD_UNACCEPTABLE;
201 }
202 }
203 else
204 {
205 if (expected_rx_info.password[0])
206 {
207 printf("%c: Phase B: remote password missing!\n", i);
208 status = T30_ERR_PWD_UNACCEPTABLE;
209 }
210 }
211 printf("%c: Phase B handler on channel %d - (0x%X) %s\n", i, i, result, t30_frametype(result));
212 return status;
213 }
214 /*- End of function --------------------------------------------------------*/
215
216 static int phase_d_handler(t30_state_t *s, void *user_data, int result)
217 {
218 int i;
219 char tag[20];
220
221 i = (intptr_t) user_data;
222 snprintf(tag, sizeof(tag), "%c: Phase D:", i);
223
224 printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
225 log_transfer_statistics(s, tag);
226 log_tx_parameters(s, tag);
227 log_rx_parameters(s, tag);
228
229 if (use_receiver_not_ready)
230 t30_set_receiver_not_ready(s, 3);
231
232 if (test_local_interrupt)
233 {
234 if (i == 'A')
235 {
236 printf("%c: Initiating interrupt request\n", i);
237 t30_local_interrupt_request(s, TRUE);
238 }
239 else
240 {
241 switch (result)
242 {
243 case T30_PIP:
244 case T30_PRI_MPS:
245 case T30_PRI_EOM:
246 case T30_PRI_EOP:
247 printf("%c: Accepting interrupt request\n", i);
248 t30_local_interrupt_request(s, TRUE);
249 break;
250 case T30_PIN:
251 break;
252 }
253 }
254 }
255 return T30_ERR_OK;
256 }
257 /*- End of function --------------------------------------------------------*/
258
259 static void phase_e_handler(t30_state_t *s, void *user_data, int result)
260 {
261 int i;
262 char tag[20];
263
264 i = (intptr_t) user_data;
265 snprintf(tag, sizeof(tag), "%c: Phase E:", i);
266 printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
267 log_transfer_statistics(s, tag);
268 log_tx_parameters(s, tag);
269 log_rx_parameters(s, tag);
270 }
271 /*- End of function --------------------------------------------------------*/
272
273 static void t30_real_time_frame_handler(t30_state_t *s,
274 void *user_data,
275 int direction,
276 const uint8_t *msg,
277 int len)
278 {
279 if (msg == NULL)
280 {
281 }
282 else
283 {
284 fprintf(stderr,
285 "T.30: Real time frame handler - %s, %s, length = %d\n",
286 (direction) ? "line->T.30" : "T.30->line",
287 t30_frametype(msg[2]),
288 len);
289 }
290 }
291 /*- End of function --------------------------------------------------------*/
292
293 static int document_handler(t30_state_t *s, void *user_data, int event)
294 {
295 int i;
296
297 i = (intptr_t) user_data;
298 fprintf(stderr, "%d: Document handler on channel %d - event %d\n", i, i, event);
299 if (next_tx_file[0])
300 {
301 t30_set_tx_file(s, next_tx_file, -1, -1);
302 next_tx_file[0] = '\0';
303 return TRUE;
304 }
305 return FALSE;
306 }
307 /*- End of function --------------------------------------------------------*/
308
309 static void faxtester_real_time_frame_handler(faxtester_state_t *s,
310 void *user_data,
311 int direction,
312 const uint8_t *msg,
313 int len)
314 {
315 if (msg == NULL)
316 {
317 while (next_step(s) == 0)
318 ;
319 /*endwhile*/
320 }
321 else
322 {
323 fprintf(stderr,
324 "TST: Real time frame handler - %s, %s, length = %d\n",
325 (direction) ? "line->tester" : "tester->line",
326 t30_frametype(msg[2]),
327 len);
328 if (direction && msg[1] == awaited[1])
329 {
330 if ((awaited_len >= 0 && len != abs(awaited_len))
331 ||
332 (awaited_len < 0 && len < abs(awaited_len))
333 ||
334 memcmp(msg, awaited, abs(awaited_len)) != 0)
335 {
336 span_log_buf(&s->logging, SPAN_LOG_FLOW, "Expected", awaited, abs(awaited_len));
337 span_log_buf(&s->logging, SPAN_LOG_FLOW, "Received", msg, len);
338 printf("Test failed\n");
339 exit(2);
340 }
341 }
342 if (msg[1] == awaited[1])
343 {
344 while (next_step(s) == 0)
345 ;
346 /*endwhile*/
347 }
348 }
349 }
350 /*- End of function --------------------------------------------------------*/
351
352 static void faxtester_front_end_step_complete_handler(faxtester_state_t *s, void *user_data)
353 {
354 while (next_step(s) == 0)
355 ;
356 /*endwhile*/
357 }
358 /*- End of function --------------------------------------------------------*/
359
360 static void faxtester_front_end_step_timeout_handler(faxtester_state_t *s, void *user_data)
361 {
362 span_log(&s->logging, SPAN_LOG_FLOW, "FAX tester step timed out\n");
363 printf("Test failed\n");
364 exit(2);
365 }
366 /*- End of function --------------------------------------------------------*/
367
368 static void fax_prepare(void)
369 {
370 t30_state_t *t30;
371 logging_state_t *logging;
372
373 t30 = fax_get_t30_state(fax);
374 fax_set_transmit_on_idle(fax, TRUE);
375 fax_set_tep_mode(fax, TRUE);
376 #if 0
377 t30_set_tx_ident(t30, "1234567890");
378 t30_set_tx_sub_address(t30, "Sub-address");
379 t30_set_tx_sender_ident(t30, "Sender ID");
380 t30_set_tx_password(t30, "Password");
381 t30_set_tx_polled_sub_address(t30, "Polled sub-address");
382 t30_set_tx_selective_polling_address(t30, "Sel polling address");
383 #endif
384 t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSF\x00", 16);
385 //t30_set_tx_nss(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSS\x00", 16);
386 t30_set_tx_nsc(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSC\x00", 16);
387 t30_set_ecm_capability(t30, TRUE);
388 t30_set_supported_t30_features(t30,
389 T30_SUPPORT_IDENTIFICATION
390 | T30_SUPPORT_SELECTIVE_POLLING
391 | T30_SUPPORT_SUB_ADDRESSING);
392 t30_set_supported_image_sizes(t30,
393 T30_SUPPORT_US_LETTER_LENGTH
394 | T30_SUPPORT_US_LEGAL_LENGTH
395 | T30_SUPPORT_UNLIMITED_LENGTH
396 | T30_SUPPORT_215MM_WIDTH
397 | T30_SUPPORT_255MM_WIDTH
398 | T30_SUPPORT_303MM_WIDTH);
399 t30_set_supported_resolutions(t30,
400 T30_SUPPORT_STANDARD_RESOLUTION
401 | T30_SUPPORT_FINE_RESOLUTION
402 | T30_SUPPORT_SUPERFINE_RESOLUTION
403 | T30_SUPPORT_R8_RESOLUTION
404 | T30_SUPPORT_R16_RESOLUTION
405 | T30_SUPPORT_300_300_RESOLUTION
406 | T30_SUPPORT_400_400_RESOLUTION
407 | T30_SUPPORT_600_600_RESOLUTION
408 | T30_SUPPORT_1200_1200_RESOLUTION
409 | T30_SUPPORT_300_600_RESOLUTION
410 | T30_SUPPORT_400_800_RESOLUTION
411 | T30_SUPPORT_600_1200_RESOLUTION);
412 t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
413 t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
414 t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A');
415 t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A');
416 t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A');
417 t30_set_real_time_frame_handler(t30, t30_real_time_frame_handler, (void *) (intptr_t) 'A');
418 t30_set_document_handler(t30, document_handler, (void *) (intptr_t) 'A');
419
420 logging = fax_get_logging_state(fax);
421 span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
422 span_log_set_tag(logging, "A");
423
424 logging = t30_get_logging_state(t30);
425 span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
426 span_log_set_tag(logging, "A");
427
428 #if 0
429 span_log_set_level(&fax.modems.v27ter_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
430 span_log_set_tag(&fax.modems.v27ter_rx.logging, "A");
431 span_log_set_level(&fax.modems.v29_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
432 span_log_set_tag(&fax.modems.v29_rx.logging, "A");
433 span_log_set_level(&fax.modems.v17_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
434 span_log_set_tag(&fax.modems.v17_rx.logging, "A");
435 #endif
436 }
437 /*- End of function --------------------------------------------------------*/
438
439 static int string_to_msg(uint8_t msg[], uint8_t mask[], const char buf[])
440 {
441 int i;
442 int x;
443 const char *t;
444
445 msg[0] = 0;
446 mask[0] = 0xFF;
447 i = 0;
448 t = (char *) buf;
449 while (*t)
450 {
451 /* Skip white space */
452 while (isspace(*t))
453 t++;
454 /* If we find ... we allow arbitrary addition info beyond this point in the message */
455 if (t[0] == '.' && t[1] == '.' && t[2] == '.')
456 {
457 return -i;
458 }
459 else if (isxdigit(*t))
460 {
461 for ( ; isxdigit(*t); t++)
462 {
463 x = *t;
464 if (x >= 'a')
465 x -= 0x20;
466 if (x >= 'A')
467 x -= ('A' - 10);
468 else
469 x -= '0';
470 msg[i] = (msg[i] << 4) | x;
471 }
472 mask[i] = 0xFF;
473 if (*t == '/')
474 {
475 /* There is a mask following the byte */
476 mask[i] = 0;
477 for (t++; isxdigit(*t); t++)
478 {
479 x = *t;
480 if (x >= 'a')
481 x -= 0x20;
482 if (x >= 'A')
483 x -= ('A' - 10);
484 else
485 x -= '0';
486 mask[i] = (mask[i] << 4) | x;
487 }
488 }
489 if (*t && !isspace(*t))
490 {
491 /* Bad string */
492 return 0;
493 }
494 i++;
495 }
496 }
497 return i;
498 }
499 /*- End of function --------------------------------------------------------*/
500
501 #if 0
502 static void string_test2(const uint8_t msg[], int len)
503 {
504 int i;
505
506 if (len > 0)
507 {
508 for (i = 0; i < len - 1; i++)
509 printf("%02X ", msg[i]);
510 printf("%02X", msg[i]);
511 }
512 }
513 /*- End of function --------------------------------------------------------*/
514
515 static void string_test3(const char buf[])
516 {
517 uint8_t msg[1000];
518 uint8_t mask[1000];
519 int len;
520 int i;
521
522 len = string_to_msg(msg, mask, buf);
523 printf("Len = %d: ", len);
524 string_test2(msg, abs(len));
525 printf("/");
526 string_test2(mask, abs(len));
527 printf("\n");
528 }
529 /*- End of function --------------------------------------------------------*/
530
531 static int string_test(void)
532 {
533 string_test3("FF C8 12 34 56 78");
534 string_test3("FF C8 12/55 34 56/aA 78 ");
535 string_test3("FF C8 12/55 34 56/aA 78 ...");
536 string_test3("FF C8 12/55 34 56/aA 78...");
537 string_test3("FF C8 12/55 34 56/aA 78 ... 99 88 77");
538 exit(0);
539 }
540 /*- End of function --------------------------------------------------------*/
541 #endif
542
543 static void corrupt_image(faxtester_state_t *s, uint8_t image[], int len, const char *bad_rows)
544 {
545 int i;
546 int j;
547 int k;
548 uint32_t bits;
549 uint32_t bitsx;
550 int list[1000];
551 int x;
552 int row;
553 const char *t;
554
555 /* Form the list of rows to be hit */
556 x = 0;
557 t = bad_rows;
558 while (*t)
559 {
560 while (isspace(*t))
561 t++;
562 if (sscanf(t, "%d", &list[x]) < 1)
563 break;
564 x++;
565 while (isdigit(*t))
566 t++;
567 if (*t == ',')
568 t++;
569 }
570
571 /* Go through the image, and corrupt the first bit of every listed row */
572 bits = 0x7FF;
573 bitsx = 0x7FF;
574 row = 0;
575 for (i = 0; i < len; i++)
576 {
577 bits ^= (image[i] << 11);
578 bitsx ^= (image[i] << 11);
579 for (j = 0; j < 8; j++)
580 {
581 if ((bits & 0xFFF) == 0x800)
582 {
583 /* We are at an EOL. Is this row in the list of rows to be corrupted? */
584 row++;
585 for (k = 0; k < x; k++)
586 {
587 if (list[k] == row)
588 {
589 /* Corrupt this row. TSB85 says to hit the first bit after the EOL */
590 bitsx ^= 0x1000;
591 }
592 }
593 }
594 bits >>= 1;
595 bitsx >>= 1;
596 }
597 image[i] = (bitsx >> 3) & 0xFF;
598 }
599 span_log(&s->logging, SPAN_LOG_FLOW, "%d rows found. %d corrupted\n", row, x);
600 }
601 /*- End of function --------------------------------------------------------*/
602
603 static int next_step(faxtester_state_t *s)
604 {
605 int delay;
606 int flags;
607 xmlChar *dir;
608 xmlChar *type;
609 xmlChar *modem;
610 xmlChar *value;
611 xmlChar *tag;
612 xmlChar *bad_rows;
613 xmlChar *crc_error;
614 xmlChar *pattern;
615 xmlChar *timeout;
616 xmlChar *min_bits;
617 xmlChar *frame_size;
618 xmlChar *block;
619 xmlChar *compression;
620 uint8_t buf[1000];
621 uint8_t mask[1000];
622 char path[1024];
623 int i;
624 int j;
625 int hdlc;
626 int short_train;
627 int min_row_bits;
628 int ecm_frame_size;
629 int ecm_block;
630 int compression_type;
631 int timer;
632 int len;
633 t4_state_t t4_state;
634 t30_state_t *t30;
635
636 if (s->cur == NULL)
637 {
638 if (!s->final_delayed)
639 {
640 /* Add a bit of waiting at the end, to ensure everything gets flushed through,
641 any timers can expire, etc. */
642 faxtester_set_timeout(s, -1);
643 faxtester_set_rx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
644 faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, 120000, FALSE);
645 s->final_delayed = TRUE;
646 return 1;
647 }
648 /* Finished */
649 printf("Test passed\n");
650 exit(0);
651 }
652 while (s->cur && xmlStrcmp(s->cur->name, (const xmlChar *) "step") != 0)
653 s->cur = s->cur->next;
654 if (s->cur == NULL)
655 {
656 /* Finished */
657 printf("Test passed\n");
658 exit(0);
659 }
660
661 dir = xmlGetProp(s->cur, (const xmlChar *) "dir");
662 type = xmlGetProp(s->cur, (const xmlChar *) "type");
663 modem = xmlGetProp(s->cur, (const xmlChar *) "modem");
664 value = xmlGetProp(s->cur, (const xmlChar *) "value");
665 tag = xmlGetProp(s->cur, (const xmlChar *) "tag");
666 bad_rows = xmlGetProp(s->cur, (const xmlChar *) "bad_rows");
667 crc_error = xmlGetProp(s->cur, (const xmlChar *) "crc_error");
668 pattern = xmlGetProp(s->cur, (const xmlChar *) "pattern");
669 timeout = xmlGetProp(s->cur, (const xmlChar *) "timeout");
670 min_bits = xmlGetProp(s->cur, (const xmlChar *) "min_bits");
671 frame_size = xmlGetProp(s->cur, (const xmlChar *) "frame_size");
672 block = xmlGetProp(s->cur, (const xmlChar *) "block");
673 compression = xmlGetProp(s->cur, (const xmlChar *) "compression");
674
675 s->cur = s->cur->next;
676
677 span_log(&s->logging,
678 SPAN_LOG_FLOW,
679 "Dir - %s, type - %s, modem - %s, value - %s, timeout - %s, tag - %s\n",
680 (dir) ? (const char *) dir : "",
681 (type) ? (const char *) type : "",
682 (modem) ? (const char *) modem : "",
683 (value) ? (const char *) value : "",
684 (timeout) ? (const char *) timeout : "",
685 (tag) ? (const char *) tag : "");
686 if (type == NULL)
687 return 1;
688 if (timeout)
689 timer = atoi((const char *) timeout);
690 else
691 timer = -1;
692
693 if (dir && strcasecmp((const char *) dir, "R") == 0)
694 {
695 /* Receive always has a timeout applied. */
696 if (timer < 0)
697 timer = 7000;
698 faxtester_set_timeout(s, timer);
699 if (modem)
700 {
701 hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0);
702 short_train = (strcasecmp((const char *) type, "TCF") != 0);
703 faxtester_set_tx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
704 if (strcasecmp((const char *) modem, "V.21") == 0)
705 {
706 faxtester_set_rx_type(s, T30_MODEM_V21, 300, FALSE, TRUE);
707 }
708 else if (strcasecmp((const char *) modem, "V.17/14400") == 0)
709 {
710 faxtester_set_rx_type(s, T30_MODEM_V17, 14400, short_train, hdlc);
711 }
712 else if (strcasecmp((const char *) modem, "V.17/12000") == 0)
713 {
714 faxtester_set_rx_type(s, T30_MODEM_V17, 12000, short_train, hdlc);
715 }
716 else if (strcasecmp((const char *) modem, "V.17/9600") == 0)
717 {
718 faxtester_set_rx_type(s, T30_MODEM_V17, 9600, short_train, hdlc);
719 }
720 else if (strcasecmp((const char *) modem, "V.17/7200") == 0)
721 {
722 faxtester_set_rx_type(s, T30_MODEM_V17, 7200, short_train, hdlc);
723 }
724 else if (strcasecmp((const char *) modem, "V.29/9600") == 0)
725 {
726 faxtester_set_rx_type(s, T30_MODEM_V29, 9600, FALSE, hdlc);
727 }
728 else if (strcasecmp((const char *) modem, "V.29/7200") == 0)
729 {
730 faxtester_set_rx_type(s, T30_MODEM_V29, 7200, FALSE, hdlc);
731 }
732 else if (strcasecmp((const char *) modem, "V.27ter/4800") == 0)
733 {
734 faxtester_set_rx_type(s, T30_MODEM_V27TER, 4800, FALSE, hdlc);
735 }
736 else if (strcasecmp((const char *) modem, "V.27ter/2400") == 0)
737 {
738 faxtester_set_rx_type(s, T30_MODEM_V27TER, 2400, FALSE, hdlc);
739 }
740 else
741 {
742 span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n");
743 }
744 }
745
746 if (strcasecmp((const char *) type, "SET") == 0)
747 {
748 if (strcasecmp((const char *) tag, "IDENT") == 0)
749 strcpy(expected_rx_info.ident, (const char *) value);
750 else if (strcasecmp((const char *) tag, "SUB") == 0)
751 strcpy(expected_rx_info.sub_address, (const char *) value);
752 else if (strcasecmp((const char *) tag, "SEP") == 0)
753 strcpy(expected_rx_info.selective_polling_address, (const char *) value);
754 else if (strcasecmp((const char *) tag, "PSA") == 0)
755 strcpy(expected_rx_info.polled_sub_address, (const char *) value);
756 else if (strcasecmp((const char *) tag, "SID") == 0)
757 strcpy(expected_rx_info.sender_ident, (const char *) value);
758 else if (strcasecmp((const char *) tag, "PWD") == 0)
759 strcpy(expected_rx_info.password, (const char *) value);
760 return 0;
761 }
762 else if (strcasecmp((const char *) type, "CNG") == 0)
763 {
764 /* Look for CNG */
765 faxtester_set_rx_type(s, T30_MODEM_CNG, 0, FALSE, FALSE);
766 faxtester_set_tx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
767 }
768 else if (strcasecmp((const char *) type, "CED") == 0)
769 {
770 /* Look for CED */
771 faxtester_set_rx_type(s, T30_MODEM_CED, 0, FALSE, FALSE);
772 faxtester_set_tx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
773 }
774 else if (strcasecmp((const char *) type, "HDLC") == 0)
775 {
776 i = string_to_msg(buf, mask, (const char *) value);
777 bit_reverse(awaited, buf, abs(i));
778 awaited_len = i;
779 }
780 else if (strcasecmp((const char *) type, "TCF") == 0)
781 {
782 }
783 else if (strcasecmp((const char *) type, "MSG") == 0)
784 {
785 }
786 else if (strcasecmp((const char *) type, "PP") == 0)
787 {
788 }
789 else if (strcasecmp((const char *) type, "SILENCE") == 0)
790 {
791 faxtest_set_rx_silence(s);
792 }
793 else
794 {
795 span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised type '%s'\n", (const char *) type);
796 return 0;
797 }
798 }
799 else
800 {
801 faxtester_set_timeout(s, timer);
802 if (modem)
803 {
804 hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0);
805 short_train = (strcasecmp((const char *) type, "TCF") != 0);
806 faxtester_set_rx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
807 if (strcasecmp((const char *) modem, "V.21") == 0)
808 {
809 faxtester_set_tx_type(s, T30_MODEM_V21, 300, FALSE, TRUE);
810 }
811 else if (strcasecmp((const char *) modem, "V.17/14400") == 0)
812 {
813 faxtester_set_tx_type(s, T30_MODEM_V17, 14400, short_train, hdlc);
814 }
815 else if (strcasecmp((const char *) modem, "V.17/12000") == 0)
816 {
817 faxtester_set_tx_type(s, T30_MODEM_V17, 12000, short_train, hdlc);
818 }
819 else if (strcasecmp((const char *) modem, "V.17/9600") == 0)
820 {
821 faxtester_set_tx_type(s, T30_MODEM_V17, 9600, short_train, hdlc);
822 }
823 else if (strcasecmp((const char *) modem, "V.17/7200") == 0)
824 {
825 faxtester_set_tx_type(s, T30_MODEM_V17, 7200, short_train, hdlc);
826 }
827 else if (strcasecmp((const char *) modem, "V.29/9600") == 0)
828 {
829 faxtester_set_tx_type(s, T30_MODEM_V29, 9600, FALSE, hdlc);
830 }
831 else if (strcasecmp((const char *) modem, "V.29/7200") == 0)
832 {
833 faxtester_set_tx_type(s, T30_MODEM_V29, 7200, FALSE, hdlc);
834 }
835 else if (strcasecmp((const char *) modem, "V.27ter/4800") == 0)
836 {
837 faxtester_set_tx_type(s, T30_MODEM_V27TER, 4800, FALSE, hdlc);
838 }
839 else if (strcasecmp((const char *) modem, "V.27ter/2400") == 0)
840 {
841 faxtester_set_tx_type(s, T30_MODEM_V27TER, 2400, FALSE, hdlc);
842 }
843 else
844 {
845 span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n");
846 }
847 }
848
849 if (strcasecmp((const char *) type, "SET") == 0)
850 {
851 t30 = fax_get_t30_state(fax);
852 if (strcasecmp((const char *) tag, "IDENT") == 0)
853 t30_set_tx_ident(t30, (const char *) value);
854 else if (strcasecmp((const char *) tag, "SUB") == 0)
855 t30_set_tx_sub_address(t30, (const char *) value);
856 else if (strcasecmp((const char *) tag, "SEP") == 0)
857 t30_set_tx_selective_polling_address(t30, (const char *) value);
858 else if (strcasecmp((const char *) tag, "PSA") == 0)
859 t30_set_tx_polled_sub_address(t30, (const char *) value);
860 else if (strcasecmp((const char *) tag, "SID") == 0)
861 t30_set_tx_sender_ident(t30, (const char *) value);
862 else if (strcasecmp((const char *) tag, "PWD") == 0)
863 t30_set_tx_password(t30, (const char *) value);
864 else if (strcasecmp((const char *) tag, "RXFILE") == 0)
865 {
866 if (value)
867 t30_set_rx_file(t30, (const char *) value, -1);
868 else
869 t30_set_rx_file(t30, output_tiff_file_name, -1);
870 }
871 else if (strcasecmp((const char *) tag, "TXFILE") == 0)
872 {
873 sprintf(next_tx_file, "%s/%s", image_path, (const char *) value);
874 printf("Push '%s'\n", next_tx_file);
875 }
876 return 0;
877 }
878 else if (strcasecmp((const char *) type, "CALL") == 0)
879 {
880 fax = fax_init(NULL, FALSE);
881 fax_prepare();
882 next_tx_file[0] = '\0';
883 t30 = fax_get_t30_state(fax);
884 t30_set_rx_file(t30, output_tiff_file_name, -1);
885 /* Avoid libtiff 3.8.2 and earlier bug on complex 2D lines. */
886 t30_set_rx_encoding(t30, T4_COMPRESSION_ITU_T4_1D);
887 if (value)
888 {
889 sprintf(path, "%s/%s", image_path, (const char *) value);
890 t30_set_tx_file(t30, path, -1, -1);
891 }
892 return 0;
893 }
894 else if (strcasecmp((const char *) type, "ANSWER") == 0)
895 {
896 fax = fax_init(NULL, TRUE);
897 fax_prepare();
898 next_tx_file[0] = '\0';
899 t30 = fax_get_t30_state(fax);
900 /* Avoid libtiff 3.8.2 and earlier bug on complex 2D lines. */
901 t30_set_rx_encoding(t30, T4_COMPRESSION_ITU_T4_1D);
902 if (value)
903 {
904 sprintf(path, "%s/%s", image_path, (const char *) value);
905 t30_set_tx_file(t30, path, -1, -1);
906 }
907 return 0;
908 }
909 else if (strcasecmp((const char *) type, "CNG") == 0)
910 {
911 faxtester_set_rx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
912 faxtester_set_tx_type(s, T30_MODEM_CNG, 0, FALSE, FALSE);
913 }
914 else if (strcasecmp((const char *) type, "CED") == 0)
915 {
916 faxtester_set_rx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
917 faxtester_set_tx_type(s, T30_MODEM_CED, 0, FALSE, FALSE);
918 }
919 else if (strcasecmp((const char *) type, "WAIT") == 0)
920 {
921 delay = (value) ? atoi((const char *) value) : 1;
922 faxtester_set_rx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
923 faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, delay, FALSE);
924 }
925 else if (strcasecmp((const char *) type, "PREAMBLE") == 0)
926 {
927 flags = (value) ? atoi((const char *) value) : 37;
928 faxtester_send_hdlc_flags(s, flags);
929 }
930 else if (strcasecmp((const char *) type, "POSTAMBLE") == 0)
931 {
932 flags = (value) ? atoi((const char *) value) : 5;
933 faxtester_send_hdlc_flags(s, flags);
934 }
935 else if (strcasecmp((const char *) type, "HDLC") == 0)
936 {
937 i = string_to_msg(buf, mask, (const char *) value);
938 bit_reverse(buf, buf, abs(i));
939 if (crc_error && strcasecmp((const char *) crc_error, "0") == 0)
940 faxtester_send_hdlc_msg(s, buf, abs(i), FALSE);
941 else
942 faxtester_send_hdlc_msg(s, buf, abs(i), TRUE);
943 }
944 else if (strcasecmp((const char *) type, "TCF") == 0)
945 {
946 if (value)
947 i = atoi((const char *) value);
948 else
949 i = 450;
950 if (pattern)
951 {
952 /* TODO: implement proper patterns */
953 j = atoi((const char *) pattern);
954 memset(image, 0x55, j);
955 if (i > j)
956 memset(image + j, 0, i - j);
957 }
958 else
959 {
960 memset(image, 0, i);
961 }
962 faxtester_set_non_ecm_image_buffer(s, image, i);
963 }
964 else if (strcasecmp((const char *) type, "MSG") == 0)
965 {
966 /* A non-ECM page */
967 min_row_bits = (min_bits) ? atoi((const char *) min_bits) : 0;
968 sprintf(path, "%s/%s", image_path, (const char *) value);
969 if (t4_tx_init(&t4_state, path, -1, -1) == NULL)
970 {
971 span_log(&s->logging, SPAN_LOG_FLOW, "Failed to init T.4 send\n");
972 printf("Test failed\n");
973 exit(2);
974 }
975 t4_tx_set_min_row_bits(&t4_state, min_row_bits);
976 t4_tx_set_header_info(&t4_state, NULL);
977 compression_type = T4_COMPRESSION_ITU_T4_1D;
978 if (compression)
979 {
980 if (strcasecmp((const char *) compression, "T.4 2D") == 0)
981 compression_type = T4_COMPRESSION_ITU_T4_2D;
982 else if (strcasecmp((const char *) compression, "T.6") == 0)
983 compression_type = T4_COMPRESSION_ITU_T6;
984 }
985 t4_tx_set_tx_encoding(&t4_state, compression_type);
986 if (t4_tx_start_page(&t4_state))
987 {
988 span_log(&s->logging, SPAN_LOG_FLOW, "Failed to start T.4 send\n");
989 printf("Test failed\n");
990 exit(2);
991 }
992 len = t4_tx_get_chunk(&t4_state, image, sizeof(image));
993 if (bad_rows)
994 {
995 span_log(&s->logging, SPAN_LOG_FLOW, "We need to corrupt the image\n");
996 corrupt_image(s, image, len, (const char *) bad_rows);
997 }
998 t4_tx_release(&t4_state);
999 span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM image is %d bytes\n", len);
1000 faxtester_set_non_ecm_image_buffer(s, image, len);
1001 }
1002 else if (strcasecmp((const char *) type, "PP") == 0)
1003 {
1004 min_row_bits = (min_bits) ? atoi((const char *) min_bits) : 0;
1005 ecm_block = (block) ? atoi((const char *) block) : 0;
1006 ecm_frame_size = (frame_size) ? atoi((const char *) frame_size) : 64;
1007 i = (crc_error) ? atoi((const char *) crc_error) : -1;
1008 sprintf(path, "%s/%s", image_path, (const char *) value);
1009 if (t4_tx_init(&t4_state, path, -1, -1) == NULL)
1010 {
1011 span_log(&s->logging, SPAN_LOG_FLOW, "Failed to init T.4 send\n");
1012 printf("Test failed\n");
1013 exit(2);
1014 }
1015 t4_tx_set_min_row_bits(&t4_state, min_row_bits);
1016 t4_tx_set_header_info(&t4_state, NULL);
1017 compression_type = T4_COMPRESSION_ITU_T4_1D;
1018 if (compression)
1019 {
1020 if (strcasecmp((const char *) compression, "T.4 2D") == 0)
1021 compression_type = T4_COMPRESSION_ITU_T4_2D;
1022 else if (strcasecmp((const char *) compression, "T.6") == 0)
1023 compression_type = T4_COMPRESSION_ITU_T6;
1024 }
1025 t4_tx_set_tx_encoding(&t4_state, compression_type);
1026 if (t4_tx_start_page(&t4_state))
1027 {
1028 span_log(&s->logging, SPAN_LOG_FLOW, "Failed to start T.4 send\n");
1029 printf("Test failed\n");
1030 exit(2);
1031 }
1032 /*endif*/
1033 len = t4_tx_get_chunk(&t4_state, image, sizeof(image));
1034 if (bad_rows)
1035 {
1036 span_log(&s->logging, SPAN_LOG_FLOW, "We need to corrupt the image\n");
1037 corrupt_image(s, image, len, (const char *) bad_rows);
1038 }
1039 /*endif*/
1040 t4_tx_release(&t4_state);
1041 span_log(&s->logging, SPAN_LOG_FLOW, "ECM image is %d bytes\n", len);
1042 faxtester_set_ecm_image_buffer(s, image, len, ecm_block, ecm_frame_size, i);
1043 }
1044 else
1045 {
1046 span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised type '%s'\n", (const char *) type);
1047 return 0;
1048 }
1049 /*endif*/
1050 }
1051 /*endif*/
1052 return 1;
1053 }
1054 /*- End of function --------------------------------------------------------*/
1055
1056 static void exchange(faxtester_state_t *s)
1057 {
1058 int16_t amp[SAMPLES_PER_CHUNK];
1059 int16_t out_amp[2*SAMPLES_PER_CHUNK];
1060 int len;
1061 int i;
1062 int total_audio_time;
1063 int log_audio;
1064 logging_state_t *logging;
1065
1066 log_audio = TRUE;
1067 output_tiff_file_name = OUTPUT_TIFF_FILE_NAME;
1068
1069 if (log_audio)
1070 {
1071 if ((out_handle = sf_open_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == NULL)
1072 {
1073 fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_WAVE);
1074 printf("Test failed\n");
1075 exit(2);
1076 }
1077 /*endif*/
1078 }
1079 /*endif*/
1080
1081 total_audio_time = 0;
1082
1083 faxtester_set_transmit_on_idle(&state, TRUE);
1084 faxtester_set_real_time_frame_handler(&state, faxtester_real_time_frame_handler, NULL);
1085 faxtester_set_front_end_step_complete_handler(&state, faxtester_front_end_step_complete_handler, NULL);
1086 faxtester_set_front_end_step_timeout_handler(&state, faxtester_front_end_step_timeout_handler, NULL);
1087
1088 fax = fax_init(NULL, FALSE);
1089 fax_prepare();
1090 next_tx_file[0] = '\0';
1091
1092 while (next_step(s) == 0)
1093 ;
1094 /*endwhile*/
1095 for (;;)
1096 {
1097 len = fax_tx(fax, amp, SAMPLES_PER_CHUNK);
1098 faxtester_rx(s, amp, len);
1099 if (log_audio)
1100 {
1101 for (i = 0; i < len; i++)
1102 out_amp[2*i + 0] = amp[i];
1103 /*endfor*/
1104 }
1105 /*endif*/
1106
1107 total_audio_time += SAMPLES_PER_CHUNK;
1108
1109 logging = t30_get_logging_state(fax_get_t30_state(fax));
1110 span_log_bump_samples(logging, len);
1111 #if 0
1112 span_log_bump_samples(&fax.modems.v27ter_rx.logging, len);
1113 span_log_bump_samples(&fax.modems.v29_rx.logging, len);
1114 span_log_bump_samples(&fax.modems.v17_rx.logging, len);
1115 #endif
1116 logging = fax_get_logging_state(fax);
1117 span_log_bump_samples(logging, len);
1118
1119 span_log_bump_samples(&s->logging, len);
1120
1121 len = faxtester_tx(s, amp, 160);
1122 if (fax_rx(fax, amp, len))
1123 break;
1124 /*endif*/
1125 if (log_audio)
1126 {
1127 for (i = 0; i < len; i++)
1128 out_amp[2*i + 1] = amp[i];
1129 /*endfor*/
1130 if (sf_writef_short(out_handle, out_amp, SAMPLES_PER_CHUNK) != SAMPLES_PER_CHUNK)
1131 break;
1132 /*endif*/
1133 }
1134 /*endif*/
1135 }
1136 /*endfor*/
1137 if (log_audio)
1138 {
1139 if (sf_close(out_handle))
1140 {
1141 fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE);
1142 printf("Test failed\n");
1143 exit(2);
1144 }
1145 /*endif*/
1146 }
1147 /*endif*/
1148 }
1149 /*- End of function --------------------------------------------------------*/
1150
1151 static int parse_config(faxtester_state_t *s, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
1152 {
1153 xmlChar *x;
1154 xmlChar *y;
1155
1156 while (cur)
1157 {
1158 if (xmlStrcmp(cur->name, (const xmlChar *) "path") == 0)
1159 {
1160 if ((x = xmlGetProp(cur, (const xmlChar *) "type"))
1161 &&
1162 (y = xmlGetProp(cur, (const xmlChar *) "value")))
1163 {
1164 if (strcasecmp((const char *) x, "IMAGE") == 0)
1165 {
1166 span_log(&s->logging, SPAN_LOG_FLOW, "Found '%s' '%s'\n", (char *) x, (char *) y);
1167 strcpy(image_path, (const char *) y);
1168 }
1169 /*endif*/
1170 }
1171 /*endif*/
1172 }
1173 /*endif*/
1174 cur = cur->next;
1175 }
1176 /*endwhile*/
1177 return -1;
1178 }
1179 /*- End of function --------------------------------------------------------*/
1180
1181 static int parse_test_group(faxtester_state_t *s, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, const char *test)
1182 {
1183 xmlChar *x;
1184
1185 while (cur)
1186 {
1187 if (xmlStrcmp(cur->name, (const xmlChar *) "test") == 0)
1188 {
1189 if ((x = xmlGetProp(cur, (const xmlChar *) "name")))
1190 {
1191 if (xmlStrcmp(x, (const xmlChar *) test) == 0)
1192 {
1193 span_log(&s->logging, SPAN_LOG_FLOW, "Found '%s'\n", (char *) x);
1194 s->cur = cur->xmlChildrenNode;
1195 return 0;
1196 }
1197 /*endif*/
1198 }
1199 /*endif*/
1200 }
1201 /*endif*/
1202 cur = cur->next;
1203 }
1204 /*endwhile*/
1205 return -1;
1206 }
1207 /*- End of function --------------------------------------------------------*/
1208
1209 static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test)
1210 {
1211 xmlDocPtr doc;
1212 xmlNsPtr ns;
1213 xmlNodePtr cur;
1214 xmlValidCtxt valid;
1215
1216 ns = NULL;
1217 xmlKeepBlanksDefault(0);
1218 xmlCleanupParser();
1219 if ((doc = xmlParseFile(test_file)) == NULL)
1220 {
1221 fprintf(stderr, "No document\n");
1222 printf("Test failed\n");
1223 exit(2);
1224 }
1225 /*endif*/
1226 xmlXIncludeProcess(doc);
1227 if (!xmlValidateDocument(&valid, doc))
1228 {
1229 fprintf(stderr, "Invalid document\n");
1230 printf("Test failed\n");
1231 exit(2);
1232 }
1233 /*endif*/
1234
1235 /* Check the document is of the right kind */
1236 if ((cur = xmlDocGetRootElement(doc)) == NULL)
1237 {
1238 xmlFreeDoc(doc);
1239 fprintf(stderr, "Empty document\n");
1240 printf("Test failed\n");
1241 exit(2);
1242 }
1243 /*endif*/
1244 if (xmlStrcmp(cur->name, (const xmlChar *) "fax-tests"))
1245 {
1246 xmlFreeDoc(doc);
1247 fprintf(stderr, "Document of the wrong type, root node != fax-tests");
1248 printf("Test failed\n");
1249 exit(2);
1250 }
1251 /*endif*/
1252 cur = cur->xmlChildrenNode;
1253 while (cur && xmlIsBlankNode(cur))
1254 cur = cur->next;
1255 /*endwhile*/
1256 if (cur == NULL)
1257 {
1258 printf("Test failed\n");
1259 exit(2);
1260 }
1261 /*endif*/
1262 while (cur)
1263 {
1264 if (xmlStrcmp(cur->name, (const xmlChar *) "config") == 0)
1265 {
1266 parse_config(s, doc, ns, cur->xmlChildrenNode);
1267 }
1268 /*endif*/
1269 if (xmlStrcmp(cur->name, (const xmlChar *) "test-group") == 0)
1270 {
1271 if (parse_test_group(s, doc, ns, cur->xmlChildrenNode, test) == 0)
1272 {
1273 /* We found the test we want, so run it. */
1274 exchange(s);
1275 break;
1276 }
1277 /*endif*/
1278 }
1279 /*endif*/
1280 cur = cur->next;
1281 }
1282 /*endwhile*/
1283 xmlFreeDoc(doc);
1284 return 0;
1285 }
1286 /*- End of function --------------------------------------------------------*/
1287
1288 int main(int argc, char *argv[])
1289 {
1290 const char *test_name;
1291
1292 //string_test();
1293
1294 test_name = "MRGN01";
1295 if (argc > 1)
1296 test_name = argv[1];
1297
1298 strcpy(image_path, ".");
1299 faxtester_init(&state, TRUE);
1300 memset(&expected_rx_info, 0, sizeof(expected_rx_info));
1301 span_log_set_level(&state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
1302 span_log_set_tag(&state.logging, "B");
1303 get_test_set(&state, "../spandsp/tsb85.xml", test_name);
1304 printf("Done\n");
1305 return 0;
1306 }
1307 /*- End of function --------------------------------------------------------*/
1308 /*- End of file ------------------------------------------------------------*/

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