2
0

t31_tests.c 31 KB

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