1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * t31_tests.c - Tests for the T.31 modem.
5  *
6  * Written by Steve Underwood <steveu@coppice.org>
7  *
8  * Copyright (C) 2004 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 t31_tests_page T.31 tests
29 \section t31_tests_page_sec_1 What does it do?
30 */
31 
32 #if defined(HAVE_CONFIG_H)
33 #include "config.h"
34 #endif
35 
36 #if defined(HAVE_FL_FL_H)  &&  defined(HAVE_FL_FL_CARTESIAN_H)  &&  defined(HAVE_FL_FL_AUDIO_METER_H)
37 #define ENABLE_GUI
38 #endif
39 
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <fcntl.h>
43 #include <unistd.h>
44 #include <string.h>
45 #include <assert.h>
46 #include <sndfile.h>
47 
48 #include "spandsp.h"
49 #include "spandsp/t30_fcf.h"
50 #include "spandsp-sim.h"
51 
52 #if defined(ENABLE_GUI)
53 #include "media_monitor.h"
54 #endif
55 #include "fax_utils.h"
56 
57 #define INPUT_FILE_NAME         "../test-data/itu/fax/itu1.tif"
58 #define OUTPUT_FILE_NAME        "t31.tif"
59 #define OUTPUT_WAVE_FILE_NAME   "t31_tests.wav"
60 
61 enum
62 {
63     ETX = 0x03,
64     DLE = 0x10,
65     SUB = 0x1A
66 };
67 
68 #define MANUFACTURER            "www.soft-switch.org"
69 
70 #define SAMPLES_PER_CHUNK 160
71 
72 struct command_response_s
73 {
74     const char *command;
75     int len_command;
76     const char *response;
77     int len_response;
78 };
79 
80 g1050_state_t *path_a_to_b;
81 g1050_state_t *path_b_to_a;
82 
83 double when = 0.0;
84 
85 int t38_mode = false;
86 
87 #define EXCHANGE(a,b) {a, sizeof(a) - 1, b, sizeof(b) - 1}
88 #define RESPONSE(b) {"", 0, b, sizeof(b) - 1}
89 #define FAST_RESPONSE(b) {NULL, -1, b, sizeof(b) - 1}
90 #define FAST_SEND(b) {(const char *) 1, -2, b, sizeof(b) - 1}
91 #define FAST_SEND_TCF(b) {(const char *) 2, -2, b, sizeof(b) - 1}
92 #define END_OF_SEQUENCE {NULL, -1, NULL, -1}
93 
94 static const struct command_response_s fax_send_test_seq[] =
95 {
96     EXCHANGE("ATE0\r", "ATE0\r\r\nOK\r\n"),
97     EXCHANGE("AT+FCLASS=1\r", "\r\nOK\r\n"),
98     EXCHANGE("ATD123456789\r", "\r\nCONNECT\r\n"),
99     //<NSF frame>         AT+FRH=3 is implied when dialing in the AT+FCLASS=1 state
100     //RESPONSE("\xFF\x03\x10\x03"),
101     //RESPONSE("\r\nOK\r\n"),
102     //EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
103     //<CSI frame data>
104     RESPONSE("\xFF\x03\x40\x31\x31\x31\x31\x31\x31\x31\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1e\x46\x10\x03"),
105     RESPONSE("\r\nOK\r\n"),
106     EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
107     //<DIS frame data>
108 #if 1
109     RESPONSE("\xFF\x13\x80\x00\xEE\xF8\x80\x80\x99\x80\x80\x80\x18\x58\x0D\x10\x03"),   // For audio FAXing
110 #else
111     RESPONSE("\xFF\x13\x80\x04\xEE\xF8\x80\x80\x99\x80\x80\x80\x18\xC4\xBD\x10\x03"),   // For T.38 FAXing
112 #endif
113     RESPONSE("\r\nOK\r\n"),
114     //EXCHANGE("AT+FRH=3\r", "\r\nNO CARRIER\r\n"),
115     EXCHANGE("AT+FTH=3\r", "\r\nCONNECT\r\n"),
116     //<TSI frame data>
117     EXCHANGE("\xFF\x03\x43\x32\x32\x32\x32\x32\x32\x32\x32\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x10\x03", "\r\nCONNECT\r\n"),
118     //<DCS frame data>
119     EXCHANGE("\xFF\x13\x83\x01\xC6\x80\x80\x80\x80\x01\x10\x03", "\r\nOK\r\n"),
120     //Do a wait for timed silence at this point, or there won't be one in the tests
121     EXCHANGE("AT+FRS=7\r", "\r\nOK\r\n"),
122     //EXCHANGE("AT+FTS=8;+FTM=96\r", "\r\nCONNECT\r\n"),
123     EXCHANGE("AT+FTS=8\r", "\r\nOK\r\n"),
124     EXCHANGE("AT+FTM=96\r", "\r\nCONNECT\r\n"),
125     //<TCF data pattern>
126     FAST_SEND_TCF("\r\nOK\r\n"),
127     EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
128     //<CFR frame data>
129     RESPONSE("\xFF\x13\x84\xEA\x7D\x10\x03"),
130     RESPONSE("\r\nOK\r\n"),
131     EXCHANGE("AT+FTM=96\r", "\r\nCONNECT\r\n"),
132     //<page image data>
133     FAST_SEND("\r\nOK\r\n"),
134     //EXCHANGE("AT+FTS=8;+FTH=3\r", "\r\nCONNECT\r\n"),
135     EXCHANGE("AT+FTS=8\r", "\r\nOK\r\n"),
136     EXCHANGE("AT+FTH=3\r", "\r\nCONNECT\r\n"),
137     //<EOP frame data>
138     EXCHANGE("\xFF\x13\x2E\x10\x03", "\r\nOK\r\n"),
139     EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
140     //<MCF frame data>
141     RESPONSE("\xFF\x13\x8C\xA2\xF1\x10\x03"),
142     RESPONSE("\r\nOK\r\n"),
143     EXCHANGE("AT+FTH=3\r", "\r\nCONNECT\r\n"),
144     // <DCN frame data>
145     EXCHANGE("\xFF\x13\xFB\x10\x03", "\r\nOK\r\n"),
146     EXCHANGE("ATH0\r", "\r\nOK\r\n"),
147     END_OF_SEQUENCE
148 };
149 
150 static const struct command_response_s fax_receive_test_seq[] =
151 {
152     EXCHANGE("ATE0\r", "ATE0\r\r\nOK\r\n"),
153     EXCHANGE("AT+FCLASS=1\r", "\r\nOK\r\n"),
154     RESPONSE("\r\nRING\r\n"),
155     EXCHANGE("ATA\r", "\r\nCONNECT\r\n"),
156     //<CSI frame data>
157     EXCHANGE("\xFF\x03\x40\x32\x32\x32\x32\x32\x32\x32\x32\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x10\x03", "\r\nCONNECT\r\n"),
158     //<DIS frame data>
159     EXCHANGE("\xFF\x13\x80\x01\xCE\xF4\x80\x80\x81\x80\x80\x80\x18\x10\x03", "\r\nOK\r\n"),
160     EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
161     //<TSI frame data>
162     RESPONSE("\xFF\x03\x43\x31\x31\x31\x31\x31\x31\x31\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xAA\x1F\x10\x03"),
163     RESPONSE("\r\nOK\r\n"),
164     EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
165     //<DCS frame data>
166     RESPONSE("\xFF\x13\x83\x00\xC6\x74\x53\x00\x10\x03"),
167     RESPONSE("\r\nOK\r\n"),
168     EXCHANGE("AT+FRM=96\r", "\r\nCONNECT\r\n"),
169     //<TCF data>
170     FAST_RESPONSE(NULL),
171     RESPONSE("\r\nNO CARRIER\r\n"),
172     EXCHANGE("AT+FTH=3\r", "\r\nCONNECT\r\n"),
173     //<CFR frame data>
174     EXCHANGE("\xFF\x13\x84\x10\x03", "\r\nOK\r\n"),
175     EXCHANGE("AT+FRM=96\r", "\r\nCONNECT\r\n"),
176     //<page image data>
177     FAST_RESPONSE(NULL),
178     RESPONSE("\r\nNO CARRIER\r\n"),
179     EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
180     //<EOP frame data>
181     RESPONSE("\xFF\x13\x2F\x33\x66\x10\x03"),
182     RESPONSE("\r\nOK\r\n"),
183     EXCHANGE("AT+FTH=3\r", "\r\nCONNECT\r\n"),
184     //<MCF frame data>
185     EXCHANGE("\xFF\x13\x8C\x10\x03", "\r\nOK\r\n"),
186     EXCHANGE("AT+FRH=3\r", "\r\nCONNECT\r\n"),
187     //<DCN frame data>
188     RESPONSE("\xFF\x13\xfb\x9a\xf6\x10\x03"),
189     RESPONSE("\r\nOK\r\n"),
190     EXCHANGE("ATH0\r", "\r\nOK\r\n"),
191     END_OF_SEQUENCE
192 };
193 
194 static const struct command_response_s v34_fax_send_test_seq[] =
195 {
196     EXCHANGE("ATE0\r", "ATE0\r\r\nOK\r\n"),
197     EXCHANGE("AT+A8E=3,,\r", "\r\nOK\r\n"),
198     EXCHANGE("AT+FCLASS=1.0\r", "\r\nOK\r\n"),
199     EXCHANGE("AT+F34=14,4,2\r", "\r\nOK\r\n"),
200     EXCHANGE("ATD123456789\r", "\r\n+A8A:1\r\nOK\r\n"),
201     EXCHANGE("AT+A8M=8185D490\r", "\r\n+A8M:8185D490\r\nOK\r\n"),
202     EXCHANGE("ATO\r", "\r\n+A8J:1\r\n+F34=14,2\r\nCONNECT\r\n"),
203     //<DIS frame data>
204     RESPONSE("\x10\x6B\x10\x7D\x10\x6F"  "\xFF\x13\x80\x00\xEE\xF8\x80\x80\x91\x80\x80\x80\x18\x78\x57\x10\x03"), // For audio FAXing
205     //RESPONSE("\x10\x6B\x10\x7D\x10\x6F"  ""\xFF\x13\x80\x04\xEE\xF8\x80\x80\x91\x80\x80\x80\x18\xE4\xE7\x10\x03"),   // For T.38 FAXing
206     //<DCS frame data>
207     //<CFR frame data>
208     EXCHANGE("\xFF\x13\x83\x01\xC6\x80\x80\x80\x80\x01\xFD\x13\x10\x03", "\xFF\x13\x84\xEA\x7D\x10\x03"),
209     EXCHANGE("\x10\x04", "\x10\x04\x10\x7D"),
210     //<FCD frames>
211     EXCHANGE("\x10\x6B", "\x10\x6B\x10\x79\x10\x6F"),
212     //<PPS-MPS frame>
213     //<FCD frames>
214     //<PPS-EOP frame>
215     EXCHANGE("\x10\x03", "\xFF\x13\x8C\xA2\xF1\x10\x03"),
216     //<DCN frame>
217     EXCHANGE("\xFF\x13\xFB\x10\x03\x10\x04", "\r\nOK\r\n"),
218     EXCHANGE("ATH\r", "\r\nOK\r\n"),
219     END_OF_SEQUENCE
220 };
221 
222 static const struct command_response_s v34_fax_receive_test_seq[] =
223 {
224     EXCHANGE("ATE0\r", "ATE0\r\r\nOK\r\n"),
225     EXCHANGE("AT+A8E=,2,\r", "\r\nOK\r\n"),
226     EXCHANGE("AT+FCLASS=1.0\r", "\r\nOK\r\n"),
227     EXCHANGE("AT+F34=10\r", "\r\nOK\r\n"),
228     RESPONSE("\r\nRING\r\n"),
229     EXCHANGE("ATA\r", "\r\n+A8M:8185D490\r\nOK\r\n"),
230     EXCHANGE("AT+A8M=8185D490;O\r", "\r\n+A8J:1\r\n+F34:10,1\r\nCONNECT\r\n"),
231     RESPONSE("\x10<ctrl>\x10<p224>\x10<C12>"),
232     EXCHANGE("ATH\r", "\r\nOK\r\n"),
233     END_OF_SEQUENCE
234 };
235 
236 static const struct command_response_s v34_fax_receive_a_test_seq[] =
237 {
238     EXCHANGE("ATE0\r", "ATE0\r\r\nOK\r\n"),
239     EXCHANGE("AT+A8E=,3,\r", "\r\nOK\r\n"),
240     EXCHANGE("AT+FCLASS=1.0\r", "\r\nOK\r\n"),
241     EXCHANGE("AT+F34=10\r", "\r\nOK\r\n"),
242     RESPONSE("\r\nRING\r\n"),
243     EXCHANGE("ATA\r", "\r\n+A8C:1\r\n+A8C:1\r\n"),
244     EXCHANGE("X", "\r\nOK\r\n"),
245     EXCHANGE("AT+A8E=,2,\r", "\r\n+A8M:8185D490\r\nOK\r\n"),
246     EXCHANGE("AT+A8M=8185D490\r", "\r\n+A8J:1\r\n+F34:10,1\r\nCONNECT\r\n"),
247     RESPONSE("\x10<ctrl>\x10<p224>\x10<C12>"),
248     EXCHANGE("ATH\r", "\r\nOK\r\n"),
249     END_OF_SEQUENCE
250 };
251 
252 static const struct command_response_s v34_fax_receive_b_test_seq[] =
253 {
254     EXCHANGE("ATE0\r", "ATE0\r\r\nOK\r\n"),
255     EXCHANGE("AT+A8E=,3,\r", "\r\nOK\r\n"),
256     EXCHANGE("AT+FCLASS=1.0\r", "\r\nOK\r\n"),
257     EXCHANGE("AT+F34=10\r", "\r\nOK\r\n"),
258     RESPONSE("\r\nRING\r\n"),
259     EXCHANGE("ATA\r", "\r\nA8I:81\r\n"),
260     RESPONSE("A8I:81\r\n"),
261     EXCHANGE("X", "\r\nOK\r\n"),
262     EXCHANGE("AT+A8E=,2,\r", "\r\n+A8M:8185D490\r\nOK\r\n"),
263     END_OF_SEQUENCE
264 };
265 
266 char *decode_test_file = NULL;
267 int countdown = 0;
268 int command_response_test_step = -1;
269 char response_buf[1000];
270 int response_buf_ptr = 0;
271 int answered = false;
272 int kick = false;
273 int dled = false;
274 int done = false;
275 int sequence_terminated = false;
276 
277 static const struct command_response_s *fax_test_seq;
278 
279 int test_seq_ptr = 0;
280 
281 t31_state_t *t31_state;
282 
phase_b_handler(void * user_data,int result)283 static int phase_b_handler(void *user_data, int result)
284 {
285     int ch;
286     t30_state_t *s;
287     char tag[20];
288 
289     ch = 'A';
290     s = (t30_state_t *) user_data;
291     snprintf(tag, sizeof(tag), "%c: Phase B", ch);
292     printf("%c: Phase B handler on channel %c - (0x%X) %s\n", ch, ch, result, t30_frametype(result));
293     fax_log_rx_parameters(s, tag);
294     return T30_ERR_OK;
295 }
296 /*- End of function --------------------------------------------------------*/
297 
phase_d_handler(void * user_data,int result)298 static int phase_d_handler(void *user_data, int result)
299 {
300     int ch;
301     t30_state_t *s;
302     char tag[20];
303 
304     ch = 'A';
305     s = (t30_state_t *) user_data;
306     snprintf(tag, sizeof(tag), "%c: Phase D", ch);
307     printf("%c: Phase D handler on channel %c - (0x%X) %s\n", ch, ch, result, t30_frametype(result));
308     fax_log_page_transfer_statistics(s, tag);
309     fax_log_tx_parameters(s, tag);
310     fax_log_rx_parameters(s, tag);
311     return T30_ERR_OK;
312 }
313 /*- End of function --------------------------------------------------------*/
314 
phase_e_handler(void * user_data,int result)315 static void phase_e_handler(void *user_data, int result)
316 {
317     int ch;
318     t30_state_t *s;
319     char tag[20];
320 
321     ch = 'A';
322     s = (t30_state_t *) user_data;
323     snprintf(tag, sizeof(tag), "%c: Phase E", ch);
324     printf("Phase E handler on channel %c\n", ch);
325     fax_log_final_transfer_statistics(s, tag);
326     fax_log_tx_parameters(s, tag);
327     fax_log_rx_parameters(s, tag);
328 }
329 /*- End of function --------------------------------------------------------*/
330 
modem_call_control(t31_state_t * s,void * user_data,int op,const char * num)331 static int modem_call_control(t31_state_t *s, void *user_data, int op, const char *num)
332 {
333     printf("\nModem control - %s", at_modem_control_to_str(op));
334     switch (op)
335     {
336     case AT_MODEM_CONTROL_CALL:
337         printf(" %s", num);
338         t31_call_event(t31_state, AT_CALL_EVENT_CONNECTED);
339         break;
340     case AT_MODEM_CONTROL_ANSWER:
341         answered = true;
342         break;
343     case AT_MODEM_CONTROL_HANGUP:
344         done = true;
345         break;
346     case AT_MODEM_CONTROL_OFFHOOK:
347         break;
348     case AT_MODEM_CONTROL_DTR:
349         printf(" %d", (int) (intptr_t) num);
350         break;
351     case AT_MODEM_CONTROL_RTS:
352         printf(" %d", (int) (intptr_t) num);
353         break;
354     case AT_MODEM_CONTROL_CTS:
355         printf(" %d", (int) (intptr_t) num);
356         break;
357     case AT_MODEM_CONTROL_CAR:
358         printf(" %d", (int) (intptr_t) num);
359         break;
360     case AT_MODEM_CONTROL_RNG:
361         printf(" %d", (int) (intptr_t) num);
362         break;
363     case AT_MODEM_CONTROL_DSR:
364         printf(" %d", (int) (intptr_t) num);
365         break;
366     case AT_MODEM_CONTROL_SETID:
367         printf(" %d", (int) (intptr_t) num);
368         break;
369     case AT_MODEM_CONTROL_RESTART:
370         printf(" %d", (int) (intptr_t) num);
371         break;
372     case AT_MODEM_CONTROL_DTE_TIMEOUT:
373         printf(" %d", (int) (intptr_t) num);
374         break;
375     }
376     /*endswitch*/
377     printf("\n");
378     return 0;
379 }
380 /*- End of function --------------------------------------------------------*/
381 
at_tx_handler(void * user_data,const uint8_t * buf,size_t len)382 static int at_tx_handler(void *user_data, const uint8_t *buf, size_t len)
383 {
384     size_t i;
385 
386     i = 0;
387     if (fax_test_seq[test_seq_ptr].command == NULL)
388     {
389         /* TCF or non-ECM image data expected */
390         for (  ;  i < len;  i++)
391         {
392             if (dled)
393             {
394                 if (buf[i] == ETX)
395                 {
396                     printf("\nFast data ended\n");
397                     response_buf_ptr = 0;
398                     response_buf[response_buf_ptr] = '\0';
399                     test_seq_ptr++;
400                     if (fax_test_seq[test_seq_ptr].command == NULL  &&  fax_test_seq[test_seq_ptr].command == NULL)
401                         sequence_terminated = true;
402                     if (fax_test_seq[test_seq_ptr].command)
403                         kick = true;
404                     break;
405                 }
406                 dled = false;
407             }
408             else
409             {
410                 if (buf[i] == DLE)
411                     dled = true;
412             }
413         }
414         i++;
415         if (i >= len)
416             return 0;
417     }
418     for (  ;  i < len;  i++)
419     {
420         response_buf[response_buf_ptr++] = buf[i];
421         putchar(buf[i]);
422     }
423     response_buf[response_buf_ptr] = '\0';
424     printf("Expected ");
425     for (i = 0;  i < response_buf_ptr;  i++)
426         printf("%02x ", fax_test_seq[test_seq_ptr].response[i] & 0xFF);
427     printf("\n");
428     printf("Response ");
429     for (i = 0;  i < response_buf_ptr;  i++)
430         printf("%02x ", response_buf[i] & 0xFF);
431     printf("\n");
432     printf("Match %d against %d\n", response_buf_ptr, fax_test_seq[test_seq_ptr].len_response);
433     if (response_buf_ptr >= fax_test_seq[test_seq_ptr].len_response
434         &&
435         memcmp(fax_test_seq[test_seq_ptr].response, response_buf, fax_test_seq[test_seq_ptr].len_response) == 0)
436     {
437         printf("\nMatched\n");
438         test_seq_ptr++;
439         if (fax_test_seq[test_seq_ptr].command == NULL  &&  fax_test_seq[test_seq_ptr].command == NULL)
440             sequence_terminated = true;
441         response_buf_ptr = 0;
442         response_buf[response_buf_ptr] = '\0';
443         if (fax_test_seq[test_seq_ptr].command)
444             kick = true;
445         else
446             dled = false;
447     }
448     return 0;
449 }
450 /*- End of function --------------------------------------------------------*/
451 
t38_tx_packet_handler(t38_core_state_t * s,void * user_data,const uint8_t * buf,int len,int count)452 static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
453 {
454     int i;
455 
456     /* This routine queues messages between two instances of T.38 processing, from the T.38 terminal side. */
457     span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count);
458 
459     for (i = 0;  i < count;  i++)
460     {
461         if (g1050_put(path_a_to_b, buf, len, s->tx_seq_no, when) < 0)
462             printf("Lost packet %d\n", s->tx_seq_no);
463     }
464     return 0;
465 }
466 /*- End of function --------------------------------------------------------*/
467 
t31_tx_packet_handler(t38_core_state_t * s,void * user_data,const uint8_t * buf,int len,int count)468 static int t31_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
469 {
470     int i;
471 
472     /* This routine queues messages between two instances of T.38 processing, from the T.31 modem side. */
473     span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count);
474 
475     for (i = 0;  i < count;  i++)
476     {
477         if (g1050_put(path_b_to_a, buf, len, s->tx_seq_no, when) < 0)
478             printf("Lost packet %d\n", s->tx_seq_no);
479     }
480     return 0;
481 }
482 /*- End of function --------------------------------------------------------*/
483 
t30_tests(int t38_mode,int use_gui,int log_audio,int test_sending,int g1050_model_no,int g1050_speed_pattern_no)484 static int t30_tests(int t38_mode, int use_gui, int log_audio, int test_sending, int g1050_model_no, int g1050_speed_pattern_no)
485 {
486     t38_terminal_state_t *t38_state;
487     fax_state_t *fax_state;
488     int fast_send;
489     int fast_send_tcf;
490     int fast_blocks;
491     int msg_len;
492     int t30_len;
493     int t31_len;
494     int t38_version;
495     int without_pacing;
496     int use_tep;
497     int seq_no;
498     int i;
499     int k;
500     int outframes;
501     uint8_t fast_buf[1000];
502     uint8_t msg[1024];
503     double tx_when;
504     double rx_when;
505     t30_state_t *t30;
506     t38_core_state_t *t38_core;
507     logging_state_t *logging;
508     int16_t t30_amp[SAMPLES_PER_CHUNK];
509     int16_t t31_amp[SAMPLES_PER_CHUNK];
510     int16_t silence[SAMPLES_PER_CHUNK];
511     int16_t out_amp[2*SAMPLES_PER_CHUNK];
512     SNDFILE *wave_handle;
513     SNDFILE *in_handle;
514 
515     /* Test the T.31 modem against the full FAX machine in spandsp */
516 
517     /* Set up the test environment */
518     t38_version = 1;
519     without_pacing = false;
520     use_tep = false;
521 
522     wave_handle = NULL;
523     if (log_audio)
524     {
525         if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
526         {
527             fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
528             exit(2);
529         }
530     }
531 
532     in_handle = NULL;
533     if (decode_test_file)
534     {
535         if ((in_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
536         {
537             fprintf(stderr, "    Cannot create audio file '%s'\n", decode_test_file);
538             exit(2);
539         }
540     }
541 
542     srand48(0x1234567);
543     if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
544     {
545         fprintf(stderr, "Failed to start IP network path model\n");
546         exit(2);
547     }
548     if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
549     {
550         fprintf(stderr, "Failed to start IP network path model\n");
551         exit(2);
552     }
553 
554     t38_state = NULL;
555     fax_state = NULL;
556     if (test_sending)
557     {
558         if (t38_mode)
559         {
560             if ((t38_state = t38_terminal_init(NULL, false, t38_tx_packet_handler, t31_state)) == NULL)
561             {
562                 fprintf(stderr, "Cannot start the T.38 channel\n");
563                 exit(2);
564             }
565             t30 = t38_terminal_get_t30_state(t38_state);
566         }
567         else
568         {
569             fax_state = fax_init(NULL, false);
570             t30 = fax_get_t30_state(fax_state);
571         }
572         t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1);
573         fax_test_seq = fax_send_test_seq;
574         countdown = 0;
575     }
576     else
577     {
578         if (t38_mode)
579         {
580             if ((t38_state = t38_terminal_init(NULL, true, t38_tx_packet_handler, t31_state)) == NULL)
581             {
582                 fprintf(stderr, "Cannot start the T.38 channel\n");
583                 exit(2);
584             }
585             t30 = t38_terminal_get_t30_state(t38_state);
586         }
587         else
588         {
589             fax_state = fax_init(NULL, true);
590             t30 = fax_get_t30_state(fax_state);
591         }
592         t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1);
593         fax_test_seq = fax_receive_test_seq;
594         countdown = 250;
595     }
596 
597     if (t38_mode)
598     {
599         t38_core = t38_terminal_get_t38_core_state(t38_state);
600         t38_set_t38_version(t38_core, t38_version);
601         t38_terminal_set_config(t38_state, without_pacing);
602         t38_terminal_set_tep_mode(t38_state, use_tep);
603     }
604 
605     t30_set_tx_ident(t30, "11111111");
606     t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
607     //t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
608     t30_set_phase_b_handler(t30, phase_b_handler, (void *) t30);
609     t30_set_phase_d_handler(t30, phase_d_handler, (void *) t30);
610     t30_set_phase_e_handler(t30, phase_e_handler, (void *) t30);
611 
612     if (t38_mode)
613         logging = t38_terminal_get_logging_state(t38_state);
614     else
615         logging = t30_get_logging_state(t30);
616     span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
617     span_log_set_tag(logging, (t38_mode)  ?  "T.38"  :  "FAX");
618 
619     if (t38_mode)
620     {
621         t38_core = t38_terminal_get_t38_core_state(t38_state);
622         span_log_set_level(&t38_core->logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
623         span_log_set_tag(&t38_core->logging, "T.38");
624 
625         logging = t30_get_logging_state(t30);
626         span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
627         span_log_set_tag(logging, "T.38");
628     }
629     else
630     {
631         logging = fax_get_logging_state(fax_state);
632         span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
633         span_log_set_tag(logging, "FAX");
634     }
635 
636     memset(silence, 0, sizeof(silence));
637     memset(t30_amp, 0, sizeof(t30_amp));
638 
639     /* Now set up and run the T.31 modem */
640     if ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, t31_tx_packet_handler, NULL)) == NULL)
641     {
642         fprintf(stderr, "    Cannot start the T.31 modem\n");
643         exit(2);
644     }
645     logging = t31_get_logging_state(t31_state);
646     span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
647     span_log_set_tag(logging, "T.31");
648 
649     logging = at_get_logging_state(t31_get_at_state(t31_state));
650     span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
651     span_log_set_tag(logging, "T.31");
652 
653     if (t38_mode)
654     {
655         t38_core = t31_get_t38_core_state(t31_state);
656         logging = t38_core_get_logging_state(t38_core);
657         span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
658         span_log_set_tag(logging, "T.31");
659 
660         t31_set_mode(t31_state, true);
661         t38_set_t38_version(t38_core, t38_version);
662     }
663 
664     fast_send = false;
665     fast_send_tcf = true;
666     fast_blocks = 0;
667     kick = true;
668 #if defined(ENABLE_GUI)
669     if (use_gui)
670         start_media_monitor();
671 #endif
672     while (!done)
673     {
674         if (countdown)
675         {
676             /* Deal with call setup, through the AT interface. */
677             if (answered)
678             {
679                 countdown = 0;
680                 t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED);
681             }
682             else if (--countdown == 0)
683             {
684                 t31_call_event(t31_state, AT_CALL_EVENT_ALERTING);
685                 countdown = 250;
686             }
687         }
688 
689         if (kick)
690         {
691             /* Work through the script */
692             kick = false;
693             if (fax_test_seq[test_seq_ptr].command > (const char *) 2)
694             {
695                 if (fax_test_seq[test_seq_ptr].command[0])
696                 {
697                     printf("%s\n", fax_test_seq[test_seq_ptr].command);
698                     t31_at_rx(t31_state, fax_test_seq[test_seq_ptr].command, fax_test_seq[test_seq_ptr].len_command);
699                 }
700             }
701             else
702             {
703                 if (fax_test_seq[test_seq_ptr].command == (const char *) 2)
704                 {
705                     printf("Fast send TCF\n");
706                     fast_send = true;
707                     fast_send_tcf = true;
708                     fast_blocks = 100;
709                 }
710                 else
711                 {
712                     printf("Fast send image\n");
713                     fast_send = true;
714                     fast_send_tcf = false;
715                     fast_blocks = 100;
716                 }
717             }
718         }
719         if (fast_send)
720         {
721             /* Send fast modem data */
722             if (fast_send_tcf)
723             {
724                 /* If we are sending TCF, its simply zeros */
725                 memset(fast_buf, 0, 36);
726                 if (fast_blocks == 1)
727                 {
728                     /* Tell the modem this is the end of the TCF data */
729                     fast_buf[34] = DLE;
730                     fast_buf[35] = ETX;
731                 }
732             }
733             else
734             {
735                 /* If we are sending image data, we need to make it look like genuine image data,
736                    with proper EOL and RTC markers. */
737                 if (fast_blocks > 1)
738                 {
739                     /* Create a chunk of white page, 1728 pixels wide. */
740                     for (i = 0;  i < 36;  i += 4)
741                     {
742                         fast_buf[i] = 0x00;
743                         fast_buf[i + 1] = 0x80;
744                         fast_buf[i + 2] = 0xB2;
745                         fast_buf[i + 3] = 0x01;
746                     }
747                 }
748                 else
749                 {
750                     /* Create the end of page condition. */
751                     for (i = 0;  i < 36;  i += 3)
752                     {
753                         fast_buf[i] = 0x00;
754                         fast_buf[i + 1] = 0x08;
755                         fast_buf[i + 2] = 0x80;
756                     }
757                     /* Tell the modem this is the end of the image data. */
758                     fast_buf[34] = DLE;
759                     fast_buf[35] = ETX;
760                 }
761             }
762             t31_at_rx(t31_state, (char *) fast_buf, 36);
763             if (--fast_blocks == 0)
764                 fast_send = false;
765         }
766 
767         if (t38_mode)
768         {
769             while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
770             {
771 #if defined(ENABLE_GUI)
772                 if (use_gui)
773                     media_monitor_rx(seq_no, tx_when, rx_when);
774 #endif
775                 t38_core = t31_get_t38_core_state(t31_state);
776                 t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
777             }
778             while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
779             {
780 #if defined(ENABLE_GUI)
781                 if (use_gui)
782                     media_monitor_rx(seq_no, tx_when, rx_when);
783 #endif
784                 t38_core = t38_terminal_get_t38_core_state(t38_state);
785                 t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
786             }
787 #if defined(ENABLE_GUI)
788             if (use_gui)
789                 media_monitor_update_display();
790 #endif
791             /* Bump the G.1050 models along */
792             when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;
793 
794             /* Bump things along on the t38_terminal side */
795             span_log_bump_samples(t38_terminal_get_logging_state(t38_state), SAMPLES_PER_CHUNK);
796             t38_core = t38_terminal_get_t38_core_state(t38_state);
797             span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);
798 
799             t38_terminal_send_timeout(t38_state, SAMPLES_PER_CHUNK);
800             t31_t38_send_timeout(t31_state, SAMPLES_PER_CHUNK);
801         }
802         else
803         {
804             t30_len = fax_tx(fax_state, t30_amp, SAMPLES_PER_CHUNK);
805             /* The receive side always expects a full block of samples, but the
806                transmit side may not be sending any when it doesn't need to. We
807                may need to pad with some silence. */
808             if (t30_len < SAMPLES_PER_CHUNK)
809             {
810                 memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len));
811                 t30_len = SAMPLES_PER_CHUNK;
812             }
813             if (log_audio)
814             {
815                 for (k = 0;  k < t30_len;  k++)
816                     out_amp[2*k] = t30_amp[k];
817             }
818             if (t31_rx(t31_state, t30_amp, t30_len))
819                 break;
820             t31_len = t31_tx(t31_state, t31_amp, SAMPLES_PER_CHUNK);
821             if (t31_len < SAMPLES_PER_CHUNK)
822             {
823                 memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len));
824                 t31_len = SAMPLES_PER_CHUNK;
825             }
826             if (log_audio)
827             {
828                 for (k = 0;  k < t31_len;  k++)
829                     out_amp[2*k + 1] = t31_amp[k];
830             }
831             if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK))
832                 break;
833 
834             if (log_audio)
835             {
836                 outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
837                 if (outframes != SAMPLES_PER_CHUNK)
838                     break;
839             }
840 
841             /* Bump things along on the FAX machine side */
842             span_log_bump_samples(fax_get_logging_state(fax_state), SAMPLES_PER_CHUNK);
843         }
844 
845         /* Bump things along on the FAX machine side */
846         span_log_bump_samples(t30_get_logging_state(t30), SAMPLES_PER_CHUNK);
847 
848         /* Bump things along on the T.31 modem side */
849         t38_core = t31_get_t38_core_state(t31_state);
850         span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);
851         span_log_bump_samples(t31_get_logging_state(t31_state), SAMPLES_PER_CHUNK);
852         span_log_bump_samples(at_get_logging_state(t31_get_at_state(t31_state)), SAMPLES_PER_CHUNK);
853     }
854 
855     g1050_free(path_a_to_b);
856     g1050_free(path_b_to_a);
857     if (t38_mode)
858         t38_terminal_free(t38_state);
859     else
860         fax_free(fax_state);
861     t31_free(t31_state);
862 
863     if (decode_test_file)
864     {
865         if (sf_close_telephony(in_handle))
866         {
867             fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
868             exit(2);
869         }
870     }
871     if (log_audio)
872     {
873         if (sf_close_telephony(wave_handle))
874         {
875             fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
876             exit(2);
877         }
878     }
879 
880     if (!done  ||  !sequence_terminated)
881     {
882         printf("Tests failed\n");
883         return -1;
884     }
885 
886     return 0;
887 }
888 /*- End of function --------------------------------------------------------*/
889 
main(int argc,char * argv[])890 int main(int argc, char *argv[])
891 {
892     int log_audio;
893     int t38_mode;
894     int test_sending;
895     int use_gui;
896     int g1050_model_no;
897     int g1050_speed_pattern_no;
898     int opt;
899 
900     decode_test_file = NULL;
901     log_audio = false;
902     test_sending = false;
903     t38_mode = false;
904     use_gui = false;
905     g1050_model_no = 0;
906     g1050_speed_pattern_no = 1;
907     while ((opt = getopt(argc, argv, "d:glM:rS:st")) != -1)
908     {
909         switch (opt)
910         {
911         case 'd':
912             decode_test_file = optarg;
913             break;
914         case 'g':
915 #if defined(ENABLE_GUI)
916             use_gui = true;
917 #else
918             fprintf(stderr, "Graphical monitoring not available\n");
919             exit(2);
920 #endif
921             break;
922         case 'l':
923             log_audio = true;
924             break;
925         case 'M':
926             g1050_model_no = optarg[0] - 'A' + 1;
927             break;
928         case 'r':
929             test_sending = false;
930             break;
931         case 'S':
932             g1050_speed_pattern_no = atoi(optarg);
933             break;
934         case 's':
935             test_sending = true;
936             break;
937         case 't':
938             t38_mode = true;
939             break;
940         default:
941             //usage();
942             exit(2);
943             break;
944         }
945     }
946 
947     if (t30_tests(t38_mode, use_gui, log_audio, test_sending, g1050_model_no, g1050_speed_pattern_no) < 0)
948         return 2;
949     printf("Tests passed\n");
950     return 0;
951 }
952 /*- End of function --------------------------------------------------------*/
953 /*- End of file ------------------------------------------------------------*/
954