1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * fax_tests.c - Tests for the audio and T.38 FAX modules.
5  *
6  * Written by Steve Underwood <steveu@coppice.org>
7  *
8  * Copyright (C) 2005, 2006, 2009, 2010 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 
26 /*! \file */
27 
28 /*! \page fax_tests_page FAX tests
29 \section fax_tests_page_sec_1 What does it do?
30 These tests exercise the following FAX to FAX paths:
31 
32 TSB85 <-----------+                                     +-----------> TSB85
33                    \                                   /
34  T.31 <-----------+ \                                 / +-----------> T.31
35                    \ \                               / /
36           +--Modems-+-+-----------TDM/RTP-----------+-+-Modems--+
37           |            \                           /            |
38           |             \                         /             |
39  T.30 <---+        T.38 gateway            T.38 gateway         +---> T.30
40           |               \                     /               |
41           |                \                   /                |
42           +---T.38---+-+----+----UDPTL/RTP----+----+ +---T.38---+
43                     / / \                         / \ \
44  T.31 <------------/ /   +----------TCP----------+   \ +------------> T.31
45                     /                                 \
46 TSB85 <------------+                                   +------------> TSB85
47 
48 T.30<->Modems<-------------------------TDM/RTP------------------------->Modems<->T.30
49 T.30<->Modems<-TDM/RTP->T.38 gateway<-UDPTL/RTP->T.38 gateway<-TDM/RTP->Modems<->T.30
50 T.30<->Modems<-TDM/RTP->T.38 gateway<-UDPTL/RTP-------------------------->T.38<->T.30
51 T.30<->T.38<--------------------------UDPTL/RTP->T.38 gateway<-TDM/RTP->Modems<->T.30
52 T.30<->T.38<--------------------------UDPTL/RTP-------------------------->T.38<->T.30
53 
54 The T.31 and TSB85 parts are incomplete right now.
55 */
56 
57 #if defined(HAVE_CONFIG_H)
58 #include "config.h"
59 #endif
60 
61 #if defined(HAVE_FL_FL_H)  &&  defined(HAVE_FL_FL_CARTESIAN_H)  &&  defined(HAVE_FL_FL_AUDIO_METER_H)
62 #define ENABLE_GUI
63 #endif
64 
65 #include <stdlib.h>
66 #include <inttypes.h>
67 #include <stdio.h>
68 #include <fcntl.h>
69 #include <string.h>
70 #include <assert.h>
71 #include <errno.h>
72 #include <sndfile.h>
73 #if !defined(_WIN32)
74 #include <unistd.h>
75 #endif
76 
77 #if defined(HAVE_LIBXML_XMLMEMORY_H)
78 #include <libxml/xmlmemory.h>
79 #endif
80 #if defined(HAVE_LIBXML_PARSER_H)
81 #include <libxml/parser.h>
82 #endif
83 #if defined(HAVE_LIBXML_XINCLUDE_H)
84 #include <libxml/xinclude.h>
85 #endif
86 
87 #include "udptl.h"
88 #include "spandsp.h"
89 #include "spandsp-sim.h"
90 
91 #if defined(ENABLE_GUI)
92 #include "media_monitor.h"
93 #endif
94 #include "fax_tester.h"
95 #include "fax_utils.h"
96 #include "pcap_parse.h"
97 
98 #define SAMPLES_PER_CHUNK       160
99 
100 #define INPUT_TIFF_FILE_NAME    "../test-data/itu/fax/itutests.tif"
101 #define OUTPUT_TIFF_FILE_NAME   "fax_tests.tif"
102 #define INPUT_WAVE_FILE_NAME    "fax_cap.wav"
103 #define OUTPUT_WAVE_FILE_NAME   "fax_tests.wav"
104 
105 enum
106 {
107     AUDIO_FAX = 1,
108     T38_FAX,
109     T31_AUDIO_FAX,
110     T31_T38_FAX,
111     TSB85_AUDIO_FAX,
112     TSB85_T38_FAX,
113     REPLAY_AUDIO_FAX,
114     REPLAY_T38_FAX,
115     AUDIO_TO_T38_GATEWAY,
116     PASSTHROUGH,
117     AUDIO_CHAN,
118     T38_CHAN
119 };
120 
121 const char *output_tiff_file_name;
122 
123 struct audio_buf_s
124 {
125     int16_t amp[SAMPLES_PER_CHUNK];
126     int len;
127 };
128 
129 struct chain_element_s
130 {
131     int node_type;
132     int left_chan_type;
133     int right_chan_type;
134     struct
135     {
136         fax_state_t *fax_state;
137         t38_terminal_state_t *t38_state;
138         faxtester_state_t *faxtester_state;
139         t38_gateway_state_t *t38_gateway_state;
140         SNDFILE *wave_handle;
141     } node;
142     struct
143     {
144         g1050_state_t *g1050_path;
145         both_ways_line_model_state_t *line_model;
146         struct audio_buf_s *audio_in_buf;
147         struct audio_buf_s *audio_out_buf;
148     } path;
149     t30_state_t *t30_state;
150     t38_core_state_t *t38_core_state;
151     int t38_subst_seq;
152     bool phase_e_reached;
153     bool completed;
154     bool succeeded;
155     t30_exchanged_info_t expected_rx_info;
156 
157     awgn_state_t *awgn_state;
158 
159     struct audio_buf_s audio_buf[2];
160 
161     int peer;
162     int t38_peer;
163 
164     char tag[10];
165 };
166 
167 struct chain_element_s chain[7];
168 int chain_elements = 2;
169 
170 bool t38_simulate_incrementing_repeats = false;
171 bool use_receiver_not_ready = false;
172 bool test_local_interrupt = false;
173 
174 double when = 0.0;
175 
phase_b_handler(void * user_data,int result)176 static int phase_b_handler(void *user_data, int result)
177 {
178     int i;
179     int ch;
180     int status;
181     int len;
182     t30_state_t *s;
183     char tag[20];
184     const char *u;
185     const uint8_t *v;
186     t30_exchanged_info_t *info;
187 
188     i = (int) (intptr_t) user_data;
189     s = chain[i].t30_state;
190     ch = i + 'A';
191     info = &chain[i].expected_rx_info;
192     snprintf(tag, sizeof(tag), "%c: Phase B", ch);
193     printf("%c: Phase B handler - (0x%X) %s\n", ch, result, t30_frametype(result));
194     fax_log_rx_parameters(s, tag);
195     status = T30_ERR_OK;
196 
197     if ((u = t30_get_rx_ident(s)))
198     {
199         printf("%c: Phase B remote ident '%s'\n", ch, u);
200         if (info->ident[0]  &&  strcmp(info->ident, u))
201         {
202             printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", ch, info->ident);
203             status = T30_ERR_IDENT_UNACCEPTABLE;
204         }
205     }
206     else
207     {
208         if (info->ident[0])
209         {
210             printf("%c: Phase B: remote ident missing!\n", ch);
211             status = T30_ERR_IDENT_UNACCEPTABLE;
212         }
213     }
214     if ((u = t30_get_rx_sub_address(s)))
215     {
216         printf("%c: Phase B: remote sub-address '%s'\n", ch, u);
217         if (info->sub_address[0]  &&  strcmp(info->sub_address, u))
218         {
219             printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", ch, info->sub_address);
220             status = T30_ERR_SUB_UNACCEPTABLE;
221         }
222     }
223     else
224     {
225         if (info->sub_address[0])
226         {
227             printf("%c: Phase B: remote sub-address missing!\n", ch);
228             status = T30_ERR_SUB_UNACCEPTABLE;
229         }
230     }
231     if ((u = t30_get_rx_polled_sub_address(s)))
232     {
233         printf("%c: Phase B: remote polled sub-address '%s'\n", ch, u);
234         if (info->polled_sub_address[0]  &&  strcmp(info->polled_sub_address, u))
235         {
236             printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", ch, info->polled_sub_address);
237             status = T30_ERR_PSA_UNACCEPTABLE;
238         }
239     }
240     else
241     {
242         if (info->polled_sub_address[0])
243         {
244             printf("%c: Phase B: remote polled sub-address missing!\n", ch);
245             status = T30_ERR_PSA_UNACCEPTABLE;
246         }
247     }
248     if ((u = t30_get_rx_selective_polling_address(s)))
249     {
250         printf("%c: Phase B: remote selective polling address '%s'\n", ch, u);
251         if (info->selective_polling_address[0]  &&  strcmp(info->selective_polling_address, u))
252         {
253             printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", ch, info->selective_polling_address);
254             status = T30_ERR_SEP_UNACCEPTABLE;
255         }
256     }
257     else
258     {
259         if (info->selective_polling_address[0])
260         {
261             printf("%c: Phase B: remote selective polling address missing!\n", ch);
262             status = T30_ERR_SEP_UNACCEPTABLE;
263         }
264     }
265     if ((u = t30_get_rx_sender_ident(s)))
266     {
267         printf("%c: Phase B: remote sender ident '%s'\n", ch, u);
268         if (info->sender_ident[0]  &&  strcmp(info->sender_ident, u))
269         {
270             printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", ch, info->sender_ident);
271             status = T30_ERR_SID_UNACCEPTABLE;
272         }
273     }
274     else
275     {
276         if (info->sender_ident[0])
277         {
278             printf("%c: Phase B: remote sender ident missing!\n", ch);
279             status = T30_ERR_SID_UNACCEPTABLE;
280         }
281     }
282     if ((u = t30_get_rx_password(s)))
283     {
284         printf("%c: Phase B: remote password '%s'\n", ch, u);
285         if (info->password[0]  &&  strcmp(info->password, u))
286         {
287             printf("%c: Phase B: remote password incorrect! - expected '%s'\n", ch, info->password);
288             status = T30_ERR_PWD_UNACCEPTABLE;
289         }
290     }
291     else
292     {
293         if (info->password[0])
294         {
295             printf("%c: Phase B: remote password missing!\n", ch);
296             status = T30_ERR_PWD_UNACCEPTABLE;
297         }
298     }
299     if ((len = t30_get_rx_nsf(s, &v)))
300     {
301         printf("%c: Phase B: NSF %d bytes\n", ch, len);
302         if (info->nsf_len  &&  (info->nsf_len != len  ||  memcmp(info->nsf, v, len)))
303         {
304             printf("%c: Phase B: remote NSF incorrect! - expected %u bytes\n", ch, (unsigned int) info->nsf_len);
305         }
306     }
307     else
308     {
309         if (info->nsf_len)
310         {
311             printf("%c: Phase B: remote NSF missing! - expected %u bytes\n", ch, (unsigned int) info->nsf_len);
312         }
313     }
314     if ((len = t30_get_rx_nsc(s, &v)))
315     {
316         printf("%c: Phase B: NSC %d bytes\n", ch, len);
317         if (info->nsc_len  &&  (info->nsc_len != len  ||  memcmp(info->nsc, v, len)))
318         {
319             printf("%c: Phase B: remote NSC incorrect! - expected %u bytes\n", ch, (unsigned int) info->nsc_len);
320         }
321     }
322     else
323     {
324         if (info->nsc_len)
325         {
326             printf("%c: Phase B: remote NSC missing! - expected %u bytes\n", ch, (unsigned int) info->nsc_len);
327         }
328     }
329     if ((len = t30_get_rx_nss(s, &v)))
330     {
331         printf("%c: Phase B: NSS %d bytes\n", ch, len);
332         if (info->nss_len  &&  (info->nss_len != len  ||  memcmp(info->nss, v, len)))
333         {
334             printf("%c: Phase B: remote NSS incorrect! - expected %u bytes\n", ch, (unsigned int) info->nss_len);
335         }
336     }
337     else
338     {
339         if (info->nss_len)
340         {
341             printf("%c: Phase B: remote NSS missing! - expected %u bytes\n", ch, (unsigned int) info->nsf_len);
342         }
343     }
344 
345     return status;
346 }
347 /*- End of function --------------------------------------------------------*/
348 
phase_d_handler(void * user_data,int result)349 static int phase_d_handler(void *user_data, int result)
350 {
351     int i;
352     int ch;
353     t30_state_t *s;
354     char tag[20];
355 
356     i = (int) (intptr_t) user_data;
357     s = chain[i].t30_state;
358     ch = i + 'A';
359     snprintf(tag, sizeof(tag), "%c: Phase D", ch);
360     printf("%c: Phase D handler - (0x%X) %s\n", ch, result, t30_frametype(result));
361     fax_log_page_transfer_statistics(s, tag);
362     fax_log_tx_parameters(s, tag);
363     fax_log_rx_parameters(s, tag);
364 
365     if (use_receiver_not_ready)
366         t30_set_receiver_not_ready(s, 3);
367 
368     if (test_local_interrupt)
369     {
370         if (i == 0)
371         {
372             printf("%c: Initiating interrupt request\n", ch);
373             t30_local_interrupt_request(s, true);
374         }
375         else
376         {
377             switch (result)
378             {
379             case T30_PIP:
380             case T30_PRI_MPS:
381             case T30_PRI_EOM:
382             case T30_PRI_EOP:
383                 printf("%c: Accepting interrupt request\n", ch);
384                 t30_local_interrupt_request(s, true);
385                 break;
386             case T30_PIN:
387                 break;
388             }
389         }
390     }
391     return T30_ERR_OK;
392 }
393 /*- End of function --------------------------------------------------------*/
394 
phase_e_handler(void * user_data,int result)395 static void phase_e_handler(void *user_data, int result)
396 {
397     int i;
398     int ch;
399     t30_stats_t t;
400     t30_state_t *s;
401     char tag[20];
402 
403     i = (int) (intptr_t) user_data;
404     s = chain[i].t30_state;
405     ch = i + 'A';
406     snprintf(tag, sizeof(tag), "%c: Phase E", ch);
407     printf("%c: Phase E handler - (%d) %s\n", ch, result, t30_completion_code_to_str(result));
408     fax_log_final_transfer_statistics(s, tag);
409     fax_log_tx_parameters(s, tag);
410     fax_log_rx_parameters(s, tag);
411     t30_get_transfer_statistics(s, &t);
412     chain[i].succeeded = (result == T30_ERR_OK);
413     chain[i].phase_e_reached = true;
414 }
415 /*- End of function --------------------------------------------------------*/
416 
real_time_t30_frame_handler(void * user_data,bool incoming,const uint8_t * msg,int len)417 static void real_time_t30_frame_handler(void *user_data,
418                                         bool incoming,
419                                         const uint8_t *msg,
420                                         int len)
421 {
422     int i;
423     int ch;
424 
425     i = (intptr_t) user_data;
426     ch = i + 'A';
427     printf("%c: Real time frame handler - %s, %s, length = %d\n",
428            ch,
429            (incoming)  ?  "line->T.30"  : "T.30->line",
430            t30_frametype(msg[2]),
431            len);
432 }
433 /*- End of function --------------------------------------------------------*/
434 
document_handler(void * user_data,int event)435 static int document_handler(void *user_data, int event)
436 {
437     int i;
438     int ch;
439 
440     i = (intptr_t) user_data;
441     ch = i + 'A';
442     printf("%c: Document handler - event %d\n", ch, event);
443     return false;
444 }
445 /*- End of function --------------------------------------------------------*/
446 
set_t30_callbacks(t30_state_t * t30,int chan)447 static void set_t30_callbacks(t30_state_t *t30, int chan)
448 {
449     t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) chan);
450     t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) chan);
451     t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) chan);
452     t30_set_real_time_frame_handler(t30, real_time_t30_frame_handler, (void *) (intptr_t) chan);
453     t30_set_document_handler(t30, document_handler, (void *) (intptr_t) chan);
454 }
455 /*- End of function --------------------------------------------------------*/
456 
real_time_gateway_frame_handler(void * user_data,bool incoming,const uint8_t * msg,int len)457 static void real_time_gateway_frame_handler(void *user_data,
458                                             bool incoming,
459                                             const uint8_t *msg,
460                                             int len)
461 {
462     int i;
463 
464     i = (intptr_t) user_data;
465     printf("%c: Real time gateway frame handler - %s, %s, length = %d\n",
466            i + 'A',
467            (incoming)  ?  "PSTN->T.38"  : "T.38->PSTN",
468            t30_frametype(msg[2]),
469            len);
470 }
471 /*- End of function --------------------------------------------------------*/
472 
tx_packet_handler(t38_core_state_t * s,void * user_data,const uint8_t * buf,int len,int count)473 static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
474 {
475     int i;
476     int chan;
477 
478     /* This routine queues messages between two instances of T.38 processing */
479     chan = (intptr_t) user_data;
480     if (t38_simulate_incrementing_repeats)
481     {
482         for (i = 0;  i < count;  i++)
483         {
484             span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", chain[chan].t38_subst_seq, len);
485 
486             if (g1050_put(chain[chan].path.g1050_path, buf, len, chain[chan].t38_subst_seq, when) < 0)
487                 printf("Lost packet %d\n", chain[chan].t38_subst_seq);
488             chain[chan].t38_subst_seq = (chain[chan].t38_subst_seq + 1) & 0xFFFF;
489         }
490     }
491     else
492     {
493         span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count);
494 
495         for (i = 0;  i < count;  i++)
496         {
497             if (g1050_put(chain[chan].path.g1050_path, buf, len, s->tx_seq_no, when) < 0)
498                 printf("Lost packet %d\n", s->tx_seq_no);
499         }
500     }
501     return 0;
502 }
503 /*- End of function --------------------------------------------------------*/
504 
t33_tests(void)505 static void t33_tests(void)
506 {
507     int n;
508     int item_no;
509     int type;
510     uint8_t num[21];
511     uint8_t new_t33[133];
512     /* These patterns are from the T.33 spec */
513     static const uint8_t *pkts[] =
514     {
515         (const uint8_t *) "#1234567890#1234",
516         (const uint8_t *) "1234#5678#8910",
517         (const uint8_t *) "#6174444100#1234#567",
518         (const uint8_t *) "1234#5678##2032223",
519         (const uint8_t *) "#2037445555##6446666",
520         (const uint8_t *) "#2037445555#1234##6446666#5678",
521         //(const uint8_t *) "#123456789012345678901#1234##6446666#5678",
522         (const uint8_t *) ""
523     };
524 
525     printf("T.33 sub-address packing/unpacking tests\n");
526     for (n = 0;  pkts[n][0];  n++)
527     {
528         new_t33[0] = '\0';
529         printf("'%s'\n", pkts[n]);
530         for (item_no = 0;  item_no < 100;  item_no++)
531         {
532             if ((type = t33_sub_address_extract_field(num, pkts[n], item_no)) <= 0)
533             {
534                 if (type == T33_NONE)
535                     break;
536                 printf("Bad sub-address field\n");
537                 exit(2);
538             }
539             switch (type)
540             {
541             case T33_SST:
542                 printf("SST '%s'\n", num);
543                 t33_sub_address_add_field(new_t33, num, type);
544                 break;
545             case T33_EXT:
546                 printf("    EXT '%s'\n", num);
547                 t33_sub_address_add_field(new_t33, num, type);
548                 break;
549             }
550         }
551         if (strcmp((const char *) pkts[n], (const char *) new_t33))
552         {
553             printf("Re-encode mismatch '%s' '%s'\n", pkts[n], new_t33);
554             exit(2);
555         }
556     }
557 }
558 /*- End of function --------------------------------------------------------*/
559 
main(int argc,char * argv[])560 int main(int argc, char *argv[])
561 {
562     int16_t silence[SAMPLES_PER_CHUNK];
563     int16_t t38_amp_hist_a[8][SAMPLES_PER_CHUNK];
564     int16_t t38_amp_hist_b[8][SAMPLES_PER_CHUNK];
565     int16_t audio_log[SAMPLES_PER_CHUNK*4];
566     int hist_ptr;
567     int log_audio;
568     int msg_len;
569     uint8_t msg[1024];
570     int outframes;
571     SNDFILE *wave_handle;
572     bool use_ecm;
573     bool use_tep;
574     bool use_polled_mode;
575     bool use_transmit_on_idle;
576     bool feedback_audio;
577     int t38_version;
578     const char *input_tiff_file_name;
579     const char *replay_file_name;
580     int i;
581     int j;
582     int k;
583     int seq_no;
584     int g1050_model_no;
585     int g1050_speed_pattern_no;
586     int t38_transport;
587     double tx_when;
588     double rx_when;
589     int supported_modems;
590     int opt;
591     int start_page;
592     int end_page;
593     int drop_frame;
594     int drop_frame_rate;
595     float signal_scaling;
596     int signal_level;
597     int noise_level;
598     int code_to_look_up;
599     int scan_line_time;
600     int allowed_bilevel_resolutions[2];
601     int allowed;
602     bool remove_fill_bits;
603     bool colour_enabled;
604     bool t37_like_output;
605     t38_stats_t t38_stats;
606     t30_stats_t t30_stats;
607     logging_state_t *logging;
608     int expected_pages;
609     char *page_header_info;
610     char *page_header_tz;
611     const char *xml_file_name;
612     const char *xml_test_name[2];
613     int xml_step;
614     char buf[132 + 1];
615     int line_model_no;
616     int channel_codec;
617     int rbs_pattern;
618 #if defined(ENABLE_GUI)
619     int use_gui;
620 #endif
621 
622 #if defined(ENABLE_GUI)
623     use_gui = false;
624 #endif
625     log_audio = false;
626     use_ecm = false;
627     t38_version = 1;
628     input_tiff_file_name = INPUT_TIFF_FILE_NAME;
629     output_tiff_file_name = OUTPUT_TIFF_FILE_NAME;
630     t38_simulate_incrementing_repeats = false;
631     g1050_model_no = 0;
632     g1050_speed_pattern_no = 1;
633     remove_fill_bits = false;
634     use_tep = false;
635     feedback_audio = false;
636     use_transmit_on_idle = true;
637     use_polled_mode = false;
638     supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17;
639     page_header_info = NULL;
640     page_header_tz = NULL;
641     drop_frame = 0;
642     drop_frame_rate = 0;
643     start_page = -1;
644     end_page = -1;
645     signal_level = 0;
646     noise_level = -99;
647     scan_line_time = 0;
648     replay_file_name = INPUT_WAVE_FILE_NAME;
649     code_to_look_up = -1;
650     allowed_bilevel_resolutions[0] = 0;
651     allowed_bilevel_resolutions[1] = 0;
652     allowed = 0;
653     line_model_no = 0;
654     channel_codec = MUNGE_CODEC_NONE;
655     rbs_pattern = 0;
656     colour_enabled = false;
657     t37_like_output = false;
658     t38_transport = T38_TRANSPORT_UDPTL;
659     xml_file_name = "../spandsp/tsb85.xml";
660     xml_test_name[0] = "MRGN01";
661     xml_test_name[1] = "MRGN01";
662     xml_step = 0;
663     while ((opt = getopt(argc, argv, "7b:c:Cd:D:efFgH:i:Ilm:M:n:p:Ps:S:tT:u:v:x:X:z:")) != -1)
664     {
665         switch (opt)
666         {
667         case '7':
668             t37_like_output = true;
669             break;
670         case 'b':
671             allowed_bilevel_resolutions[allowed] = atoi(optarg);
672             allowed ^= 1;
673             break;
674         case 'c':
675             code_to_look_up = atoi(optarg);
676             break;
677         case 'C':
678             colour_enabled = true;
679             break;
680         case 'd':
681             replay_file_name = optarg;
682             break;
683         case 'D':
684             drop_frame_rate =
685             drop_frame = atoi(optarg);
686             break;
687         case 'e':
688             use_ecm = true;
689             break;
690         case 'f':
691             feedback_audio = true;
692             break;
693         case 'F':
694             remove_fill_bits = true;
695             break;
696         case 'g':
697 #if defined(ENABLE_GUI)
698             use_gui = true;
699 #else
700             fprintf(stderr, "Graphical monitoring not available\n");
701             exit(2);
702 #endif
703             break;
704         case 'H':
705             page_header_info = optarg;
706             break;
707         case 'i':
708             input_tiff_file_name = optarg;
709             break;
710         case 'I':
711             t38_simulate_incrementing_repeats = true;
712             break;
713         case 'l':
714             log_audio = true;
715             break;
716         case 'm':
717             supported_modems = atoi(optarg);
718             break;
719         case 'M':
720             g1050_model_no = optarg[0] - 'A' + 1;
721             break;
722         case 'n':
723             noise_level = atoi(optarg);
724             break;
725         case 'p':
726             /*
727                -p FAX-audio-FAX
728                -p FAX-T38-FAX
729                -p FAX-audio-T38gateway-T38-T38gateway-audio-FAX
730                -p FAX-T38-T38gateway-audio-T38gateway-T38-FAX
731                -p FAX-T38-T38gateway-audio-FAX
732                -p FAX-audio-T38gateway-T38-FAX
733                -p tester-audio-FAX
734                -p tester-T38-FAX
735                -p tester-audio-T38gateway-T38-T38gateway-audio-FAX
736                -p tester-T38-T38gateway-audio-T38gateway-T38-FAX
737                -p tester-T38-T38gateway-audio-FAX
738                -p tester-audio-T38gateway-T38-FAX
739              */
740             for (i = 0, chain_elements = 0, k = 0;  chain_elements < 7;  i++)
741             {
742                 if (optarg[i] != '-'  &&  optarg[i] != '\0')
743                     continue;
744                 j = optarg[i];
745                 optarg[i] = '\0';
746                 if (strcmp(&optarg[k], "FAX") == 0)
747                 {
748                     chain[chain_elements++].node_type = AUDIO_FAX;
749                 }
750                 else if (strcmp(&optarg[k], "T38") == 0)
751                 {
752                     chain[chain_elements++].node_type = T38_FAX;
753                 }
754                 else if (strcmp(&optarg[k], "T31") == 0)
755                 {
756                     chain[chain_elements++].node_type = T31_AUDIO_FAX;
757                 }
758                 else if (strcmp(&optarg[k], "tester") == 0)
759                 {
760                     chain[chain_elements++].node_type = TSB85_AUDIO_FAX;
761                 }
762                 else if (strcmp(&optarg[k], "replay") == 0)
763                 {
764                     chain[chain_elements++].node_type = REPLAY_AUDIO_FAX;
765                 }
766                 else if (strcmp(&optarg[k], "T38gateway") == 0)
767                 {
768                     chain[chain_elements++].node_type = AUDIO_TO_T38_GATEWAY;
769                 }
770                 else if (strcmp(&optarg[k], "passthrough") == 0)
771                 {
772                     chain[chain_elements++].node_type = PASSTHROUGH;
773                 }
774                 else
775                 {
776                     fprintf(stderr, "Unknown FAX path element %s\n", &optarg[k]);
777                     exit(2);
778                 }
779                 k = i + 1;
780                 if (j == '\0')
781                     break;
782             }
783 #if 0
784             if ((chain[0].node_type == AUDIO_FAX  &&  chain[chain_elements - 1].node_type != AUDIO_FAX)
785                 ||
786                 (chain[0].node_type != AUDIO_FAX  &&  chain[chain_elements - 1].node_type == AUDIO_FAX))
787             {
788                 fprintf(stderr, "Invalid FAX path\n");
789                 exit(2);
790             }
791 #endif
792             break;
793         case 'P':
794             use_polled_mode = true;
795             break;
796         case 's':
797             g1050_speed_pattern_no = atoi(optarg);
798             break;
799 #if 0
800         case 's':
801             signal_level = atoi(optarg);
802             break;
803 #endif
804         case 'S':
805             scan_line_time = atoi(optarg);
806             break;
807         case 't':
808             use_tep = true;
809             break;
810         case 'T':
811             start_page = 0;
812             end_page = atoi(optarg);
813             break;
814         case 'u':
815             if (strcasecmp(optarg, "udptl") == 0)
816                 t38_transport = T38_TRANSPORT_UDPTL;
817             else if (strcasecmp(optarg, "rtp") == 0)
818                 t38_transport = T38_TRANSPORT_RTP;
819             else if (strcasecmp(optarg, "tcp") == 0)
820                 t38_transport = T38_TRANSPORT_TCP;
821             else if (strcasecmp(optarg, "tcp-tpkt") == 0)
822                 t38_transport = T38_TRANSPORT_TCP_TPKT;
823             else
824             {
825                 fprintf(stderr, "Unknown T.38 transport mode\n");
826                 exit(2);
827             }
828             break;
829         case 'v':
830             t38_version = atoi(optarg);
831             break;
832         case 'x':
833             xml_test_name[xml_step] = optarg;
834             xml_step ^= 1;
835             break;
836         case 'X':
837             xml_file_name = optarg;
838             break;
839         case 'z':
840             page_header_tz = optarg;
841             break;
842         default:
843             //usage();
844             exit(2);
845             break;
846         }
847     }
848 
849     if (code_to_look_up >= 0)
850     {
851         printf("Result code %d is %s\n", code_to_look_up, t30_completion_code_to_str(code_to_look_up));
852         exit(0);
853     }
854 
855     printf("Using T.38 version %d\n", t38_version);
856     if (use_ecm)
857         printf("Using ECM\n");
858 
859     wave_handle = NULL;
860     if (log_audio)
861     {
862         if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 4)) == NULL)
863         {
864             fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
865             exit(2);
866         }
867     }
868     memset(silence, 0, sizeof(silence));
869 
870     srand48(0x1234567);
871 
872     memset(t38_amp_hist_a, 0, sizeof(t38_amp_hist_a));
873     memset(t38_amp_hist_b, 0, sizeof(t38_amp_hist_b));
874 
875     /* Set up the nodes */
876     chain[0].peer = chain_elements - 1;
877     chain[chain_elements - 1].peer = 0;
878 
879     for (i = 0;  i < chain_elements;  i++)
880     {
881         chain[i].tag[0] = i + 'A';
882         chain[i].tag[1] = '\0';
883 
884         memset(&chain[i].audio_buf[0], 0, sizeof(chain[i].audio_buf[0]));
885         memset(&chain[i].audio_buf[1], 0, sizeof(chain[i].audio_buf[1]));
886         memset(&chain[i].expected_rx_info, 0, sizeof(chain[i].expected_rx_info));
887 
888         switch (chain[i].node_type)
889         {
890         case AUDIO_FAX:
891             if ((chain[i].node.fax_state = fax_init(NULL, (i == 0))) == NULL)
892             {
893                 fprintf(stderr, "    Cannot start FAX instance\n");
894                 exit(2);
895             }
896             chain[i].t30_state = fax_get_t30_state(chain[i].node.fax_state);
897 
898             logging = fax_get_logging_state(chain[i].node.fax_state);
899             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
900             span_log_set_tag(logging, chain[i].tag);
901 
902             logging = fax_modems_get_logging_state(&chain[i].node.fax_state->modems);
903             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
904             span_log_set_tag(logging, chain[i].tag);
905 
906             logging = t30_get_logging_state(chain[i].t30_state);
907             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
908             span_log_set_tag(logging, chain[i].tag);
909 
910             set_t30_callbacks(chain[i].t30_state, i);
911 
912             chain[i].path.audio_in_buf = &chain[i + ((i == 0)  ?  1  :  -1)].audio_buf[0];
913             chain[i].path.audio_out_buf = &chain[i].audio_buf[0];
914 
915             chain[i].awgn_state = NULL;
916             signal_scaling = 1.0f;
917             if (noise_level > -99)
918             {
919                 chain[i].awgn_state = awgn_init_dbm0(NULL, 1234567, noise_level);
920                 signal_scaling = powf(10.0f, signal_level/20.0f);
921                 printf("Signal scaling %f\n", signal_scaling);
922             }
923             break;
924         case T38_FAX:
925             if ((chain[i].node.t38_state = t38_terminal_init(NULL, (i == 0), tx_packet_handler, (void *) (intptr_t) i)) == NULL)
926             {
927                 fprintf(stderr, "    Cannot start the T.38 terminal instance\n");
928                 exit(2);
929             }
930             chain[i].t30_state = t38_terminal_get_t30_state(chain[i].node.t38_state);
931             chain[i].t38_core_state = t38_terminal_get_t38_core_state(chain[i].node.t38_state);
932 
933             logging = t38_terminal_get_logging_state(chain[i].node.t38_state);
934             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
935             span_log_set_tag(logging, chain[i].tag);
936 
937             logging = t38_core_get_logging_state(chain[i].t38_core_state);
938             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
939             span_log_set_tag(logging, chain[i].tag);
940 
941             logging = t30_get_logging_state(chain[i].t30_state);
942             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
943             span_log_set_tag(logging, chain[i].tag);
944 
945             set_t30_callbacks(chain[i].t30_state, i);
946 
947             if (i == 0)
948             {
949                 chain[i].t38_peer = i + 1;
950             }
951             else
952             {
953                 switch (chain[i - 1].node_type)
954                 {
955                 case T38_FAX:
956                 case AUDIO_TO_T38_GATEWAY:
957                     chain[i].t38_peer = i - 1;
958                     break;
959                 default:
960                     chain[i].t38_peer = i + 1;
961                     break;
962                 }
963             }
964             break;
965         case T31_AUDIO_FAX:
966             break;
967         case T31_T38_FAX:
968             break;
969         case TSB85_AUDIO_FAX:
970         case TSB85_T38_FAX:
971             if ((chain[i].node.faxtester_state = faxtester_init(NULL, xml_file_name, xml_test_name[(i == 0)  ?  0  :  1])) == NULL)
972             {
973                 fprintf(stderr, "    Cannot start FAX tester instance\n");
974                 exit(2);
975             }
976             logging = faxtester_get_logging_state(chain[i].node.faxtester_state);
977             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
978             span_log_set_tag(logging, chain[i].tag);
979 
980             faxtester_set_transmit_on_idle(chain[i].node.faxtester_state, true);
981 
982             chain[i].path.audio_in_buf = &chain[i + ((i == 0)  ?  1  :  -1)].audio_buf[0];
983             chain[i].path.audio_out_buf = &chain[i].audio_buf[0];
984 
985             if (i == 0)
986             {
987                 chain[i].t38_peer = i + 1;
988             }
989             else
990             {
991                 switch (chain[i - 1].node_type)
992                 {
993                 case T38_FAX:
994                 case AUDIO_TO_T38_GATEWAY:
995                     chain[i].t38_peer = i - 1;
996                     break;
997                 default:
998                     chain[i].t38_peer = i + 1;
999                     break;
1000                 }
1001             }
1002 
1003             chain[i].awgn_state = NULL;
1004             signal_scaling = 1.0f;
1005             if (noise_level > -99)
1006             {
1007                 chain[i].awgn_state = awgn_init_dbm0(NULL, 1234567, noise_level);
1008                 signal_scaling = powf(10.0f, signal_level/20.0f);
1009                 printf("Signal scaling %f\n", signal_scaling);
1010             }
1011             break;
1012         case REPLAY_AUDIO_FAX:
1013             if ((chain[i].node.wave_handle = sf_open_telephony_read(replay_file_name, 1)) == NULL)
1014             {
1015                 fprintf(stderr, "    Cannot open audio file '%s'\n", replay_file_name);
1016                 exit(2);
1017             }
1018 
1019             chain[i].path.audio_in_buf = &chain[i + ((i == 0)  ?  1  :  -1)].audio_buf[0];
1020             chain[i].path.audio_out_buf = &chain[i].audio_buf[0];
1021             break;
1022         case AUDIO_TO_T38_GATEWAY:
1023             if ((chain[i].node.t38_gateway_state = t38_gateway_init(NULL, tx_packet_handler, (void *) (intptr_t) i)) == NULL)
1024             {
1025                 fprintf(stderr, "    Cannot start T.38 gateway instance\n");
1026                 exit(2);
1027             }
1028             chain[i].t38_core_state = t38_gateway_get_t38_core_state(chain[i].node.t38_gateway_state);
1029 
1030             logging = t38_gateway_get_logging_state(chain[i].node.t38_gateway_state);
1031             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
1032             span_log_set_tag(logging, chain[i].tag);
1033 
1034             logging = fax_modems_get_logging_state(&chain[i].node.t38_gateway_state->audio.modems);
1035             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
1036             span_log_set_tag(logging, chain[i].tag);
1037 
1038             logging = t38_core_get_logging_state(chain[i].t38_core_state);
1039             span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
1040             span_log_set_tag(logging, chain[i].tag);
1041 
1042             t38_gateway_set_transmit_on_idle(chain[i].node.t38_gateway_state, use_transmit_on_idle);
1043             t38_gateway_set_supported_modems(chain[i].node.t38_gateway_state, supported_modems);
1044             //t38_gateway_set_nsx_suppression(chain[i].node.t38_state, NULL, 0, NULL, 0);
1045             t38_gateway_set_fill_bit_removal(chain[i].node.t38_gateway_state, remove_fill_bits);
1046             t38_gateway_set_real_time_frame_handler(chain[i].node.t38_gateway_state, real_time_gateway_frame_handler, (void *) (intptr_t) i);
1047             t38_gateway_set_ecm_capability(chain[i].node.t38_gateway_state, use_ecm);
1048             t38_set_t38_version(chain[i].t38_core_state, t38_version);
1049 
1050             if (i == 0)
1051             {
1052                 chain[i].t38_peer = i + 1;
1053                 chain[i].path.audio_in_buf = NULL;
1054             }
1055             else
1056             {
1057                 switch (chain[i - 1].node_type)
1058                 {
1059                 case T38_FAX:
1060                 case AUDIO_TO_T38_GATEWAY:
1061                     chain[i].t38_peer = i - 1;
1062                     chain[i].path.audio_in_buf = &chain[i + 1].audio_buf[0];
1063                     break;
1064                 default:
1065                     chain[i].t38_peer = i + 1;
1066                     chain[i].path.audio_in_buf = &chain[i - 1].audio_buf[0];
1067                     break;
1068                 }
1069             }
1070 
1071             chain[i].path.audio_out_buf = &chain[i].audio_buf[0];
1072 
1073             chain[i].awgn_state = NULL;
1074             signal_scaling = 1.0f;
1075             if (noise_level > -99)
1076             {
1077                 chain[i].awgn_state = awgn_init_dbm0(NULL, 1234567, noise_level);
1078                 signal_scaling = powf(10.0f, signal_level/20.0f);
1079                 printf("Signal scaling %f\n", signal_scaling);
1080             }
1081         }
1082         if ((chain[i].path.g1050_path = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
1083         {
1084             fprintf(stderr, "    Failed to start IP network path model\n");
1085             exit(2);
1086         }
1087     }
1088 
1089     for (i = 0;  i < chain_elements;  i++)
1090     {
1091         j = i + 1;
1092         if (chain[i].t30_state)
1093         {
1094             sprintf(buf, "%d%d%d%d%d%d%d%d", j, j, j, j, j, j, j, j);
1095             t30_set_tx_ident(chain[i].t30_state, buf);
1096             strcpy(chain[chain[i].peer].expected_rx_info.ident, buf);
1097             sprintf(buf, "Sub-address %d", j);
1098             t30_set_tx_sub_address(chain[i].t30_state, buf);
1099             //strcpy(chain[chain[i].peer].expected_rx_info.sub_address, buf);
1100             sprintf(buf, "Sender ID %d", j);
1101             t30_set_tx_sender_ident(chain[i].t30_state, buf);
1102             //strcpy(chain[chain[i].peer].expected_rx_info.sender_ident, buf);
1103             sprintf(buf, "Password %d", j);
1104             t30_set_tx_password(chain[i].t30_state, buf);
1105             //strcpy(chain[chain[i].peer].expected_rx_info.password, buf);
1106             sprintf(buf, "Polled sub-add %d", j);
1107             t30_set_tx_polled_sub_address(chain[i].t30_state, buf);
1108             //strcpy(chain[chain[i].peer].expected_rx_info.polled_sub_address, buf);
1109             sprintf(buf, "Select poll add %d", j);
1110             t30_set_tx_selective_polling_address(chain[i].t30_state, buf);
1111             //strcpy(chain[chain[i].peer].expected_rx_info.selective_polling_address, buf);
1112             t30_set_tx_page_header_info(chain[i].t30_state, page_header_info);
1113             if (page_header_tz)
1114                 t30_set_tx_page_header_tz(chain[i].t30_state, page_header_tz);
1115 
1116             if (i != 0)
1117             {
1118                 t30_set_tx_nsf(chain[i].t30_state, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
1119                 chain[chain[i].peer].expected_rx_info.nsf = (uint8_t *) "\x50\x00\x00\x00Spandsp\x00";
1120                 chain[chain[i].peer].expected_rx_info.nsf_len = 12;
1121             }
1122 
1123             t30_set_supported_modems(chain[i].t30_state, supported_modems);
1124             t30_set_supported_t30_features(chain[i].t30_state,
1125                                            T30_SUPPORT_IDENTIFICATION
1126                                          | T30_SUPPORT_SELECTIVE_POLLING
1127                                          | T30_SUPPORT_SUB_ADDRESSING);
1128             t30_set_supported_image_sizes(chain[i].t30_state,
1129                                           T4_SUPPORT_WIDTH_215MM
1130                                         | T4_SUPPORT_WIDTH_255MM
1131                                         | T4_SUPPORT_WIDTH_303MM
1132                                         | T4_SUPPORT_LENGTH_US_LETTER
1133                                         | T4_SUPPORT_LENGTH_US_LEGAL
1134                                         | T4_SUPPORT_LENGTH_UNLIMITED);
1135             switch (allowed_bilevel_resolutions[(i == 0)  ?  0  :  1])
1136             {
1137             case 0:
1138                 /* Allow anything */
1139                 t30_set_supported_bilevel_resolutions(chain[i].t30_state,
1140                                                       T4_RESOLUTION_R8_STANDARD
1141                                                     | T4_RESOLUTION_R8_FINE
1142                                                     | T4_RESOLUTION_R8_SUPERFINE
1143                                                     | T4_RESOLUTION_R16_SUPERFINE
1144                                                     | T4_RESOLUTION_200_100
1145                                                     | T4_RESOLUTION_200_200
1146                                                     | T4_RESOLUTION_200_400
1147                                                     | T4_RESOLUTION_300_300
1148                                                     | T4_RESOLUTION_300_600
1149                                                     | T4_RESOLUTION_400_400
1150                                                     | T4_RESOLUTION_400_800
1151                                                     | T4_RESOLUTION_600_600
1152                                                     | T4_RESOLUTION_600_1200
1153                                                     | T4_RESOLUTION_1200_1200);
1154                 break;
1155             case 1:
1156                 /* Allow anything metric */
1157                 t30_set_supported_bilevel_resolutions(chain[i].t30_state,
1158                                                       T4_RESOLUTION_R8_STANDARD
1159                                                     | T4_RESOLUTION_R8_FINE
1160                                                     | T4_RESOLUTION_R8_SUPERFINE
1161                                                     | T4_RESOLUTION_R16_SUPERFINE);
1162                 break;
1163             case 2:
1164                 /* Allow anything inch based */
1165                 t30_set_supported_bilevel_resolutions(chain[i].t30_state,
1166                                                       T4_RESOLUTION_200_100
1167                                                     | T4_RESOLUTION_200_200
1168                                                     | T4_RESOLUTION_200_400
1169                                                     | T4_RESOLUTION_300_300
1170                                                     | T4_RESOLUTION_300_600
1171                                                     | T4_RESOLUTION_400_400
1172                                                     | T4_RESOLUTION_400_800
1173                                                     | T4_RESOLUTION_600_600
1174                                                     | T4_RESOLUTION_600_1200
1175                                                     | T4_RESOLUTION_1200_1200);
1176                 break;
1177             case 3:
1178                 /* Allow only restricted length resolution */
1179                 t30_set_supported_bilevel_resolutions(chain[i].t30_state,
1180                                                       T4_RESOLUTION_R8_STANDARD
1181                                                     | T4_RESOLUTION_R8_FINE
1182                                                     | T4_RESOLUTION_200_100
1183                                                     | T4_RESOLUTION_200_200);
1184                 break;
1185             case 4:
1186                 /* Allow only more restricted length resolution */
1187                 t30_set_supported_bilevel_resolutions(chain[i].t30_state,
1188                                                       T4_RESOLUTION_R8_STANDARD
1189                                                     | T4_RESOLUTION_200_100);
1190                 break;
1191             }
1192             if (colour_enabled)
1193             {
1194                 t30_set_supported_colour_resolutions(chain[i].t30_state,
1195                                                      T4_RESOLUTION_100_100
1196                                                    | T4_RESOLUTION_200_200
1197                                                    | T4_RESOLUTION_300_300
1198                                                    | T4_RESOLUTION_400_400
1199                                                    | T4_RESOLUTION_600_600
1200                                                    | T4_RESOLUTION_1200_1200);
1201             }
1202             else
1203             {
1204                 t30_set_supported_colour_resolutions(chain[i].t30_state, 0);
1205             }
1206             if (t37_like_output)
1207             {
1208                 t30_set_supported_output_compressions(chain[i].t30_state,
1209                                                       T4_COMPRESSION_T85
1210                                                     | T4_COMPRESSION_T85_L0
1211                                                     | T4_COMPRESSION_T6
1212                                                     | T4_COMPRESSION_T42_T81);
1213             }
1214             else
1215             {
1216                 t30_set_supported_output_compressions(chain[i].t30_state,
1217                                                       T4_COMPRESSION_T6
1218                                                     | T4_COMPRESSION_JPEG);
1219             }
1220 
1221             t30_set_ecm_capability(chain[i].t30_state, use_ecm);
1222             t30_set_supported_compressions(chain[i].t30_state,
1223                                            T4_COMPRESSION_T4_1D
1224                                          | T4_COMPRESSION_T4_2D
1225                                          | T4_COMPRESSION_T6
1226                                          | T4_COMPRESSION_T85
1227                                          | T4_COMPRESSION_T85_L0
1228                                          //| T4_COMPRESSION_T88
1229                                          | T4_COMPRESSION_T43
1230                                          | T4_COMPRESSION_T45
1231                                          | T4_COMPRESSION_T42_T81
1232                                          | T4_COMPRESSION_SYCC_T81
1233                                          | T4_COMPRESSION_GRAYSCALE
1234                                          | T4_COMPRESSION_COLOUR
1235                                          | T4_COMPRESSION_12BIT
1236                                          | T4_COMPRESSION_COLOUR_TO_GRAY
1237                                          | T4_COMPRESSION_GRAY_TO_BILEVEL
1238                                          | T4_COMPRESSION_COLOUR_TO_BILEVEL
1239                                          | T4_COMPRESSION_RESCALING
1240                                          | 0);
1241             t30_set_minimum_scan_line_time(chain[i].t30_state, scan_line_time);
1242         }
1243 
1244         switch (chain[i].node_type)
1245         {
1246         case AUDIO_FAX:
1247             fax_set_transmit_on_idle(chain[i].node.fax_state, use_transmit_on_idle);
1248             fax_set_tep_mode(chain[i].node.fax_state, use_tep);
1249             break;
1250         case T38_FAX:
1251             t38_set_t38_version(chain[i].t38_core_state, t38_version);
1252             //t30_set_iaf_mode(chain[i].t30_state, T30_IAF_MODE_NO_FILL_BITS);
1253             switch (t38_transport)
1254             {
1255             case T38_TRANSPORT_UDPTL:
1256             case T38_TRANSPORT_RTP:
1257                 t38_terminal_set_fill_bit_removal(chain[i].node.t38_state, remove_fill_bits);
1258                 t38_terminal_set_tep_mode(chain[i].node.t38_state, use_tep);
1259                 break;
1260             case T38_TRANSPORT_TCP:
1261             case T38_TRANSPORT_TCP_TPKT:
1262                 t38_terminal_set_fill_bit_removal(chain[i].node.t38_state, true);
1263                 t38_terminal_set_config(chain[i].node.t38_state, T38_TERMINAL_OPTION_NO_PACING | T38_TERMINAL_OPTION_NO_INDICATORS);
1264                 t38_terminal_set_tep_mode(chain[i].node.t38_state, false);
1265                 break;
1266             }
1267             break;
1268         }
1269     }
1270 
1271     for (i = 0;  i < chain_elements;  i++)
1272     {
1273         switch (chain[i].node_type)
1274         {
1275         case TSB85_AUDIO_FAX:
1276         case TSB85_T38_FAX:
1277             if (chain[chain[i].peer].node_type == AUDIO_FAX)
1278                 chain[i].node.faxtester_state->far_fax = chain[chain[i].peer].node.fax_state;
1279             else
1280                 chain[i].node.faxtester_state->far_t38 = chain[chain[i].peer].node.t38_state;
1281             chain[i].node.faxtester_state->far_t30 = chain[chain[i].peer].t30_state;
1282             chain[i].node.faxtester_state->far_tag = chain[i].peer + 'A';
1283 
1284             while (faxtester_next_step(chain[i].node.faxtester_state) == 0)
1285                 /*dummy loop*/;
1286             /*endwhile*/
1287             break;
1288         case REPLAY_AUDIO_FAX:
1289             break;
1290         case PASSTHROUGH:
1291             if (chain[i - 1].path.audio_in_buf == &chain[i].audio_buf[0])
1292                 chain[i - 1].path.audio_in_buf = &chain[i + 1].audio_buf[0];
1293             if (chain[i + 1].path.audio_in_buf == &chain[i].audio_buf[0])
1294                 chain[i + 1].path.audio_in_buf = &chain[i - 1].audio_buf[0];
1295             break;
1296         }
1297     }
1298 
1299     switch (chain[chain_elements - 1].node_type)
1300     {
1301     case AUDIO_FAX:
1302     case T38_FAX:
1303         k = (use_polled_mode)  ?  (chain_elements - 1)  :  0;
1304         if (chain[k].t30_state)
1305             t30_set_tx_file(chain[k].t30_state, input_tiff_file_name, start_page, end_page);
1306         break;
1307     }
1308     switch (chain[0].node_type)
1309     {
1310     case AUDIO_FAX:
1311     case T38_FAX:
1312         k = (use_polled_mode)  ?  0  :  (chain_elements - 1);
1313         if (chain[k].t30_state)
1314             t30_set_rx_file(chain[k].t30_state, output_tiff_file_name, -1);
1315         break;
1316     }
1317 
1318 #if defined(ENABLE_GUI)
1319     if (use_gui)
1320         start_media_monitor();
1321 #endif
1322     hist_ptr = 0;
1323     for (;;)
1324     {
1325         memset(audio_log, 0, sizeof(audio_log));
1326 
1327         for (i = 0;  i < chain_elements;  i++)
1328         {
1329             /* Update T.30 timing */
1330             switch (chain[i].node_type)
1331             {
1332             case AUDIO_FAX:
1333                 /* Update timing */
1334                 logging = t30_get_logging_state(chain[i].t30_state);
1335                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1336                 logging = fax_get_logging_state(chain[i].node.fax_state);
1337                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1338                 logging = fax_modems_get_logging_state(&chain[i].node.fax_state->modems);
1339                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1340 #if 0
1341                 /* Probe inside the modems to update their logs */
1342                 span_log_bump_samples(chain[i].node.fax_state->modems.v27ter_rx.logging, len);
1343                 span_log_bump_samples(chain[i].node.fax_state->modems.v29_rx.logging, len);
1344                 span_log_bump_samples(chain[i].node.fax_state->modems.v17_rx.logging, len);
1345 #endif
1346 
1347 #if 0
1348                 /* Mute the signal */
1349                 vec_zeroi16(chain[i].path.audio_in_buf->amp, SAMPLES_PER_CHUNK);
1350                 chain[i].path.audio_in_buf->len = SAMPLES_PER_CHUNK;
1351 #endif
1352                 if (log_audio)
1353                 {
1354                     k = (i == 0)  ?  0  :  2;
1355                     for (j = 0;  j < chain[i].path.audio_in_buf->len;  j++)
1356                         audio_log[4*j + k] = chain[i].path.audio_in_buf->amp[j];
1357                 }
1358                 fax_rx(chain[i].node.fax_state, chain[i].path.audio_in_buf->amp, chain[i].path.audio_in_buf->len);
1359                 if (!t30_call_active(chain[i].t30_state))
1360                 {
1361                     chain[i].completed = true;
1362                     continue;
1363                 }
1364 
1365                 chain[i].path.audio_out_buf->len = fax_tx(chain[i].node.fax_state, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK);
1366                 if (!use_transmit_on_idle)
1367                 {
1368                     /* The receive side always expects a full block of samples, but the
1369                        transmit side may not be sending any when it doesn't need to. We
1370                        may need to pad with some silence. */
1371                     if (chain[i].path.audio_out_buf->len < SAMPLES_PER_CHUNK)
1372                     {
1373                         vec_zeroi16(&chain[i].path.audio_out_buf->amp[chain[i].path.audio_out_buf->len], SAMPLES_PER_CHUNK - chain[i].path.audio_out_buf->len);
1374                         chain[i].path.audio_out_buf->len = SAMPLES_PER_CHUNK;
1375                     }
1376                 }
1377                 if (chain[i].awgn_state)
1378                 {
1379                     for (j = 0;  j < chain[i].path.audio_out_buf->len;  j++)
1380                         chain[i].path.audio_out_buf->amp[j] = ((int16_t) (chain[i].path.audio_out_buf->amp[j]*signal_scaling)) + awgn(chain[i].awgn_state);
1381                 }
1382                 if (log_audio)
1383                 {
1384                     k = (i == 0)  ?  1  :  3;
1385                     for (j = 0;  j < chain[i].path.audio_out_buf->len;  j++)
1386                         audio_log[4*j + k] = chain[i].path.audio_out_buf->amp[j];
1387                 }
1388                 if (feedback_audio)
1389                 {
1390                     for (j = 0;  j < chain[i].path.audio_out_buf->len;  j++)
1391                         chain[i].path.audio_out_buf->amp[j] += t38_amp_hist_a[hist_ptr][j] >> 1;
1392                     memcpy(t38_amp_hist_a[hist_ptr], chain[i].path.audio_out_buf->amp, sizeof(int16_t)*SAMPLES_PER_CHUNK);
1393                 }
1394                 break;
1395             case T38_FAX:
1396                 /* Update timing */
1397                 logging = t30_get_logging_state(chain[i].t30_state);
1398                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1399                 logging = t38_terminal_get_logging_state(chain[i].node.t38_state);
1400                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1401                 logging = t38_core_get_logging_state(chain[i].t38_core_state);
1402                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1403 
1404                 chain[i].completed = t38_terminal_send_timeout(chain[i].node.t38_state, SAMPLES_PER_CHUNK);
1405 
1406                 while ((msg_len = g1050_get(chain[i].path.g1050_path, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
1407                 {
1408 #if defined(ENABLE_GUI)
1409                     if (use_gui)
1410                         media_monitor_rx(seq_no, tx_when, rx_when);
1411 #endif
1412                     t38_core_rx_ifp_packet(chain[chain[i].t38_peer].t38_core_state, msg, msg_len, seq_no);
1413                 }
1414                 break;
1415             case TSB85_AUDIO_FAX:
1416                 /* Update timing */
1417                 logging = faxtester_get_logging_state(chain[i].node.faxtester_state);
1418                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1419 #if 0
1420                 /* Probe inside the modems to update their logs */
1421                 span_log_bump_samples(&chain[i].node.faxtester_state->modems.v27ter_rx.logging, len);
1422                 span_log_bump_samples(&chain[i].node.faxtester_state->modems.v29_rx.logging, len);
1423                 span_log_bump_samples(&chain[i].node.faxtester_state->modems.v17_rx.logging, len);
1424 #endif
1425 
1426                 if (log_audio)
1427                 {
1428                     k = (i == 0)  ?  0  :  2;
1429                     for (j = 0;  j < chain[i].path.audio_in_buf->len;  j++)
1430                         audio_log[4*j + k] = chain[i].path.audio_in_buf->amp[j];
1431                 }
1432                 faxtester_rx(chain[i].node.faxtester_state, chain[i].path.audio_in_buf->amp, chain[i].path.audio_in_buf->len);
1433                 chain[i].path.audio_out_buf->len = faxtester_tx(chain[i].node.faxtester_state, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK);
1434                 if (chain[i].path.audio_out_buf->len == 0)
1435                     break;
1436                 if (log_audio)
1437                 {
1438                     k = (i == 0)  ?  1  :  3;
1439                     for (j = 0;  j < chain[i].path.audio_out_buf->len;  j++)
1440                         audio_log[4*j + k] = chain[i].path.audio_out_buf->amp[j];
1441                 }
1442                 if (chain[i].node.faxtester_state->test_for_call_clear  &&  !chain[i].node.faxtester_state->far_end_cleared_call)
1443                 {
1444                     chain[i].node.faxtester_state->call_clear_timer += chain[i].path.audio_out_buf->len;
1445                     if (!t30_call_active(chain[i].node.faxtester_state->far_t30))
1446                     {
1447                         span_log(faxtester_get_logging_state(chain[i].node.faxtester_state),
1448                                  SPAN_LOG_FLOW,
1449                                  "Far end cleared after %dms (limits %dms to %dms)\n",
1450                                  chain[i].node.faxtester_state->call_clear_timer/8,
1451                                  chain[i].node.faxtester_state->timein_x,
1452                                  chain[i].node.faxtester_state->timeout);
1453                         if (chain[i].node.faxtester_state->call_clear_timer/8 < chain[i].node.faxtester_state->timein_x  ||  chain[i].node.faxtester_state->call_clear_timer/8 > chain[i].node.faxtester_state->timeout_x)
1454                         {
1455                             printf("Test failed\n");
1456                             exit(2);
1457                         }
1458                         span_log(faxtester_get_logging_state(chain[i].node.faxtester_state), SPAN_LOG_FLOW, "Clear time OK\n");
1459                         chain[i].node.faxtester_state->far_end_cleared_call = true;
1460                         chain[i].node.faxtester_state->test_for_call_clear = false;
1461                         while (faxtester_next_step(chain[i].node.faxtester_state) == 0)
1462                             /*dummy loop*/;
1463                         /*endwhile*/
1464                     }
1465                     /*endif*/
1466                 }
1467                 /*endif*/
1468                 break;
1469             case REPLAY_AUDIO_FAX:
1470                 chain[i].path.audio_out_buf->len = sf_readf_short(chain[i].node.wave_handle, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK);
1471                 if (chain[i].path.audio_out_buf->len == 0)
1472                     break;
1473                 break;
1474             case AUDIO_TO_T38_GATEWAY:
1475                 /* Update timing */
1476                 logging = t38_gateway_get_logging_state(chain[i].node.t38_gateway_state);
1477                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1478                 logging = t38_core_get_logging_state(chain[i].t38_core_state);
1479                 span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
1480 #if 0
1481                 /* Probe inside the modems to update their logs */
1482                 span_log_bump_samples(&chain[i].node.t38_gateway_state->modems.v27ter_rx.logging, len);
1483                 span_log_bump_samples(&chain[i].node.t38_gateway_state->modems.v29_rx.logging, len);
1484                 span_log_bump_samples(&chain[i].node.t38_gateway_state->modems.v17_rx.logging, len);
1485 #endif
1486 
1487                 if (drop_frame_rate  &&  --drop_frame == 0)
1488                 {
1489                     drop_frame = drop_frame_rate;
1490                     if (t38_gateway_rx_fillin(chain[i].node.t38_gateway_state, SAMPLES_PER_CHUNK))
1491                         break;
1492                 }
1493                 else
1494                 {
1495                     if (t38_gateway_rx(chain[i].node.t38_gateway_state, chain[i].path.audio_in_buf->amp, chain[i].path.audio_in_buf->len))
1496                         break;
1497                 }
1498 
1499                 chain[i].path.audio_out_buf->len = t38_gateway_tx(chain[i].node.t38_gateway_state, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK);
1500                 if (!use_transmit_on_idle)
1501                 {
1502                     if (chain[i].path.audio_out_buf->len < SAMPLES_PER_CHUNK)
1503                     {
1504                         vec_zeroi16(&chain[i].path.audio_out_buf->amp[chain[i].path.audio_out_buf->len], SAMPLES_PER_CHUNK - chain[i].path.audio_out_buf->len);
1505                         chain[i].path.audio_out_buf->len = SAMPLES_PER_CHUNK;
1506                     }
1507                 }
1508                 if (feedback_audio)
1509                 {
1510                     for (j = 0;  j < chain[i].path.audio_out_buf->len;  j++)
1511                         chain[i].path.audio_out_buf->amp[j] += t38_amp_hist_a[hist_ptr][j] >> 1;
1512                     vec_movei16(t38_amp_hist_a[hist_ptr], chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK);
1513                 }
1514 
1515 #if 0
1516                 if (log_audio)
1517                 {
1518                     k = (i == 0)  ?  1  :  3;
1519                     for (j = 0;  j < chain[i].path.audio_out_buf->len;  j++)
1520                         audio_log[4*j + k] = chain[i].path.audio_out_buf->amp[j];
1521                 }
1522 #endif
1523                 while ((msg_len = g1050_get(chain[i].path.g1050_path, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
1524                 {
1525 #if defined(ENABLE_GUI)
1526                     if (use_gui)
1527                         media_monitor_rx(seq_no, tx_when, rx_when);
1528 #endif
1529                     t38_core_rx_ifp_packet(chain[chain[i].t38_peer].t38_core_state, msg, msg_len, seq_no);
1530                 }
1531                 break;
1532             }
1533         }
1534         if (log_audio)
1535         {
1536             outframes = sf_writef_short(wave_handle, audio_log, SAMPLES_PER_CHUNK);
1537             if (outframes != SAMPLES_PER_CHUNK)
1538                 break;
1539         }
1540 
1541         when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;
1542 
1543         if (chain[0].completed  &&  chain[chain_elements - 1].completed)
1544             break;
1545 #if defined(ENABLE_GUI)
1546         if (use_gui)
1547             media_monitor_update_display();
1548 #endif
1549         if (++hist_ptr > 3)
1550             hist_ptr = 0;
1551     }
1552 
1553     for (i = 0;  i < chain_elements;  i++)
1554     {
1555         switch (chain[i].node_type)
1556         {
1557         case AUDIO_TO_T38_GATEWAY:
1558             t38_gateway_get_transfer_statistics(chain[i].node.t38_gateway_state, &t38_stats);
1559             printf("%c side exchanged %d pages at %dbps, in %s mode\n",
1560                    i + 'A',
1561                    t38_stats.pages_transferred,
1562                    t38_stats.bit_rate,
1563                    (t38_stats.error_correcting_mode)  ?  "ECM"  :  "non-ECM");
1564             break;
1565         }
1566     }
1567     if (log_audio)
1568     {
1569         if (sf_close_telephony(wave_handle))
1570         {
1571             fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
1572             exit(2);
1573         }
1574     }
1575 
1576     /* Check how many pages should have been transferred */
1577     expected_pages = get_tiff_total_pages(input_tiff_file_name);
1578     if (end_page >= 0  &&  expected_pages > end_page + 1)
1579         expected_pages = end_page + 1;
1580     if (start_page >= 0)
1581         expected_pages -= start_page;
1582     /* Check how many pages were transferred */
1583     for (j = 0;  j < 2;  j++)
1584     {
1585         i = (j == 0)  ?  0  :  (chain_elements - 1);
1586         if (!chain[i].phase_e_reached)
1587             break;
1588         if (!chain[i].succeeded)
1589             break;
1590 
1591         t30_get_transfer_statistics(chain[i].t30_state, &t30_stats);
1592         if ((!use_polled_mode  &&  i != 0)  ||  (use_polled_mode  &&  i == 0))
1593         {
1594             if (t30_stats.pages_tx != 0  ||  t30_stats.pages_rx != expected_pages)
1595                 break;
1596         }
1597         else
1598         {
1599             if (t30_stats.pages_tx != expected_pages  ||  t30_stats.pages_rx != 0)
1600                 break;
1601         }
1602     }
1603     for (i = 0;  i < chain_elements;  i++)
1604     {
1605         switch (chain[i].node_type)
1606         {
1607         case AUDIO_FAX:
1608             fax_free(chain[i].node.fax_state);
1609             break;
1610         case T38_FAX:
1611             t38_terminal_free(chain[i].node.t38_state);
1612             break;
1613         case TSB85_AUDIO_FAX:
1614         case TSB85_T38_FAX:
1615             faxtester_free(chain[i].node.faxtester_state);
1616             break;
1617         case REPLAY_AUDIO_FAX:
1618             if (sf_close_telephony(chain[i].node.wave_handle))
1619             {
1620                 fprintf(stderr, "    Cannot close audio file '%s'\n", replay_file_name);
1621                 exit(2);
1622             }
1623             chain[i].node.wave_handle = NULL;
1624             break;
1625         case AUDIO_TO_T38_GATEWAY:
1626             t38_gateway_free(chain[i].node.t38_gateway_state);
1627             break;
1628         }
1629         if (chain[i].path.g1050_path)
1630         {
1631             g1050_free(chain[i].path.g1050_path);
1632             chain[i].path.g1050_path = NULL;
1633         }
1634     }
1635     if (j < 2)
1636     {
1637         printf("Tests failed\n");
1638         exit(2);
1639     }
1640     t33_tests();
1641     printf("Tests passed\n");
1642     return 0;
1643 }
1644 /*- End of function --------------------------------------------------------*/
1645 /*- End of file ------------------------------------------------------------*/
1646