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