t31_pseudo_terminal_tests.c 24 KB

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