1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * t31_pseudo_terminal_tests.c -
5  *
6  * Written by Steve Underwood <steveu@coppice.org>
7  *
8  * Copyright (C) 2012 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 #include <inttypes.h>
27 #include <stdlib.h>
28 
29 #if defined(WIN32)
30 #include <windows.h>
31 #else
32 #if defined(__APPLE__)
33 #include <util.h>
34 #include <sys/ioctl.h>
35 #elif defined(__FreeBSD__)
36 #include <libutil.h>
37 #include <termios.h>
38 #include <sys/socket.h>
39 #else
40 #include <pty.h>
41 #endif
42 #include <unistd.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <poll.h>
46 #endif
47 
48 #include "spandsp.h"
49 
50 #include "spandsp-sim.h"
51 
52 #undef SPANDSP_EXPOSE_INTERNAL_STRUCTURES
53 
54 #include "pseudo_terminals.h"
55 
56 #if defined(ENABLE_GUI)
57 #include "media_monitor.h"
58 #endif
59 #include "fax_utils.h"
60 
61 #define INPUT_FILE_NAME         "../test-data/itu/fax/itutests.tif"
62 #define OUTPUT_FILE_NAME        "t31_pseudo_terminal.tif"
63 #define OUTPUT_WAVE_FILE_NAME   "t31_tests.wav"
64 
65 #define MANUFACTURER            "www.soft-switch.org"
66 
67 #define SAMPLES_PER_CHUNK 160
68 
69 typedef enum
70 {
71     MODEM_POLL_READ = (1 << 0),
72     MODEM_POLL_WRITE = (1 << 1),
73     MODEM_POLL_ERROR = (1 << 2)
74 } modem_poll_t;
75 
76 g1050_state_t *path_a_to_b;
77 g1050_state_t *path_b_to_a;
78 
79 double when = 0.0;
80 
81 int t38_mode = false;
82 
83 struct modem_s modem[10];
84 
85 char *decode_test_file = NULL;
86 int countdown = 0;
87 int answered = 0;
88 int done = false;
89 
90 int test_seq_ptr = 0;
91 
92 t31_state_t *t31_state;
93 
phase_b_handler(void * user_data,int result)94 static int phase_b_handler(void *user_data, int result)
95 {
96     int ch;
97     t30_state_t *s;
98     char tag[20];
99 
100     ch = 'A';
101     s = (t30_state_t *) user_data;
102     snprintf(tag, sizeof(tag), "%c: Phase B", ch);
103     printf("%c: Phase B handler on channel %c - (0x%X) %s\n", ch, ch, result, t30_frametype(result));
104     fax_log_rx_parameters(s, tag);
105     return T30_ERR_OK;
106 }
107 /*- End of function --------------------------------------------------------*/
108 
phase_d_handler(void * user_data,int result)109 static int phase_d_handler(void *user_data, int result)
110 {
111     int ch;
112     t30_state_t *s;
113     char tag[20];
114 
115     ch = 'A';
116     s = (t30_state_t *) user_data;
117     snprintf(tag, sizeof(tag), "%c: Phase D", ch);
118     printf("%c: Phase D handler on channel %c - (0x%X) %s\n", ch, ch, result, t30_frametype(result));
119     fax_log_page_transfer_statistics(s, tag);
120     fax_log_tx_parameters(s, tag);
121     fax_log_rx_parameters(s, tag);
122     return T30_ERR_OK;
123 }
124 /*- End of function --------------------------------------------------------*/
125 
phase_e_handler(void * user_data,int result)126 static void phase_e_handler(void *user_data, int result)
127 {
128     int ch;
129     t30_state_t *s;
130     char tag[20];
131 
132     ch = 'A';
133     s = (t30_state_t *) user_data;
134     snprintf(tag, sizeof(tag), "%c: Phase E", ch);
135     printf("Phase E handler on channel %c\n", ch);
136     fax_log_final_transfer_statistics(s, tag);
137     fax_log_tx_parameters(s, tag);
138     fax_log_rx_parameters(s, tag);
139 }
140 /*- End of function --------------------------------------------------------*/
141 
at_tx_handler(void * user_data,const uint8_t * buf,size_t len)142 static int at_tx_handler(void *user_data, const uint8_t *buf, size_t len)
143 {
144 #if defined(WIN32)
145     DWORD res;
146     OVERLAPPED o;
147 #else
148     int res;
149 #endif
150     modem_t *modem;
151 
152 int i;
153 
154 printf("YYZ %d - ", (int) len);
155 for (i = 0;  i < len;  i++)
156     printf(" 0x%02x", buf[i]);
157 printf("\n");
158 
159     modem = (modem_t *) user_data;
160 #if defined(WIN32)
161     o.hEvent = CreateEvent(NULL, true, false, NULL);
162     /* Initialize the rest of the OVERLAPPED structure to zero. */
163     o.Internal = 0;
164     o.InternalHigh = 0;
165     o.Offset = 0;
166     o.OffsetHigh = 0;
167     assert(o.hEvent);
168     if (!WriteFile(modem->master, buf, (DWORD) len, &res, &o))
169         GetOverlappedResult(modem->master, &o, &res, true);
170     CloseHandle(o.hEvent);
171 #else
172     res = write(modem->master, buf, len);
173 #endif
174     if (res != len)
175     {
176         printf("Failed to write the whole buffer to the device. %d bytes of %d written: %s\n", res, (int) len, strerror(errno));
177 
178         if (res == -1)
179             res = 0;
180 #if !defined(WIN32)
181         if (tcflush(modem->master, TCOFLUSH))
182             printf("Unable to flush pty master buffer: %s\n", strerror(errno));
183         else if (tcflush(modem->slave, TCOFLUSH))
184             printf("Unable to flush pty slave buffer: %s\n", strerror(errno));
185         else
186             printf("Successfully flushed pty buffer\n");
187 #endif
188     }
189     return 0;
190 }
191 /*- End of function --------------------------------------------------------*/
192 
t31_call_control(t31_state_t * s,void * user_data,int op,const char * num)193 static int t31_call_control(t31_state_t *s, void *user_data, int op, const char *num)
194 {
195     uint8_t x[2];
196     modem_t *modem;
197 
198     printf("Modem control - %s", at_modem_control_to_str(op));
199     modem = (modem_t *) user_data;
200     switch (op)
201     {
202     case AT_MODEM_CONTROL_CALL:
203         printf(" %s", num);
204         t31_call_event(t31_state, AT_CALL_EVENT_CONNECTED);
205         answered = 2;
206         break;
207     case AT_MODEM_CONTROL_ANSWER:
208         answered = 1;
209         break;
210     case AT_MODEM_CONTROL_HANGUP:
211         //done = true;
212         break;
213     case AT_MODEM_CONTROL_OFFHOOK:
214         break;
215     case AT_MODEM_CONTROL_DTR:
216         printf(" %d", (int) (intptr_t) num);
217         break;
218     case AT_MODEM_CONTROL_RTS:
219         printf(" %d", (int) (intptr_t) num);
220         break;
221     case AT_MODEM_CONTROL_CTS:
222         printf(" %d", (int) (intptr_t) num);
223         /* Use XON/XOFF characters for flow control */
224         switch (t31_state->at_state.dte_dce_flow_control)
225         {
226         case 1:
227             x[0] = (num)  ?  0x11  :  0x13;
228             at_tx_handler(user_data, x, 1);
229             break;
230         case 2:
231             break;
232         }
233         /*endswitch*/
234         modem->block_read = (num == NULL);
235         break;
236     case AT_MODEM_CONTROL_CAR:
237         printf(" %d", (int) (intptr_t) num);
238         break;
239     case AT_MODEM_CONTROL_RNG:
240         printf(" %d", (int) (intptr_t) num);
241         break;
242     case AT_MODEM_CONTROL_DSR:
243         printf(" %d", (int) (intptr_t) num);
244         break;
245     case AT_MODEM_CONTROL_SETID:
246         printf(" %d", (int) (intptr_t) num);
247         break;
248     case AT_MODEM_CONTROL_RESTART:
249         printf(" %d", (int) (intptr_t) num);
250         break;
251     case AT_MODEM_CONTROL_DTE_TIMEOUT:
252         printf(" %d", (int) (intptr_t) num);
253         break;
254     }
255     /*endswitch*/
256     printf("\n");
257     return 0;
258 }
259 /*- End of function --------------------------------------------------------*/
260 
t38_tx_packet_handler(t38_core_state_t * s,void * user_data,const uint8_t * buf,int len,int count)261 static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
262 {
263     int i;
264 
265     /* This routine queues messages between two instances of T.38 processing, from the T.38 terminal side. */
266     span_log(t38_core_get_logging_state(s), SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count);
267 
268     for (i = 0;  i < count;  i++)
269     {
270         if (g1050_put(path_a_to_b, buf, len, s->tx_seq_no, when) < 0)
271             printf("Lost packet %d\n", s->tx_seq_no);
272     }
273     return 0;
274 }
275 /*- End of function --------------------------------------------------------*/
276 
t31_tx_packet_handler(t38_core_state_t * s,void * user_data,const uint8_t * buf,int len,int count)277 static int t31_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
278 {
279     int i;
280 
281     /* This routine queues messages between two instances of T.38 processing, from the T.31 modem side. */
282     span_log(t38_core_get_logging_state(s), SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count);
283 
284     for (i = 0;  i < count;  i++)
285     {
286         if (g1050_put(path_b_to_a, buf, len, s->tx_seq_no, when) < 0)
287             printf("Lost packet %d\n", s->tx_seq_no);
288     }
289     return 0;
290 }
291 /*- End of function --------------------------------------------------------*/
292 
293 #if defined(WIN32)
modem_wait_sock(modem_t * modem,int ms,modem_poll_t flags)294 static int modem_wait_sock(modem_t *modem, int ms, modem_poll_t flags)
295 {
296     /* This method ignores ms and waits infinitely */
297     DWORD dwEvtMask;
298     DWORD dwWait;
299     DWORD comerrors;
300     OVERLAPPED o;
301     BOOL result;
302     int ret;
303     HANDLE arHandles[2];
304 
305     ret = MODEM_POLL_ERROR;
306     arHandles[0] = modem->threadAbort;
307 
308     o.hEvent = CreateEvent(NULL, true, false, NULL);
309     arHandles[1] = o.hEvent;
310 
311     /* Initialize the rest of the OVERLAPPED structure to zero. */
312     o.Internal = 0;
313     o.InternalHigh = 0;
314     o.Offset = 0;
315     o.OffsetHigh = 0;
316     assert(o.hEvent);
317 
318     if ((result = WaitCommEvent(modem->master, &dwEvtMask, &o)) == 0)
319     {
320         if (GetLastError() != ERROR_IO_PENDING)
321         {
322             /* Something went horribly wrong with WaitCommEvent(), so
323                clear all errors and try again */
324             ClearCommError(modem->master, &comerrors, 0);
325         }
326         else
327         {
328             /* IO is pending, wait for it to finish */
329             dwWait = WaitForMultipleObjects(2, arHandles, false, INFINITE);
330             if (dwWait == WAIT_OBJECT_0 + 1  &&  !modem->block_read)
331                 ret = MODEM_POLL_READ;
332         }
333     }
334     else
335     {
336         if (!modem->block_read)
337             ret = MODEM_POLL_READ;
338     }
339 
340     CloseHandle (o.hEvent);
341     return ret;
342 }
343 /*- End of function --------------------------------------------------------*/
344 #else
modem_wait_sock(int sock,uint32_t ms,modem_poll_t flags)345 static int modem_wait_sock(int sock, uint32_t ms, modem_poll_t flags)
346 {
347     struct pollfd pfds[2] = {{0}};
348     int s;
349     int ret;
350 
351     pfds[0].fd = sock;
352 
353     if ((flags & MODEM_POLL_READ))
354         pfds[0].events |= POLLIN;
355     if ((flags & MODEM_POLL_WRITE))
356         pfds[0].events |= POLLOUT;
357     if ((flags & MODEM_POLL_ERROR))
358         pfds[0].events |= POLLERR;
359 
360     s = poll(pfds, (modem->block_read)  ?  0  :  1, ms);
361 
362     ret = 0;
363     if (s < 0)
364     {
365         ret = s;
366     }
367     else if (s > 0)
368     {
369         if ((pfds[0].revents & POLLIN))
370             ret |= MODEM_POLL_READ;
371         if ((pfds[0].revents & POLLOUT))
372             ret |= MODEM_POLL_WRITE;
373         if ((pfds[0].revents & POLLERR))
374             ret |= MODEM_POLL_ERROR;
375     }
376 
377     return ret;
378 
379 }
380 /*- End of function --------------------------------------------------------*/
381 #endif
382 
t30_tests(int t38_mode,int use_ecm,int use_gui,int log_audio,int test_sending,int g1050_model_no,int g1050_speed_pattern_no)383 static int t30_tests(int t38_mode, int use_ecm, int use_gui, int log_audio, int test_sending, int g1050_model_no, int g1050_speed_pattern_no)
384 {
385     t38_terminal_state_t *t38_state;
386     fax_state_t *fax_state;
387     uint8_t msg[1024];
388     char buf[1024];
389     int len;
390     int msg_len;
391     int t30_len;
392     int t31_len;
393     int t38_version;
394     int without_pacing;
395     int use_tep;
396     int seq_no;
397     double tx_when;
398     double rx_when;
399     t30_state_t *t30;
400     t38_core_state_t *t38_core;
401     logging_state_t *logging;
402     int k;
403     int outframes;
404     int ret;
405     int16_t t30_amp[SAMPLES_PER_CHUNK];
406     int16_t t31_amp[SAMPLES_PER_CHUNK];
407     int16_t silence[SAMPLES_PER_CHUNK];
408     int16_t out_amp[2*SAMPLES_PER_CHUNK];
409     SNDFILE *wave_handle;
410     SNDFILE *in_handle;
411     at_state_t *at_state;
412 #if defined(WIN32)
413     DWORD read_bytes;
414     OVERLAPPED o;
415 #endif
416 
417     /* Test the T.31 modem against the full FAX machine in spandsp */
418 
419     /* Set up the test environment */
420     t38_version = 1;
421     without_pacing = false;
422     use_tep = false;
423 
424     wave_handle = NULL;
425     if (log_audio)
426     {
427         if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
428         {
429             fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
430             exit(2);
431         }
432     }
433 
434     in_handle = NULL;
435     if (decode_test_file)
436     {
437         if ((in_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
438         {
439             fprintf(stderr, "    Cannot create audio file '%s'\n", decode_test_file);
440             exit(2);
441         }
442     }
443 
444     srand48(0x1234567);
445     if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
446     {
447         fprintf(stderr, "Failed to start IP network path model\n");
448         exit(2);
449     }
450     if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
451     {
452         fprintf(stderr, "Failed to start IP network path model\n");
453         exit(2);
454     }
455 
456     t38_state = NULL;
457     fax_state = NULL;
458     if (test_sending)
459     {
460         if (t38_mode)
461         {
462             if ((t38_state = t38_terminal_init(NULL, false, t38_tx_packet_handler, t31_state)) == NULL)
463             {
464                 fprintf(stderr, "Cannot start the T.38 channel\n");
465                 exit(2);
466             }
467             t30 = t38_terminal_get_t30_state(t38_state);
468         }
469         else
470         {
471             fax_state = fax_init(NULL, false);
472             t30 = fax_get_t30_state(fax_state);
473         }
474         t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1);
475         countdown = 0;
476     }
477     else
478     {
479         if (t38_mode)
480         {
481             if ((t38_state = t38_terminal_init(NULL, true, t38_tx_packet_handler, t31_state)) == NULL)
482             {
483                 fprintf(stderr, "Cannot start the T.38 channel\n");
484                 exit(2);
485             }
486             t30 = t38_terminal_get_t30_state(t38_state);
487         }
488         else
489         {
490             fax_state = fax_init(NULL, true);
491             t30 = fax_get_t30_state(fax_state);
492         }
493         t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1);
494         countdown = 250;
495     }
496 
497     t30_set_ecm_capability(t30, use_ecm);
498 
499     if (t38_mode)
500     {
501         t38_core = t38_terminal_get_t38_core_state(t38_state);
502         t38_set_t38_version(t38_core, t38_version);
503         t38_terminal_set_config(t38_state, without_pacing);
504         t38_terminal_set_tep_mode(t38_state, use_tep);
505     }
506 
507     t30_set_tx_ident(t30, "11111111");
508     t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
509     //t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
510     t30_set_phase_b_handler(t30, phase_b_handler, (void *) t30);
511     t30_set_phase_d_handler(t30, phase_d_handler, (void *) t30);
512     t30_set_phase_e_handler(t30, phase_e_handler, (void *) t30);
513 
514     if (t38_mode)
515         logging = t38_terminal_get_logging_state(t38_state);
516     else
517         logging = t30_get_logging_state(t30);
518     span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
519     span_log_set_tag(logging, (t38_mode)  ?  "T.38"  :  "FAX");
520 
521     if (t38_mode)
522     {
523         t38_core = t38_terminal_get_t38_core_state(t38_state);
524         logging = t38_core_get_logging_state(t38_core);
525         span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
526         span_log_set_tag(logging, "T.38");
527 
528         logging = t30_get_logging_state(t30);
529         span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
530         span_log_set_tag(logging, "T.38");
531     }
532     else
533     {
534         logging = fax_get_logging_state(fax_state);
535         span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
536         span_log_set_tag(logging, "FAX");
537     }
538 
539     memset(silence, 0, sizeof(silence));
540     memset(t30_amp, 0, sizeof(t30_amp));
541 
542     /* Now set up and run the T.31 modem */
543     if ((t31_state = t31_init(NULL, at_tx_handler, &modem[0], t31_call_control, &modem[0], t31_tx_packet_handler, NULL)) == NULL)
544     {
545         fprintf(stderr, "    Cannot start the T.31 modem\n");
546         exit(2);
547     }
548     at_state = t31_get_at_state(t31_state);
549 
550     logging = t31_get_logging_state(t31_state);
551     span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
552     span_log_set_tag(logging, "T.31");
553 
554     logging = at_get_logging_state(at_state);
555     span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
556     span_log_set_tag(logging, "T.31");
557 
558     if (t38_mode)
559     {
560         t38_core = t31_get_t38_core_state(t31_state);
561         logging = t38_core_get_logging_state(t38_core);
562         span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
563         span_log_set_tag(logging, "T.31");
564 
565         t31_set_mode(t31_state, true);
566         t38_set_t38_version(t38_core, t38_version);
567     }
568 
569     at_reset_call_info(at_state);
570     at_set_call_info(at_state, "DATE", "1231");
571     at_set_call_info(at_state, "TIME", "1200");
572     at_set_call_info(at_state, "NAME", "Name");
573     at_set_call_info(at_state, "NMBR", "123456789");
574     at_set_call_info(at_state, "ANID", "987654321");
575     at_set_call_info(at_state, "USER", "User");
576     at_set_call_info(at_state, "CDID", "234567890");
577     at_set_call_info(at_state, "NDID", "345678901");
578 
579 #if defined(ENABLE_GUI)
580     if (use_gui)
581         start_media_monitor();
582 #endif
583 
584     while (!done)
585     {
586         /* Deal with call setup, through the AT interface. */
587         if (test_sending)
588         {
589         }
590         else
591         {
592             if (answered == 0)
593             {
594                 if (--countdown == 0)
595                 {
596                     t31_call_event(t31_state, AT_CALL_EVENT_ALERTING);
597                     countdown = 250;
598                 }
599             }
600             else if (answered == 1)
601             {
602 printf("ZZZ\n");
603                 answered = 2;
604                 t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED);
605             }
606         }
607 
608         ret = modem_wait_sock(modem[0].master, 20, MODEM_POLL_READ);
609         if ((ret & MODEM_POLL_READ))
610         {
611 #if defined(WIN32)
612             o.hEvent = CreateEvent(NULL, true, false, NULL);
613 
614             /* Initialize the rest of the OVERLAPPED structure to zero. */
615             o.Internal = 0;
616             o.InternalHigh = 0;
617             o.Offset = 0;
618             o.OffsetHigh = 0;
619             assert(o.hEvent);
620             if (!ReadFile(modem->master, buf, avail, &read_bytes, &o))
621                 GetOverlappedResult(modem->master, &o, &read_bytes, true);
622             CloseHandle (o.hEvent);
623             if ((len = read_bytes))
624 #else
625             if ((len = read(modem[0].master, buf, 1024)))
626 #endif
627 {
628 int i;
629 
630 printf("YYY %d - ", len);
631 for (i = 0;  i < len;  i++)
632     printf(" 0x%02x", buf[i] & 0xFF);
633 printf("\n");
634                 t31_at_rx(t31_state, buf, len);
635 }
636         }
637 
638         if (answered == 2)
639         {
640             if (t38_mode)
641             {
642                 while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
643                 {
644 #if defined(ENABLE_GUI)
645                     if (use_gui)
646                         media_monitor_rx(seq_no, tx_when, rx_when);
647 #endif
648                     t38_core = t31_get_t38_core_state(t31_state);
649                     t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
650                 }
651                 while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
652                 {
653 #if defined(ENABLE_GUI)
654                     if (use_gui)
655                         media_monitor_rx(seq_no, tx_when, rx_when);
656 #endif
657                     t38_core = t38_terminal_get_t38_core_state(t38_state);
658                     t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
659                 }
660 #if defined(ENABLE_GUI)
661                 if (use_gui)
662                     media_monitor_update_display();
663 #endif
664                 /* Bump the G.1050 models along */
665                 when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;
666 
667                 /* Bump things along on the t38_terminal side */
668                 span_log_bump_samples(t38_terminal_get_logging_state(t38_state), SAMPLES_PER_CHUNK);
669                 t38_core = t38_terminal_get_t38_core_state(t38_state);
670                 span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);
671 
672                 t38_terminal_send_timeout(t38_state, SAMPLES_PER_CHUNK);
673                 t31_t38_send_timeout(t31_state, SAMPLES_PER_CHUNK);
674             }
675             else
676             {
677                 t30_len = fax_tx(fax_state, t30_amp, SAMPLES_PER_CHUNK);
678                 /* The receive side always expects a full block of samples, but the
679                    transmit side may not be sending any when it doesn't need to. We
680                    may need to pad with some silence. */
681                 if (t30_len < SAMPLES_PER_CHUNK)
682                 {
683                     memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len));
684                     t30_len = SAMPLES_PER_CHUNK;
685                 }
686                 if (log_audio)
687                 {
688                     for (k = 0;  k < t30_len;  k++)
689                         out_amp[2*k] = t30_amp[k];
690                 }
691                 if (t31_rx(t31_state, t30_amp, t30_len))
692                     break;
693                 t31_len = t31_tx(t31_state, t31_amp, SAMPLES_PER_CHUNK);
694                 if (t31_len < SAMPLES_PER_CHUNK)
695                 {
696                     memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len));
697                     t31_len = SAMPLES_PER_CHUNK;
698                 }
699                 if (log_audio)
700                 {
701                     for (k = 0;  k < t31_len;  k++)
702                         out_amp[2*k + 1] = t31_amp[k];
703                 }
704                 if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK))
705                     break;
706 
707                 if (log_audio)
708                 {
709                     outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
710                     if (outframes != SAMPLES_PER_CHUNK)
711                         break;
712                 }
713 
714                 /* Bump things along on the FAX machine side */
715                 span_log_bump_samples(fax_get_logging_state(fax_state), SAMPLES_PER_CHUNK);
716             }
717             /* Bump things along on the FAX machine side */
718             span_log_bump_samples(t30_get_logging_state(t30), SAMPLES_PER_CHUNK);
719 
720             /* Bump things along on the T.31 modem side */
721             t38_core = t31_get_t38_core_state(t31_state);
722             span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);
723             span_log_bump_samples(t31_get_logging_state(t31_state), SAMPLES_PER_CHUNK);
724             span_log_bump_samples(at_get_logging_state(t31_get_at_state(t31_state)), SAMPLES_PER_CHUNK);
725         }
726     }
727 
728     if (t38_mode)
729         t38_terminal_release(t38_state);
730 
731     if (decode_test_file)
732     {
733         if (sf_close_telephony(in_handle))
734         {
735             fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
736             exit(2);
737         }
738     }
739     if (log_audio)
740     {
741         if (sf_close_telephony(wave_handle))
742         {
743             fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
744             exit(2);
745         }
746     }
747 
748     if (!done)
749     {
750         printf("Tests failed\n");
751         return 2;
752     }
753 
754     return 0;
755 }
756 /*- End of function --------------------------------------------------------*/
757 
main(int argc,char * argv[])758 int main(int argc, char *argv[])
759 {
760     int log_audio;
761     int t38_mode;
762     int test_sending;
763     int use_ecm;
764     int use_gui;
765     int g1050_model_no;
766     int g1050_speed_pattern_no;
767     int opt;
768 #if !defined(WIN32)
769     int tioflags;
770 #endif
771 
772     decode_test_file = NULL;
773     log_audio = false;
774     test_sending = false;
775     t38_mode = false;
776     use_ecm = false;
777     use_gui = false;
778     g1050_model_no = 0;
779     g1050_speed_pattern_no = 1;
780     while ((opt = getopt(argc, argv, "d:eglM:rS:st")) != -1)
781     {
782         switch (opt)
783         {
784         case 'd':
785             decode_test_file = optarg;
786             break;
787         case 'e':
788             use_ecm = true;
789             break;
790         case 'g':
791 #if defined(ENABLE_GUI)
792             use_gui = true;
793 #else
794             fprintf(stderr, "Graphical monitoring not available\n");
795             exit(2);
796 #endif
797             break;
798         case 'l':
799             log_audio = true;
800             break;
801         case 'M':
802             g1050_model_no = optarg[0] - 'A' + 1;
803             break;
804         case 'r':
805             test_sending = false;
806             break;
807         case 'S':
808             g1050_speed_pattern_no = atoi(optarg);
809             break;
810         case 's':
811             test_sending = true;
812             break;
813         case 't':
814             t38_mode = true;
815             break;
816         default:
817             //usage();
818             exit(2);
819             break;
820         }
821     }
822 
823     if (pseudo_terminal_create(&modem[0]))
824         printf("Failure\n");
825 
826 #if !defined(WIN32)
827     ioctl(modem[0].slave, TIOCMGET, &tioflags);
828     tioflags |= TIOCM_RI;
829     ioctl(modem[0].slave, TIOCMSET, &tioflags);
830 #endif
831 
832     t30_tests(t38_mode, use_ecm, use_gui, log_audio, test_sending, g1050_model_no, g1050_speed_pattern_no);
833     if (pseudo_terminal_close(&modem[0]))
834         printf("Failure\n");
835     printf("Tests passed\n");
836     return 0;
837 }
838 /*- End of function --------------------------------------------------------*/
839 /*- End of file ------------------------------------------------------------*/
840