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