From 3e2bea0f1c4eca819519e82fe834c484809377d1 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Wed, 28 Mar 2012 21:43:13 +0800 Subject: [PATCH] Lots of little improvements to the spandsp test suite --- libs/spandsp/tests/Makefile.am | 29 +- libs/spandsp/tests/bell_mf_tx_tests.c | 31 +- libs/spandsp/tests/bert_tests.c | 2 +- libs/spandsp/tests/dc_restore_tests.c | 5 +- libs/spandsp/tests/dtmf_tx_tests.c | 33 +- libs/spandsp/tests/echo_tests.c | 8 +- libs/spandsp/tests/fax_tester.c | 76 +- libs/spandsp/tests/fax_tests.c | 1091 +++++++++++++---- libs/spandsp/tests/fax_tests.sh | 4 +- libs/spandsp/tests/fax_utils.c | 33 +- libs/spandsp/tests/fax_utils.h | 4 +- libs/spandsp/tests/g1050_tests.c | 8 +- libs/spandsp/tests/g722_tests.c | 20 +- libs/spandsp/tests/g726_tests.c | 20 +- libs/spandsp/tests/gsm0610_tests.c | 3 +- libs/spandsp/tests/ima_adpcm_tests.c | 3 +- libs/spandsp/tests/line_model_tests.c | 7 +- libs/spandsp/tests/lpc10_tests.c | 7 +- libs/spandsp/tests/modem_echo_tests.c | 6 - libs/spandsp/tests/oki_adpcm_tests.c | 5 +- libs/spandsp/tests/pcap_parse.c | 54 +- libs/spandsp/tests/r2_mf_rx_tests.c | 5 - libs/spandsp/tests/r2_mf_tx_tests.c | 9 +- libs/spandsp/tests/regression_tests.sh | 370 ++---- libs/spandsp/tests/rfc2198_sim_tests.c | 8 +- libs/spandsp/tests/schedule_tests.c | 8 +- libs/spandsp/tests/super_tone_rx_tests.c | 142 ++- libs/spandsp/tests/super_tone_tx_tests.c | 4 +- libs/spandsp/tests/t31_tests.c | 637 +++++----- libs/spandsp/tests/t35_tests.c | 117 ++ libs/spandsp/tests/t38_core_tests.c | 507 +++++++- libs/spandsp/tests/t38_decode.c | 13 +- libs/spandsp/tests/t38_gateway_tests.c | 665 ---------- .../tests/t38_gateway_to_terminal_tests.c | 708 ----------- libs/spandsp/tests/t38_terminal_tests.c | 418 ------- .../tests/t38_terminal_to_gateway_tests.c | 514 -------- libs/spandsp/tests/t4_tests.c | 76 +- libs/spandsp/tests/tone_generate_tests.c | 1 - libs/spandsp/tests/tsb85_tests.c | 4 +- libs/spandsp/tests/v17_tests.c | 32 +- libs/spandsp/tests/v22bis_tests.c | 72 +- libs/spandsp/tests/v27ter_tests.c | 56 +- libs/spandsp/tests/v29_tests.c | 61 +- libs/spandsp/tests/v42_tests.c | 4 +- libs/spandsp/tests/v42bis_tests.c | 4 +- libs/spandsp/tests/v8_tests.c | 1 - 46 files changed, 2312 insertions(+), 3573 deletions(-) create mode 100644 libs/spandsp/tests/t35_tests.c delete mode 100644 libs/spandsp/tests/t38_gateway_tests.c delete mode 100644 libs/spandsp/tests/t38_gateway_to_terminal_tests.c delete mode 100644 libs/spandsp/tests/t38_terminal_tests.c delete mode 100644 libs/spandsp/tests/t38_terminal_to_gateway_tests.c diff --git a/libs/spandsp/tests/Makefile.am b/libs/spandsp/tests/Makefile.am index 429ed34e98..05cccf1392 100644 --- a/libs/spandsp/tests/Makefile.am +++ b/libs/spandsp/tests/Makefile.am @@ -37,7 +37,6 @@ EXTRA_DIST = fax_tests.sh \ msvc/queue_tests.vcproj \ msvc/t38_core_tests.vcproj \ msvc/t38_non_ecm_buffer_tests.vcproj \ - msvc/t38_terminal_tests.vcproj \ msvc/v22bis_tests.vcproj \ msvc/v29_tests.vcproj \ msvc/v8_tests.vcproj \ @@ -104,13 +103,10 @@ noinst_PROGRAMS = adsi_tests \ super_tone_tx_tests \ swept_tone_tests \ t31_tests \ + t35_tests \ t38_core_tests \ t38_decode \ - t38_gateway_tests \ - t38_gateway_to_terminal_tests \ t38_non_ecm_buffer_tests \ - t38_terminal_tests \ - t38_terminal_to_gateway_tests \ t4_tests \ time_scale_tests \ timezone_tests \ @@ -195,7 +191,7 @@ echo_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspand fax_decode_SOURCES = fax_decode.c fax_decode_LDADD = $(LIBDIR) -lspandsp -fax_tests_SOURCES = fax_tests.c fax_utils.c +fax_tests_SOURCES = fax_tests.c fax_utils.c media_monitor.cpp fax_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp fsk_tests_SOURCES = fsk_tests.c @@ -238,7 +234,7 @@ lpc10_tests_SOURCES = lpc10_tests.c lpc10_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp math_fixed_tests_SOURCES = math_fixed_tests.c -math_fixed_tests_LDADD = $(LIBDIR) -lspandsp +math_fixed_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp make_g168_css_SOURCES = make_g168_css.c make_g168_css_LDADD = $(LIBDIR) -lspandsp @@ -294,32 +290,23 @@ super_tone_tx_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR swept_tone_tests_SOURCES = swept_tone_tests.c swept_tone_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp -t4_tests_SOURCES = t4_tests.c -t4_tests_LDADD = $(LIBDIR) -lspandsp - t31_tests_SOURCES = t31_tests.c fax_utils.c media_monitor.cpp t31_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp +t35_tests_SOURCES = t35_tests.c +t35_tests_LDADD = $(LIBDIR) -lspandsp + t38_core_tests_SOURCES = t38_core_tests.c t38_core_tests_LDADD = $(LIBDIR) -lspandsp t38_decode_SOURCES = t38_decode.c fax_utils.c pcap_parse.c udptl.c t38_decode_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp -lpcap -t38_gateway_tests_SOURCES = t38_gateway_tests.c fax_utils.c media_monitor.cpp -t38_gateway_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp - -t38_gateway_to_terminal_tests_SOURCES = t38_gateway_to_terminal_tests.c fax_utils.c media_monitor.cpp -t38_gateway_to_terminal_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp - t38_non_ecm_buffer_tests_SOURCES = t38_non_ecm_buffer_tests.c t38_non_ecm_buffer_tests_LDADD = $(LIBDIR) -lspandsp -t38_terminal_tests_SOURCES = t38_terminal_tests.c fax_utils.c media_monitor.cpp -t38_terminal_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp - -t38_terminal_to_gateway_tests_SOURCES = t38_terminal_to_gateway_tests.c fax_utils.c media_monitor.cpp -t38_terminal_to_gateway_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp +t4_tests_SOURCES = t4_tests.c +t4_tests_LDADD = $(LIBDIR) -lspandsp time_scale_tests_SOURCES = time_scale_tests.c time_scale_tests_LDADD = $(LIBDIR) -lspandsp diff --git a/libs/spandsp/tests/bell_mf_tx_tests.c b/libs/spandsp/tests/bell_mf_tx_tests.c index dac4f9db49..c5b5867155 100644 --- a/libs/spandsp/tests/bell_mf_tx_tests.c +++ b/libs/spandsp/tests/bell_mf_tx_tests.c @@ -59,7 +59,6 @@ int main(int argc, char *argv[]) int16_t amp[16384]; int len; SNDFILE *outhandle; - int outframes; int add_digits; if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL) @@ -71,36 +70,34 @@ int main(int argc, char *argv[]) gen = bell_mf_tx_init(NULL); len = bell_mf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "123", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "456", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "789", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "*#", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); add_digits = 1; do { len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) - { - outframes = sf_writef_short(outhandle, amp, len); - } + sf_writef_short(outhandle, amp, len); if (add_digits) { if (bell_mf_tx_put(gen, "1234567890", -1)) @@ -115,41 +112,39 @@ int main(int argc, char *argv[]) bell_mf_tx_init(gen); len = bell_mf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "123", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "456", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "789", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "0*#", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (bell_mf_tx_put(gen, "ABC", -1)) printf("Ooops\n"); len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); add_digits = 1; do { len = bell_mf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) - { - outframes = sf_writef_short(outhandle, amp, len); - } + sf_writef_short(outhandle, amp, len); if (add_digits) { if (bell_mf_tx_put(gen, "1234567890", -1)) diff --git a/libs/spandsp/tests/bert_tests.c b/libs/spandsp/tests/bert_tests.c index 9db22b565f..fce1eec16f 100644 --- a/libs/spandsp/tests/bert_tests.c +++ b/libs/spandsp/tests/bert_tests.c @@ -60,7 +60,7 @@ static void reporter(void *user_data, int reason, bert_results_t *results) int channel; channel = (int) (intptr_t) user_data; - printf("BERT report '%s' ", bert_event_to_str(reason)); + printf("%d: BERT report '%s' ", channel, bert_event_to_str(reason)); switch (reason) { case BERT_REPORT_REGULAR: diff --git a/libs/spandsp/tests/dc_restore_tests.c b/libs/spandsp/tests/dc_restore_tests.c index fd91ef9f24..e18e16f1aa 100644 --- a/libs/spandsp/tests/dc_restore_tests.c +++ b/libs/spandsp/tests/dc_restore_tests.c @@ -49,7 +49,6 @@ int main (int argc, char *argv[]) int i; int idum = 1234567; int16_t dirty; - int16_t clean; int estimate; int min; int max; @@ -61,7 +60,7 @@ int main (int argc, char *argv[]) for (i = 0; i < 100000; i++) { dirty = awgn(&noise_source) + dc_offset; - clean = dc_restore(&dc_state, dirty); + dc_restore(&dc_state, dirty); if ((i % 1000) == 0) { printf("Sample %6d: %d (expect %d)\n", @@ -76,7 +75,7 @@ int main (int argc, char *argv[]) for (i = 0; i < 100000; i++) { dirty = awgn(&noise_source) + dc_offset; - clean = dc_restore(&dc_state, dirty); + dc_restore(&dc_state, dirty); estimate = dc_restore_estimate(&dc_state); if (estimate < min) min = estimate; diff --git a/libs/spandsp/tests/dtmf_tx_tests.c b/libs/spandsp/tests/dtmf_tx_tests.c index 94fd6ed6ab..43c8522c31 100644 --- a/libs/spandsp/tests/dtmf_tx_tests.c +++ b/libs/spandsp/tests/dtmf_tx_tests.c @@ -59,7 +59,6 @@ int main(int argc, char *argv[]) int16_t amp[16384]; int len; SNDFILE *outhandle; - int outframes; int add_digits; if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL) @@ -71,7 +70,7 @@ int main(int argc, char *argv[]) gen = dtmf_tx_init(NULL); len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "123", -1)) { printf("Ooops\n"); @@ -79,7 +78,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "456", -1)) { printf("Ooops\n"); @@ -87,7 +86,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "789", -1)) { printf("Ooops\n"); @@ -95,7 +94,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "*#", -1)) { printf("Ooops\n"); @@ -103,16 +102,14 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); add_digits = 1; do { len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) - { - outframes = sf_writef_short(outhandle, amp, len); - } + sf_writef_short(outhandle, amp, len); if (add_digits) { if (dtmf_tx_put(gen, "1234567890", -1)) @@ -127,7 +124,7 @@ int main(int argc, char *argv[]) dtmf_tx_init(gen); len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "123", -1)) { printf("Ooops\n"); @@ -135,7 +132,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "456", -1)) { printf("Ooops\n"); @@ -143,7 +140,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "789", -1)) { printf("Ooops\n"); @@ -151,7 +148,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "0*#", -1)) { printf("Ooops\n"); @@ -159,7 +156,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "ABCD", -1)) { printf("Ooops\n"); @@ -167,7 +164,7 @@ int main(int argc, char *argv[]) } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); /* Try modifying the level and length of the digits */ printf("Try different levels and timing\n"); @@ -183,7 +180,7 @@ int main(int argc, char *argv[]) len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); } while (len > 0); printf("Restore normal levels and timing\n"); @@ -201,9 +198,7 @@ int main(int argc, char *argv[]) len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) - { - outframes = sf_writef_short(outhandle, amp, len); - } + sf_writef_short(outhandle, amp, len); if (add_digits) { if (dtmf_tx_put(gen, "1234567890", -1)) diff --git a/libs/spandsp/tests/echo_tests.c b/libs/spandsp/tests/echo_tests.c index 3283cc37ca..86b6cda961 100644 --- a/libs/spandsp/tests/echo_tests.c +++ b/libs/spandsp/tests/echo_tests.c @@ -1117,7 +1117,6 @@ static int perform_test_6(void) int16_t rx; int16_t tx; int16_t clean; - int local_max; tone_gen_descriptor_t tone_desc; tone_gen_state_t tone_state; int16_t local_sound[40000]; @@ -1151,7 +1150,7 @@ static int perform_test_6(void) j = 0; for (i = 0; i < 5; i++) { - local_max = tone_gen(&tone_state, local_sound, SAMPLE_RATE); + tone_gen(&tone_state, local_sound, SAMPLE_RATE); for (j = 0; j < SAMPLE_RATE; j++) { tx = local_sound[j]; @@ -1186,7 +1185,6 @@ static int perform_test_7(void) int16_t rx; int16_t tx; int16_t clean; - int local_max; tone_gen_descriptor_t tone_desc; tone_gen_state_t tone_state; int16_t local_sound[40000]; @@ -1213,7 +1211,7 @@ static int perform_test_7(void) j = 0; for (i = 0; i < 120; i++) { - local_max = tone_gen(&tone_state, local_sound, SAMPLE_RATE); + tone_gen(&tone_state, local_sound, SAMPLE_RATE); for (j = 0; j < SAMPLE_RATE; j++) { tx = local_sound[j]; @@ -1489,7 +1487,6 @@ static void simulate_ec(char *argv[], int two_channel_file, int mode) int16_t rout; int16_t sin; int16_t sout; - int32_t samples; mode |= ECHO_CAN_USE_ADAPTION; txfile = NULL; @@ -1510,7 +1507,6 @@ static void simulate_ec(char *argv[], int two_channel_file, int mode) ctx = echo_can_init(TEST_EC_TAPS, 0); echo_can_adaption_mode(ctx, mode); - samples = 0; do { if (two_channel_file) diff --git a/libs/spandsp/tests/fax_tester.c b/libs/spandsp/tests/fax_tester.c index 2d61e5677c..d6813a488d 100644 --- a/libs/spandsp/tests/fax_tester.c +++ b/libs/spandsp/tests/fax_tester.c @@ -287,7 +287,7 @@ static void hdlc_rx_status(void *user_data, int status) faxtester_state_t *s; s = (faxtester_state_t *) user_data; - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier status is %s (%d)\n", signal_status_to_str(status), status); + fprintf(stderr, "HDLC carrier status is %s (%d)\n", signal_status_to_str(status), status); switch (status) { case SIG_STATUS_TRAINING_FAILED: @@ -330,15 +330,15 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len) t = (faxtester_state_t *) user_data; s = &t->modems; - v17_rx(&s->v17_rx, amp, len); + v17_rx(&s->fast_modems.v17_rx, amp, len); fsk_rx(&s->v21_rx, amp, len); if (s->rx_trained) { /* The fast modem has trained, so we no longer need to run the slow one in parallel. */ - span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->v17_rx)); + span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx)); s->rx_handler = (span_rx_handler_t *) &v17_rx; - s->rx_user_data = &s->v17_rx; + s->rx_user_data = &s->fast_modems.v17_rx; } return 0; } @@ -351,15 +351,15 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len) t = (faxtester_state_t *) user_data; s = &t->modems; - v27ter_rx(&s->v27ter_rx, amp, len); + v27ter_rx(&s->fast_modems.v27ter_rx, amp, len); fsk_rx(&s->v21_rx, amp, len); if (s->rx_trained) { /* The fast modem has trained, so we no longer need to run the slow one in parallel. */ - span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->v27ter_rx)); + span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx)); s->rx_handler = (span_rx_handler_t *) &v27ter_rx; - s->rx_user_data = &s->v27ter_rx; + s->rx_user_data = &s->fast_modems.v27ter_rx; } return 0; } @@ -372,15 +372,15 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len) t = (faxtester_state_t *) user_data; s = &t->modems; - v29_rx(&s->v29_rx, amp, len); + v29_rx(&s->fast_modems.v29_rx, amp, len); fsk_rx(&s->v21_rx, amp, len); if (s->rx_trained) { /* The fast modem has trained, so we no longer need to run the slow one in parallel. */ - span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->v29_rx)); + span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx)); s->rx_handler = (span_rx_handler_t *) &v29_rx; - s->rx_user_data = &s->v29_rx; + s->rx_user_data = &s->fast_modems.v29_rx; } return 0; } @@ -500,20 +500,20 @@ void faxtester_set_rx_type(void *user_data, int type, int bit_rate, int short_tr t->rx_user_data = &t->v21_rx; break; case T30_MODEM_V27TER: - v27ter_rx_restart(&t->v27ter_rx, bit_rate, FALSE); - v27ter_rx_set_put_bit(&t->v27ter_rx, put_bit_func, put_bit_user_data); + v27ter_rx_restart(&t->fast_modems.v27ter_rx, bit_rate, FALSE); + v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data); t->rx_handler = (span_rx_handler_t *) &v27ter_v21_rx; t->rx_user_data = s; break; case T30_MODEM_V29: - v29_rx_restart(&t->v29_rx, bit_rate, FALSE); - v29_rx_set_put_bit(&t->v29_rx, put_bit_func, put_bit_user_data); + v29_rx_restart(&t->fast_modems.v29_rx, bit_rate, FALSE); + v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data); t->rx_handler = (span_rx_handler_t *) &v29_v21_rx; t->rx_user_data = s; break; case T30_MODEM_V17: - v17_rx_restart(&t->v17_rx, bit_rate, short_train); - v17_rx_set_put_bit(&t->v17_rx, put_bit_func, put_bit_user_data); + v17_rx_restart(&t->fast_modems.v17_rx, bit_rate, short_train); + v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data); t->rx_handler = (span_rx_handler_t *) &v17_v21_rx; t->rx_user_data = s; break; @@ -577,31 +577,31 @@ void faxtester_set_tx_type(void *user_data, int type, int bit_rate, int short_tr s->transmit = TRUE; break; case T30_MODEM_V27TER: - v27ter_tx_restart(&t->v27ter_tx, bit_rate, t->use_tep); - v27ter_tx_set_get_bit(&t->v27ter_tx, get_bit_func, get_bit_user_data); - v27ter_tx_set_modem_status_handler(&t->v27ter_tx, modem_tx_status, (void *) s); + v27ter_tx_restart(&t->fast_modems.v27ter_tx, bit_rate, t->use_tep); + v27ter_tx_set_get_bit(&t->fast_modems.v27ter_tx, get_bit_func, get_bit_user_data); + v27ter_tx_set_modem_status_handler(&t->fast_modems.v27ter_tx, modem_tx_status, (void *) s); t->tx_handler = (span_tx_handler_t *) &v27ter_tx; - t->tx_user_data = &t->v27ter_tx; + t->tx_user_data = &t->fast_modems.v27ter_tx; /* For any fast modem, set 200ms of preamble flags */ hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); s->transmit = TRUE; break; case T30_MODEM_V29: - v29_tx_restart(&t->v29_tx, bit_rate, t->use_tep); - v29_tx_set_get_bit(&t->v29_tx, get_bit_func, get_bit_user_data); - v29_tx_set_modem_status_handler(&t->v29_tx, modem_tx_status, (void *) s); + v29_tx_restart(&t->fast_modems.v29_tx, bit_rate, t->use_tep); + v29_tx_set_get_bit(&t->fast_modems.v29_tx, get_bit_func, get_bit_user_data); + v29_tx_set_modem_status_handler(&t->fast_modems.v29_tx, modem_tx_status, (void *) s); t->tx_handler = (span_tx_handler_t *) &v29_tx; - t->tx_user_data = &t->v29_tx; + t->tx_user_data = &t->fast_modems.v29_tx; /* For any fast modem, set 200ms of preamble flags */ hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); s->transmit = TRUE; break; case T30_MODEM_V17: - v17_tx_restart(&t->v17_tx, bit_rate, t->use_tep, short_train); - v17_tx_set_get_bit(&t->v17_tx, get_bit_func, get_bit_user_data); - v17_tx_set_modem_status_handler(&t->v17_tx, modem_tx_status, (void *) s); + v17_tx_restart(&t->fast_modems.v17_tx, bit_rate, t->use_tep, short_train); + v17_tx_set_get_bit(&t->fast_modems.v17_tx, get_bit_func, get_bit_user_data); + v17_tx_set_modem_status_handler(&t->fast_modems.v17_tx, modem_tx_status, (void *) s); t->tx_handler = (span_tx_handler_t *) &v17_tx; - t->tx_user_data = &t->v17_tx; + t->tx_user_data = &t->fast_modems.v17_tx; /* For any fast modem, set 200ms of preamble flags */ hdlc_tx_flags(&t->hdlc_tx, bit_rate/(8*5)); s->transmit = TRUE; @@ -672,16 +672,16 @@ static void faxtester_fax_modems_init(fax_modems_state_t *s, int use_tep, void * fsk_rx_signal_cutoff(&s->v21_rx, -45.5); fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); fsk_tx_set_modem_status_handler(&s->v21_tx, modem_tx_status, user_data); - v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data); - v17_tx_init(&s->v17_tx, 14400, s->use_tep, non_ecm_get_bit, user_data); - v17_tx_set_modem_status_handler(&s->v17_tx, modem_tx_status, user_data); - v29_rx_init(&s->v29_rx, 9600, non_ecm_put_bit, user_data); - v29_rx_signal_cutoff(&s->v29_rx, -45.5); - v29_tx_init(&s->v29_tx, 9600, s->use_tep, non_ecm_get_bit, user_data); - v29_tx_set_modem_status_handler(&s->v29_tx, modem_tx_status, user_data); - v27ter_rx_init(&s->v27ter_rx, 4800, non_ecm_put_bit, user_data); - v27ter_tx_init(&s->v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data); - v27ter_tx_set_modem_status_handler(&s->v27ter_tx, modem_tx_status, user_data); + v17_rx_init(&s->fast_modems.v17_rx, 14400, non_ecm_put_bit, user_data); + v17_tx_init(&s->fast_modems.v17_tx, 14400, s->use_tep, non_ecm_get_bit, user_data); + v17_tx_set_modem_status_handler(&s->fast_modems.v17_tx, modem_tx_status, user_data); + v29_rx_init(&s->fast_modems.v29_rx, 9600, non_ecm_put_bit, user_data); + v29_rx_signal_cutoff(&s->fast_modems.v29_rx, -45.5); + v29_tx_init(&s->fast_modems.v29_tx, 9600, s->use_tep, non_ecm_get_bit, user_data); + v29_tx_set_modem_status_handler(&s->fast_modems.v29_tx, modem_tx_status, user_data); + v27ter_rx_init(&s->fast_modems.v27ter_rx, 4800, non_ecm_put_bit, user_data); + v27ter_tx_init(&s->fast_modems.v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data); + v27ter_tx_set_modem_status_handler(&s->fast_modems.v27ter_tx, modem_tx_status, user_data); silence_gen_init(&s->silence_gen, 0); modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); modem_connect_tones_rx_init(&s->connect_rx, diff --git a/libs/spandsp/tests/fax_tests.c b/libs/spandsp/tests/fax_tests.c index 4614ba1ffa..2d92767533 100644 --- a/libs/spandsp/tests/fax_tests.c +++ b/libs/spandsp/tests/fax_tests.c @@ -27,13 +27,35 @@ /*! \page fax_tests_page FAX tests \section fax_tests_page_sec_1 What does it do? -\section fax_tests_page_sec_2 How does it work? +These tests exercise the following FAX to FAX paths: + + +--Modems-+---------TDM/RTP---------+-Modems--+ + | \ / | + | \ / | +T.30 <---+ T.38 gateway T.38 gateway +--->T.30 + | \ / | + | \ / | + +---T.38--------+--UDPTL/RTP--+--------T.38---+ + +T.30<->Modems<-------------------------TDM/RTP------------------------->Modems<->T.30 +T.30<->Modems<-TDM/RTP->T.38 gateway<-UDPTL/RTP->T.38 gateway<-TDM/RTP->Modems<->T.30 +T.30<->Modems<-TDM/RTP->T.38 gateway<-UDPTL/RTP-------------------------->T.38<->T.30 +T.30<->T.38<--------------------------UDPTL/RTP->T.38 gateway<-TDM/RTP->Modems<->T.30 +T.30<->T.38<--------------------------UDPTL/RTP-------------------------->T.38<->T.30 + */ +/* Enable the following definition to enable direct probing into the FAX structures */ +//#define WITH_SPANDSP_INTERNALS + #if defined(HAVE_CONFIG_H) #include "config.h" #endif +#if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H) && defined(HAVE_FL_FL_AUDIO_METER_H) +#define ENABLE_GUI +#endif + #include #include #include @@ -46,51 +68,236 @@ #include #endif +#if defined(HAVE_LIBXML_XMLMEMORY_H) +#include +#endif +#if defined(HAVE_LIBXML_PARSER_H) +#include +#endif +#if defined(HAVE_LIBXML_XINCLUDE_H) +#include +#endif + //#if defined(WITH_SPANDSP_INTERNALS) #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES //#endif +#include "udptl.h" #include "spandsp.h" #include "spandsp-sim.h" +#if defined(ENABLE_GUI) +#include "media_monitor.h" +#endif +#include "fax_tester.h" #include "fax_utils.h" +#include "pcap_parse.h" #define SAMPLES_PER_CHUNK 160 #define INPUT_TIFF_FILE_NAME "../test-data/itu/fax/itutests.tif" +#define OUTPUT_TIFF_FILE_NAME "fax_tests.tif" +#define OUTPUT_WAVE_FILE_NAME "fax_tests.wav" -#define OUTPUT_FILE_NAME_WAVE "fax_tests.wav" - -#define FAX_MACHINES 2 - -struct machine_s +enum { - int chan; - int16_t amp[SAMPLES_PER_CHUNK]; - int len; - fax_state_t *fax; - awgn_state_t *awgn; - int done; - int succeeded; - char tag[50]; - int error_delay; - int total_audio_time; -} machines[FAX_MACHINES]; + AUDIO_FAX, + T38_TERMINAL_FAX, + T38_GATEWAY_FAX +}; + +int mode[2] = {AUDIO_FAX, AUDIO_FAX}; + +t30_state_t *t30_state[2]; +fax_state_t *fax_state[2]; +t38_gateway_state_t *t38_gateway_state[2]; +t38_terminal_state_t *t38_state[2]; +t38_core_state_t *t38_core_state[2]; +g1050_state_t *g1050_path[2]; +awgn_state_t *awgn_state[2]; +int16_t audio_buffer[2*2][SAMPLES_PER_CHUNK]; + +int t38_subst_seq[2] = {0, 0}; + +t30_exchanged_info_t expected_rx_info[2]; int use_receiver_not_ready = FALSE; int test_local_interrupt = FALSE; -int t30_state_to_wreck = -1; + +double when = 0.0; + +int phase_e_reached[2] = {FALSE, FALSE}; +int completed[2] = {FALSE, FALSE}; +int succeeded[2] = {FALSE, FALSE}; + +int t38_simulate_incrementing_repeats = FALSE; static int phase_b_handler(t30_state_t *s, void *user_data, int result) { int i; + int ch; + int status; + int len; char tag[20]; + const char *u; + const uint8_t *v; i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase B", i); - printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); + ch = i + 'A'; + snprintf(tag, sizeof(tag), "%c: Phase B", ch); + printf("%c: Phase B handler - (0x%X) %s\n", ch, result, t30_frametype(result)); fax_log_rx_parameters(s, tag); - return T30_ERR_OK; + status = T30_ERR_OK; + + if ((u = t30_get_rx_ident(s))) + { + printf("%c: Phase B remote ident '%s'\n", ch, u); + if (expected_rx_info[i].ident[0] && strcmp(expected_rx_info[i].ident, u)) + { + printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", ch, expected_rx_info[i].ident); + status = T30_ERR_IDENT_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info[i].ident[0]) + { + printf("%c: Phase B: remote ident missing!\n", ch); + status = T30_ERR_IDENT_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_sub_address(s))) + { + printf("%c: Phase B: remote sub-address '%s'\n", ch, u); + if (expected_rx_info[i].sub_address[0] && strcmp(expected_rx_info[i].sub_address, u)) + { + printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", ch, expected_rx_info[i].sub_address); + status = T30_ERR_SUB_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info[i].sub_address[0]) + { + printf("%c: Phase B: remote sub-address missing!\n", ch); + status = T30_ERR_SUB_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_polled_sub_address(s))) + { + printf("%c: Phase B: remote polled sub-address '%s'\n", ch, u); + if (expected_rx_info[i].polled_sub_address[0] && strcmp(expected_rx_info[i].polled_sub_address, u)) + { + printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", ch, expected_rx_info[i].polled_sub_address); + status = T30_ERR_PSA_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info[i].polled_sub_address[0]) + { + printf("%c: Phase B: remote polled sub-address missing!\n", ch); + status = T30_ERR_PSA_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_selective_polling_address(s))) + { + printf("%c: Phase B: remote selective polling address '%s'\n", ch, u); + if (expected_rx_info[i].selective_polling_address[0] && strcmp(expected_rx_info[i].selective_polling_address, u)) + { + printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", ch, expected_rx_info[i].selective_polling_address); + status = T30_ERR_SEP_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info[i].selective_polling_address[0]) + { + printf("%c: Phase B: remote selective polling address missing!\n", ch); + status = T30_ERR_SEP_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_sender_ident(s))) + { + printf("%c: Phase B: remote sender ident '%s'\n", ch, u); + if (expected_rx_info[i].sender_ident[0] && strcmp(expected_rx_info[i].sender_ident, u)) + { + printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", ch, expected_rx_info[i].sender_ident); + status = T30_ERR_SID_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info[i].sender_ident[0]) + { + printf("%c: Phase B: remote sender ident missing!\n", ch); + status = T30_ERR_SID_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_password(s))) + { + printf("%c: Phase B: remote password '%s'\n", ch, u); + if (expected_rx_info[i].password[0] && strcmp(expected_rx_info[i].password, u)) + { + printf("%c: Phase B: remote password incorrect! - expected '%s'\n", ch, expected_rx_info[i].password); + status = T30_ERR_PWD_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info[i].password[0]) + { + printf("%c: Phase B: remote password missing!\n", ch); + status = T30_ERR_PWD_UNACCEPTABLE; + } + } + if ((len = t30_get_rx_nsf(s, &v))) + { + printf("%c: Phase B: NSF %d bytes\n", ch, len); + if (expected_rx_info[i].nsf_len && (expected_rx_info[i].nsf_len != len || memcmp(expected_rx_info[i].nsf, v, len))) + { + printf("%c: Phase B: remote NSF incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); + } + } + else + { + if (expected_rx_info[i].nsf_len) + { + printf("%c: Phase B: remote NSF missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); + } + } + if ((len = t30_get_rx_nsc(s, &v))) + { + printf("%c: Phase B: NSC %d bytes\n", ch, len); + if (expected_rx_info[i].nsc_len && (expected_rx_info[i].nsc_len != len || memcmp(expected_rx_info[i].nsc, v, len))) + { + printf("%c: Phase B: remote NSC incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsc_len); + } + } + else + { + if (expected_rx_info[i].nsc_len) + { + printf("%c: Phase B: remote NSC missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsc_len); + } + } + if ((len = t30_get_rx_nss(s, &v))) + { + printf("%c: Phase B: NSS %d bytes\n", ch, len); + if (expected_rx_info[i].nss_len && (expected_rx_info[i].nss_len != len || memcmp(expected_rx_info[i].nss, v, len))) + { + printf("%c: Phase B: remote NSS incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nss_len); + } + } + else + { + if (expected_rx_info[i].nss_len) + { + printf("%c: Phase B: remote NSS missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); + } + } + + return status; } /*- End of function --------------------------------------------------------*/ @@ -100,9 +307,9 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result) char tag[20]; i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase D", i); - printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); + snprintf(tag, sizeof(tag), "%c: Phase D", i + 'A'); + printf("%c: Phase D handler - (0x%X) %s\n", i + 'A', result, t30_frametype(result)); + fax_log_page_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); @@ -111,9 +318,9 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result) if (test_local_interrupt) { - if (i == 0) + if (i == 'A') { - printf("%d: Initiating interrupt request\n", i); + printf("%c: Initiating interrupt request\n", i); t30_local_interrupt_request(s, TRUE); } else @@ -124,7 +331,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result) case T30_PRI_MPS: case T30_PRI_EOM: case T30_PRI_EOP: - printf("%d: Accepting interrupt request\n", i); + printf("%c: Accepting interrupt request\n", i); t30_local_interrupt_request(s, TRUE); break; case T30_PIN: @@ -141,16 +348,16 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) int i; t30_stats_t t; char tag[20]; - - i = (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase E", i); - printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result)); - fax_log_transfer_statistics(s, tag); + + i = (int) (intptr_t) user_data; + snprintf(tag, sizeof(tag), "%c: Phase E", i + 'A'); + printf("%c: Phase E handler - (%d) %s\n", i + 'A', result, t30_completion_code_to_str(result)); + fax_log_final_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); t30_get_transfer_statistics(s, &t); - machines[i - 'A'].succeeded = (result == T30_ERR_OK) && (t.pages_tx == 12 || t.pages_rx == 12); - machines[i - 'A'].done = TRUE; + succeeded[i] = (result == T30_ERR_OK); + phase_e_reached[i] = TRUE; } /*- End of function --------------------------------------------------------*/ @@ -163,9 +370,8 @@ static void real_time_frame_handler(t30_state_t *s, int i; i = (intptr_t) user_data; - printf("%c: Real time frame handler on channel %c - %s, %s, length = %d\n", - i, - i, + printf("%c: Real time frame handler - %s, %s, length = %d\n", + i + 'A', (direction) ? "line->T.30" : "T.30->line", t30_frametype(msg[2]), len); @@ -177,73 +383,187 @@ static int document_handler(t30_state_t *s, void *user_data, int event) int i; i = (intptr_t) user_data; - printf("%c: Document handler on channel %c - event %d\n", i, i, event); + printf("%c: Document handler - event %d\n", i + 'A', event); return FALSE; } /*- End of function --------------------------------------------------------*/ +static void set_t30_callbacks(t30_state_t *t30, int chan) +{ + t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) chan); + t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) chan); + t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) chan); + t30_set_real_time_frame_handler(t30, real_time_frame_handler, (void *) (intptr_t) chan); + t30_set_document_handler(t30, document_handler, (void *) (intptr_t) chan); +} +/*- End of function --------------------------------------------------------*/ + +static void real_time_gateway_frame_handler(t38_gateway_state_t *s, + void *user_data, + int direction, + const uint8_t *msg, + int len) +{ + int i; + + i = (intptr_t) user_data; + printf("%c: Real time gateway frame handler - %s, %s, length = %d\n", + i + 'A', + (direction) ? "PSTN->T.38" : "T.38->PSTN", + t30_frametype(msg[2]), + len); +} +/*- End of function --------------------------------------------------------*/ + +static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) +{ + int i; + int chan; + + /* This routine queues messages between two instances of T.38 processing */ + chan = (intptr_t) user_data; + if (t38_simulate_incrementing_repeats) + { + for (i = 0; i < count; i++) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", t38_subst_seq[chan], len); + + if (g1050_put(g1050_path[chan], buf, len, t38_subst_seq[chan], when) < 0) + printf("Lost packet %d\n", t38_subst_seq[chan]); + t38_subst_seq[chan] = (t38_subst_seq[chan] + 1) & 0xFFFF; + } + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); + + for (i = 0; i < count; i++) + { + if (g1050_put(g1050_path[chan], buf, len, s->tx_seq_no, when) < 0) + printf("Lost packet %d\n", s->tx_seq_no); + } + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + int main(int argc, char *argv[]) { + int16_t silence[SAMPLES_PER_CHUNK]; + int16_t t30_amp[2][SAMPLES_PER_CHUNK]; + int16_t t38_amp[2][SAMPLES_PER_CHUNK]; + int16_t t38_amp_hist_a[8][SAMPLES_PER_CHUNK]; + int16_t t38_amp_hist_b[8][SAMPLES_PER_CHUNK]; + int16_t out_amp[SAMPLES_PER_CHUNK*4]; + int16_t *fax_rx_buf[2]; + int16_t *fax_tx_buf[2]; + int16_t *t38_gateway_rx_buf[2]; + int16_t *t38_gateway_tx_buf[2]; + int t30_len[2]; + int t38_len[2]; + int hist_ptr; + int log_audio; + int msg_len; + uint8_t msg[1024]; + int outframes; SNDFILE *wave_handle; SNDFILE *input_wave_handle; - int i; - int j; - int k; - struct machine_s *mc; - int outframes; - char buf[128 + 1]; - int16_t silence[SAMPLES_PER_CHUNK]; - int16_t out_amp[2*SAMPLES_PER_CHUNK]; - int alldone; - const char *input_tiff_file_name; - const char *input_audio_file_name; - int log_audio; int use_ecm; int use_tep; + int feedback_audio; int use_transmit_on_idle; - int use_line_hits; - int polled_mode; - int reverse_flow; - int use_page_limits; + int t38_version; + const char *input_tiff_file_name; + const char *decode_file_name; + int i; + int j; + int seq_no; + int g1050_model_no; + int g1050_speed_pattern_no; + int t38_transport; + double tx_when; + double rx_when; int supported_modems; + int remove_fill_bits; + int opt; + int start_page; + int end_page; + int drop_frame; + int drop_frame_rate; + float signal_scaling; int signal_level; int noise_level; - float signal_scaling; - time_t start_time; - time_t end_time; + int code_to_look_up; int scan_line_time; + t38_stats_t t38_stats; + t30_stats_t t30_stats; + logging_state_t *logging; + int expected_pages; char *page_header_info; char *page_header_tz; - int opt; - t30_state_t *t30; - logging_state_t *logging; + const char *tag; + char buf[132 + 1]; +#if defined(ENABLE_GUI) + int use_gui; +#endif +#if defined(ENABLE_GUI) + use_gui = FALSE; +#endif log_audio = FALSE; - input_tiff_file_name = INPUT_TIFF_FILE_NAME; - input_audio_file_name = NULL; use_ecm = FALSE; - use_line_hits = FALSE; + t38_version = 1; + input_tiff_file_name = INPUT_TIFF_FILE_NAME; + t38_simulate_incrementing_repeats = FALSE; + g1050_model_no = 0; + g1050_speed_pattern_no = 1; + remove_fill_bits = FALSE; use_tep = FALSE; - polled_mode = FALSE; + feedback_audio = FALSE; + use_transmit_on_idle = TRUE; + supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17; page_header_info = NULL; page_header_tz = NULL; - reverse_flow = FALSE; - use_transmit_on_idle = TRUE; - use_receiver_not_ready = FALSE; - use_page_limits = FALSE; + drop_frame = 0; + drop_frame_rate = 0; + start_page = -1; + end_page = -1; signal_level = 0; noise_level = -99; scan_line_time = 0; - supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17; - while ((opt = getopt(argc, argv, "ehH:i:I:lm:n:prRs:S:tTw:z:")) != -1) + decode_file_name = NULL; + code_to_look_up = -1; + t38_transport = T38_TRANSPORT_UDPTL; + while ((opt = getopt(argc, argv, "c:d:D:efFgH:i:Ilm:M:n:p:s:tT:u:v:z:")) != -1) { switch (opt) { + case 'c': + code_to_look_up = atoi(optarg); + break; + case 'd': + decode_file_name = optarg; + break; + case 'D': + drop_frame_rate = + drop_frame = atoi(optarg); + break; case 'e': use_ecm = TRUE; break; - case 'h': - use_line_hits = TRUE; + case 'f': + feedback_audio = TRUE; + break; + case 'F': + remove_fill_bits = TRUE; + break; + case 'g': +#if defined(ENABLE_GUI) + use_gui = TRUE; +#else + fprintf(stderr, "Graphical monitoring not available\n"); + exit(2); +#endif break; case 'H': page_header_info = optarg; @@ -252,7 +572,7 @@ int main(int argc, char *argv[]) input_tiff_file_name = optarg; break; case 'I': - input_audio_file_name = optarg; + t38_simulate_incrementing_repeats = TRUE; break; case 'l': log_audio = TRUE; @@ -260,21 +580,47 @@ int main(int argc, char *argv[]) case 'm': supported_modems = atoi(optarg); break; + case 'M': + g1050_model_no = optarg[0] - 'A' + 1; + break; case 'n': noise_level = atoi(optarg); break; case 'p': - polled_mode = TRUE; + for (i = 0; i < 2; i++) + { + switch (optarg[i]) + { + case 'A': + mode[i] = AUDIO_FAX; + break; + case 'G': + mode[i] = T38_GATEWAY_FAX; + break; + case 'T': + mode[i] = T38_TERMINAL_FAX; + break; + default: + fprintf(stderr, "Unknown FAX path element %c\n", optarg[i]); + exit(2); + } + } + if ((mode[0] == AUDIO_FAX && mode[1] != AUDIO_FAX) + || + (mode[0] != AUDIO_FAX && mode[1] == AUDIO_FAX)) + { + fprintf(stderr, "Invalid FAX path %s\n", optarg); + exit(2); + } break; - case 'r': - reverse_flow = TRUE; - break; - case 'R': - use_receiver_not_ready = TRUE; + case 's': + g1050_speed_pattern_no = atoi(optarg); break; +#if 0 case 's': signal_level = atoi(optarg); break; +#endif case 'S': scan_line_time = atoi(optarg); break; @@ -282,10 +628,26 @@ int main(int argc, char *argv[]) use_tep = TRUE; break; case 'T': - use_page_limits = TRUE; + start_page = 0; + end_page = atoi(optarg); break; - case 'w': - t30_state_to_wreck = atoi(optarg); + case 'u': + if (strcasecmp(optarg, "udptl") == 0) + t38_transport = T38_TRANSPORT_UDPTL; + else if (strcasecmp(optarg, "rtp") == 0) + t38_transport = T38_TRANSPORT_RTP; + else if (strcasecmp(optarg, "tcp") == 0) + t38_transport = T38_TRANSPORT_TCP; + else if (strcasecmp(optarg, "tcp-tpkt") == 0) + t38_transport = T38_TRANSPORT_TCP_TPKT; + else + { + fprintf(stderr, "Unknown T.38 transport mode\n"); + exit(2); + } + break; + case 'v': + t38_version = atoi(optarg); break; case 'z': page_header_tz = optarg; @@ -297,75 +659,198 @@ int main(int argc, char *argv[]) } } - input_wave_handle = NULL; - if (input_audio_file_name) + if (code_to_look_up >= 0) { - if ((input_wave_handle = sf_open_telephony_read(input_audio_file_name, 1)) == NULL) - { - fprintf(stderr, " Cannot open audio file '%s'\n", input_audio_file_name); - exit(2); - } + printf("Result code %d is %s\n", code_to_look_up, t30_completion_code_to_str(code_to_look_up)); + exit(0); } + printf("Using T.38 version %d\n", t38_version); + if (use_ecm) + printf("Using ECM\n"); + wave_handle = NULL; if (log_audio) { - if ((wave_handle = sf_open_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == NULL) + if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 4)) == NULL) { - fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); + fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME); exit(2); } } - memset(silence, 0, sizeof(silence)); - for (j = 0; j < FAX_MACHINES; j++) + + srand48(0x1234567); + /* Set up the nodes */ + input_wave_handle = NULL; + if (mode[0] == T38_TERMINAL_FAX) { - machines[j].chan = j; - mc = &machines[j]; - - i = mc->chan + 1; - sprintf(buf, "%d%d%d%d%d%d%d%d", i, i, i, i, i, i, i, i); - if (reverse_flow) - mc->fax = fax_init(NULL, (mc->chan & 1) ? TRUE : FALSE); - else - mc->fax = fax_init(NULL, (mc->chan & 1) ? FALSE : TRUE); - mc->awgn = NULL; - signal_scaling = 1.0f; - if (noise_level > -99) + } + else + { + if (decode_file_name) { - mc->awgn = awgn_init_dbm0(NULL, 1234567, noise_level); - signal_scaling = powf(10.0f, signal_level/20.0f); - printf("Signal scaling %f\n", signal_scaling); + if ((input_wave_handle = sf_open_telephony_read(decode_file_name, 1)) == NULL) + { + fprintf(stderr, " Cannot open audio file '%s'\n", decode_file_name); + exit(2); + } } - fax_set_transmit_on_idle(mc->fax, use_transmit_on_idle); - fax_set_tep_mode(mc->fax, use_tep); - t30 = fax_get_t30_state(mc->fax); - t30_set_tx_ident(t30, buf); - t30_set_tx_sub_address(t30, "Sub-address"); - t30_set_tx_sender_ident(t30, "Sender ID"); - t30_set_tx_password(t30, "Password"); - t30_set_tx_polled_sub_address(t30, "Polled sub-address"); - t30_set_tx_selective_polling_address(t30, "Selective polling address"); - t30_set_tx_page_header_info(t30, page_header_info); + } + + for (i = 0; i < 2; i++) + { + tag = (i == 0) ? "A" : "B"; + + memset(&expected_rx_info[i], 0, sizeof(expected_rx_info[i])); + if (mode[i] == T38_TERMINAL_FAX) + { + if ((t38_state[i] = t38_terminal_init(NULL, (i == 0), tx_packet_handler, (void *) (intptr_t) i)) == NULL) + { + fprintf(stderr, "Cannot start the T.38 terminal instance\n"); + exit(2); + } + t30_state[i] = t38_terminal_get_t30_state(t38_state[i]); + t38_core_state[i] = t38_terminal_get_t38_core_state(t38_state[i]); + + logging = t38_terminal_get_logging_state(t38_state[i]); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + logging = t38_core_get_logging_state(t38_core_state[i]); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + logging = t30_get_logging_state(t30_state[i]); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + } + else + { + if ((fax_state[i] = fax_init(NULL, (i == 0))) == NULL) + { + fprintf(stderr, "Cannot start FAX instance\n"); + exit(2); + } + t30_state[i] = fax_get_t30_state(fax_state[i]); + + logging = fax_get_logging_state(fax_state[i]); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + logging = fax_modems_get_logging_state(&fax_state[i]->modems); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + logging = t30_get_logging_state(t30_state[i]); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + if (mode[i] == T38_GATEWAY_FAX) + { + if ((t38_gateway_state[i] = t38_gateway_init(NULL, tx_packet_handler, (void *) (intptr_t) i)) == NULL) + { + fprintf(stderr, "Cannot start the T.38 gateway instancel\n"); + exit(2); + } + t38_core_state[i] = t38_gateway_get_t38_core_state(t38_gateway_state[i]); + + logging = t38_gateway_get_logging_state(t38_gateway_state[i]); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + logging = fax_modems_get_logging_state(&t38_gateway_state[i]->audio.modems); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + logging = t38_core_get_logging_state(t38_core_state[i]); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, tag); + + fax_rx_buf[i] = t38_amp[i]; + fax_tx_buf[i] = t30_amp[i]; + t38_gateway_rx_buf[i] = t30_amp[i]; + t38_gateway_tx_buf[i] = t38_amp[i]; + } + else + { + fax_rx_buf[i] = t30_amp[i]; + fax_tx_buf[i] = t30_amp[i ^ 1]; + t38_gateway_rx_buf[i] = NULL; + t38_gateway_tx_buf[i] = NULL; + } + awgn_state[i] = NULL; + signal_scaling = 1.0f; + if (noise_level > -99) + { + awgn_state[i] = awgn_init_dbm0(NULL, 1234567, noise_level); + signal_scaling = powf(10.0f, signal_level/20.0f); + printf("Signal scaling %f\n", signal_scaling); + } + } + set_t30_callbacks(t30_state[i], i); + } + /* Set up the channels */ + for (i = 0; i < 2; i++) + { + if ((g1050_path[i] = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) + { + fprintf(stderr, "Failed to start IP network path model\n"); + exit(2); + } + memset(audio_buffer[2*i], 0, SAMPLES_PER_CHUNK*sizeof(int16_t)); + memset(audio_buffer[2*i + 1], 0, SAMPLES_PER_CHUNK*sizeof(int16_t)); + memset(t30_amp[i], 0, sizeof(t30_amp[i])); + memset(t38_amp[i], 0, sizeof(t38_amp[i])); + } + memset(t38_amp_hist_a, 0, sizeof(t38_amp_hist_a)); + memset(t38_amp_hist_b, 0, sizeof(t38_amp_hist_b)); + + for (i = 0; i < 2; i++) + { + j = i + 1; + sprintf(buf, "%d%d%d%d%d%d%d%d", j, j, j, j, j, j, j, j); + t30_set_tx_ident(t30_state[i], buf); + strcpy(expected_rx_info[i ^ 1].ident, buf); + sprintf(buf, "Sub-address %d", j); + t30_set_tx_sub_address(t30_state[i], buf); + //strcpy(expected_rx_info[i ^ 1].sub_address, buf); + sprintf(buf, "Sender ID %d", j); + t30_set_tx_sender_ident(t30_state[i], buf); + //strcpy(expected_rx_info[i ^ 1].sender_ident, buf); + sprintf(buf, "Password %d", j); + t30_set_tx_password(t30_state[i], buf); + //strcpy(expected_rx_info[i ^ 1].password, buf); + sprintf(buf, "Polled sub-add %d", j); + t30_set_tx_polled_sub_address(t30_state[i], buf); + //strcpy(expected_rx_info[i ^ 1].polled_sub_address, buf); + sprintf(buf, "Select poll add %d", j); + t30_set_tx_selective_polling_address(t30_state[i], buf); + //strcpy(expected_rx_info[i ^ 1].selective_polling_address, buf); + t30_set_tx_page_header_info(t30_state[i], page_header_info); if (page_header_tz) - t30_set_tx_page_header_tz(t30, page_header_tz); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_ecm_capability(t30, use_ecm); - t30_set_supported_t30_features(t30, + t30_set_tx_page_header_tz(t30_state[i], page_header_tz); + + if ((i & 1) == 1) + { + t30_set_tx_nsf(t30_state[i], (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); + expected_rx_info[i ^ 1].nsf = (uint8_t *) "\x50\x00\x00\x00Spandsp\x00"; + expected_rx_info[i ^ 1].nsf_len = 12; + } + + t30_set_supported_modems(t30_state[i], supported_modems); + t30_set_supported_t30_features(t30_state[i], T30_SUPPORT_IDENTIFICATION | T30_SUPPORT_SELECTIVE_POLLING | T30_SUPPORT_SUB_ADDRESSING); - - if ((mc->chan & 1)) - t30_set_minimum_scan_line_time(t30, scan_line_time); - t30_set_supported_image_sizes(t30, + t30_set_supported_image_sizes(t30_state[i], T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH | T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH | T30_SUPPORT_303MM_WIDTH); - t30_set_supported_resolutions(t30, + t30_set_supported_resolutions(t30_state[i], T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION @@ -378,146 +863,185 @@ int main(int argc, char *argv[]) | T30_SUPPORT_300_600_RESOLUTION | T30_SUPPORT_400_800_RESOLUTION | T30_SUPPORT_600_1200_RESOLUTION); - t30_set_supported_modems(t30, supported_modems); + + t30_set_ecm_capability(t30_state[i], use_ecm); if (use_ecm) -#if defined(SPANDSP_SUPPORT_T85) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION | T30_SUPPORT_T85_COMPRESSION); -#else - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); -#endif - if ((mc->chan & 1)) + t30_set_supported_compressions(t30_state[i], T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); + t30_set_minimum_scan_line_time(t30_state[i], scan_line_time); + + if (mode[i] == T38_GATEWAY_FAX) { - if (polled_mode) + t38_gateway_set_transmit_on_idle(t38_gateway_state[i], use_transmit_on_idle); + t38_gateway_set_supported_modems(t38_gateway_state[i], supported_modems); + //t38_gateway_set_nsx_suppression(t38_state[i], NULL, 0, NULL, 0); + t38_gateway_set_fill_bit_removal(t38_gateway_state[i], remove_fill_bits); + t38_gateway_set_real_time_frame_handler(t38_gateway_state[i], real_time_gateway_frame_handler, (void *) (intptr_t) i); + t38_gateway_set_ecm_capability(t38_gateway_state[i], use_ecm); + } + if (mode[i] != AUDIO_FAX) + { + t38_set_t38_version(t38_core_state[i], t38_version); + } + + if (mode[i] == T38_TERMINAL_FAX) + { + //t30_set_iaf_mode(t30_state[i], T30_IAF_MODE_NO_FILL_BITS); + switch (t38_transport) { - if (use_page_limits) - t30_set_tx_file(t30, input_tiff_file_name, 3, 6); - else - t30_set_tx_file(t30, input_tiff_file_name, -1, -1); - } - else - { - sprintf(buf, "fax_tests_%d.tif", (mc->chan + 1)/2); - t30_set_rx_file(t30, buf, -1); - t30_set_rx_encoding(t30, T4_COMPRESSION_ITU_T6); + case T38_TRANSPORT_UDPTL: + case T38_TRANSPORT_RTP: + t38_terminal_set_fill_bit_removal(t38_state[i], remove_fill_bits); + t38_terminal_set_tep_mode(t38_state[i], use_tep); + break; + case T38_TRANSPORT_TCP: + case T38_TRANSPORT_TCP_TPKT: + t38_terminal_set_fill_bit_removal(t38_state[i], TRUE); + t38_terminal_set_config(t38_state[i], T38_TERMINAL_OPTION_NO_PACING | T38_TERMINAL_OPTION_NO_INDICATORS); + t38_terminal_set_tep_mode(t38_state[i], FALSE); + break; } } else { - if (polled_mode) - { - sprintf(buf, "fax_tests_%d.tif", (mc->chan + 1)/2); - t30_set_rx_file(t30, buf, -1); - t30_set_rx_encoding(t30, T4_COMPRESSION_ITU_T6); - } - else - { - if (use_page_limits) - t30_set_tx_file(t30, input_tiff_file_name, 3, 6); - else - t30_set_tx_file(t30, input_tiff_file_name, -1, -1); - } + fax_set_transmit_on_idle(fax_state[i], use_transmit_on_idle); + fax_set_tep_mode(fax_state[i], use_tep); } - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) mc->chan + 'A'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) mc->chan + 'A'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) mc->chan + 'A'); - t30_set_real_time_frame_handler(t30, real_time_frame_handler, (void *) (intptr_t) mc->chan + 'A'); - t30_set_document_handler(t30, document_handler, (void *) (intptr_t) mc->chan + 'A'); - sprintf(mc->tag, "FAX-%d", j + 1); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(logging, mc->tag); - if ((j & 1)) - { - span_log_set_level(&t30->t4.rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(&t30->t4.rx.logging, mc->tag); - } - else - { - span_log_set_level(&t30->t4.tx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(&t30->t4.tx.logging, mc->tag); - } - logging = fax_get_logging_state(mc->fax); - span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(logging, mc->tag); - - memset(mc->amp, 0, sizeof(mc->amp)); - mc->total_audio_time = 0; - mc->done = FALSE; } - time(&start_time); + + t30_set_tx_file(t30_state[0], input_tiff_file_name, start_page, end_page); + t30_set_rx_file(t30_state[1], OUTPUT_TIFF_FILE_NAME, -1); + +#if defined(ENABLE_GUI) + if (use_gui) + start_media_monitor(); +#endif + hist_ptr = 0; for (;;) { - alldone = TRUE; - for (j = 0; j < FAX_MACHINES; j++) - { - mc = &machines[j]; + memset(out_amp, 0, sizeof(out_amp)); - if ((j & 1) == 0 && input_audio_file_name) + for (i = 0; i < 2; i++) + { + /* Update T.30 timing */ + logging = t30_get_logging_state(t30_state[i]); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + + if (mode[i] == T38_TERMINAL_FAX) { - mc->len = sf_readf_short(input_wave_handle, mc->amp, SAMPLES_PER_CHUNK); - if (mc->len == 0) - break; + /* Update T.38 termination timing */ + logging = t38_terminal_get_logging_state(t38_state[i]); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + logging = t38_core_get_logging_state(t38_core_state[i]); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + + completed[i] = t38_terminal_send_timeout(t38_state[i], SAMPLES_PER_CHUNK); } else { - mc->len = fax_tx(mc->fax, mc->amp, SAMPLES_PER_CHUNK); - if (mc->awgn) - { - for (k = 0; k < mc->len; k++) - mc->amp[k] = ((int16_t) (mc->amp[k]*signal_scaling)) + awgn(mc->awgn); - } - } - mc->total_audio_time += SAMPLES_PER_CHUNK; - if (!use_transmit_on_idle) - { - /* The receive side always expects a full block of samples, but the - transmit side may not be sending any when it doesn't need to. We - may need to pad with some silence. */ - if (mc->len < SAMPLES_PER_CHUNK) - { - memset(mc->amp + mc->len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - mc->len)); - mc->len = SAMPLES_PER_CHUNK; - } - } - t30 = fax_get_t30_state(mc->fax); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, mc->len); - logging = fax_get_logging_state(mc->fax); - span_log_bump_samples(logging, mc->len); + /* Update audio FAX timing */ + logging = fax_get_logging_state(fax_state[i]); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - if (log_audio) - { - for (k = 0; k < mc->len; k++) - out_amp[2*k + j] = mc->amp[k]; - } - if (machines[j ^ 1].len < SAMPLES_PER_CHUNK) - memset(machines[j ^ 1].amp + machines[j ^ 1].len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - machines[j ^ 1].len)); - t30 = fax_get_t30_state(mc->fax); -#if defined(WITH_SPANDSP_INTERNALS) - if (use_line_hits) - { - /* TODO: This applies very crude line hits. improve it */ - if (t30->state == 22) + fax_rx(fax_state[i], fax_rx_buf[i], SAMPLES_PER_CHUNK); + if (!t30_call_active(t30_state[i])) { - if (++mc->error_delay == 100) + completed[i] = TRUE; + continue; + } + + if (i == 0 && input_wave_handle) + { + t30_len[i] = sf_readf_short(input_wave_handle, fax_tx_buf[i], SAMPLES_PER_CHUNK); + if (t30_len[i] == 0) + break; + } + else + { + t30_len[i] = fax_tx(fax_state[i], fax_tx_buf[i], SAMPLES_PER_CHUNK); + if (!use_transmit_on_idle) { - fprintf(stderr, "HIT %d!\n", j); - mc->error_delay = 0; - for (k = 0; k < 5; k++) - mc->amp[k] = 0; + /* The receive side always expects a full block of samples, but the + transmit side may not be sending any when it doesn't need to. We + may need to pad with some silence. */ + if (t30_len[i] < SAMPLES_PER_CHUNK) + { + memset(t30_amp[i] + t30_len[i], 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len[i])); + t30_len[i] = SAMPLES_PER_CHUNK; + } } - } - } - if (t30->state == t30_state_to_wreck) - memset(machines[j ^ 1].amp, 0, sizeof(int16_t)*SAMPLES_PER_CHUNK); -#endif - if (fax_rx(mc->fax, machines[j ^ 1].amp, SAMPLES_PER_CHUNK)) - break; - if (!mc->done) - alldone = FALSE; - } + if (awgn_state[i]) + { + for (j = 0; j < t30_len[i]; j++) + fax_tx_buf[i][j] = ((int16_t) (fax_tx_buf[i][j]*signal_scaling)) + awgn(awgn_state[i]); + } + } + if (log_audio) + { + for (j = 0; j < t30_len[i]; j++) + out_amp[4*j + 2*i] = t30_amp[i][j]; + } + if (feedback_audio) + { + for (j = 0; j < t30_len[i]; j++) + t30_amp[i][j] += t38_amp_hist_a[hist_ptr][j] >> 1; + memcpy(t38_amp_hist_a[hist_ptr], t38_amp[i], sizeof(int16_t)*SAMPLES_PER_CHUNK); + } + if (mode[i] == T38_GATEWAY_FAX) + { + /* Update T.38 gateway timing */ + logging = t38_gateway_get_logging_state(t38_gateway_state[i]); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + logging = t38_core_get_logging_state(t38_core_state[i]); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + + if (drop_frame_rate && --drop_frame == 0) + { + drop_frame = drop_frame_rate; + if (t38_gateway_rx_fillin(t38_gateway_state[i], SAMPLES_PER_CHUNK)) + break; + } + else + { + if (t38_gateway_rx(t38_gateway_state[i], t38_gateway_rx_buf[i], SAMPLES_PER_CHUNK)) + break; + } + + t38_len[i] = t38_gateway_tx(t38_gateway_state[i], t38_gateway_tx_buf[i], SAMPLES_PER_CHUNK); + if (!use_transmit_on_idle) + { + if (t38_len[i] < SAMPLES_PER_CHUNK) + { + memset(t38_amp[i] + t38_len[i], 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len[i])); + t38_len[i] = SAMPLES_PER_CHUNK; + } + } + if (feedback_audio) + { + for (j = 0; j < t30_len[i]; j++) + t30_amp[i][j] += t38_amp_hist_a[hist_ptr][j] >> 1; + memcpy(t38_amp_hist_a[hist_ptr], t38_amp[i], sizeof(int16_t)*SAMPLES_PER_CHUNK); + } + + if (log_audio) + { + for (j = 0; j < t38_len[i]; j++) + out_amp[4*j + 2*i + 1] = t38_amp[i][j]; + } + } + } + if (mode[i] != AUDIO_FAX) + { + while ((msg_len = g1050_get(g1050_path[i], msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) + { +#if defined(ENABLE_GUI) + if (use_gui) + media_monitor_rx(seq_no, tx_when, rx_when); +#endif + t38_core_rx_ifp_packet(t38_core_state[i ^ 1], msg, msg_len, seq_no); + } + } + } if (log_audio) { outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK); @@ -525,32 +1049,83 @@ int main(int argc, char *argv[]) break; } - if (alldone || j < FAX_MACHINES) + when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; + + if (completed[0] && completed[1]) break; +#if defined(ENABLE_GUI) + if (use_gui) + media_monitor_update_display(); +#endif + if (++hist_ptr > 3) + hist_ptr = 0; } - time(&end_time); - for (j = 0; j < FAX_MACHINES; j++) + for (i = 0; i < 2; i++) { - mc = &machines[j]; - fax_release(mc->fax); + if (mode[i] == T38_GATEWAY_FAX) + { + t38_gateway_get_transfer_statistics(t38_gateway_state[i], &t38_stats); + printf("%c side exchanged %d pages at %dbps, in %s mode\n", + i + 'A', + t38_stats.pages_transferred, + t38_stats.bit_rate, + (t38_stats.error_correcting_mode) ? "ECM" : "non-ECM"); + } + } + if (input_wave_handle) + { + if (sf_close_telephony(input_wave_handle)) + { + fprintf(stderr, " Cannot close audio file '%s'\n", decode_file_name); + exit(2); + } } if (log_audio) { - if (sf_close(wave_handle)) + if (sf_close_telephony(wave_handle)) { - fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); + fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME); exit(2); } } - if (input_audio_file_name) + + /* Check how many pages should have been transferred */ + expected_pages = get_tiff_total_pages(input_tiff_file_name); + if (end_page >= 0 && expected_pages > end_page + 1) + expected_pages = end_page + 1; + if (start_page >= 0) + expected_pages -= start_page; + /* Check how many pages were transferred */ + for (i = 0; i < 2; i++) { - if (sf_close(input_wave_handle)) + if (!phase_e_reached[i]) + break; + if (!succeeded[i]) + break; + t30_get_transfer_statistics(t30_state[i], &t30_stats); + if (i & 1) { - fprintf(stderr, " Cannot close audio file '%s'\n", input_audio_file_name); - exit(2); + if (t30_stats.pages_tx != 0 || t30_stats.pages_rx != expected_pages) + break; } + else + { + if (t30_stats.pages_tx != expected_pages || t30_stats.pages_rx != 0) + break; + } + if (mode[i] == T38_TERMINAL_FAX) + t38_terminal_release(t38_state[i]); + else + fax_release(fax_state[i]); + if (mode[i] == T38_GATEWAY_FAX) + t38_gateway_release(t38_gateway_state[i]); } - printf("Total audio time = %ds (wall time %ds)\n", machines[0].total_audio_time/8000, (int) (end_time - start_time)); + if (i < 2) + { + printf("Tests failed\n"); + exit(2); + } + printf("Tests passed\n"); return 0; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/tests/fax_tests.sh b/libs/spandsp/tests/fax_tests.sh index 41f6c2d72c..a798ff8a6a 100755 --- a/libs/spandsp/tests/fax_tests.sh +++ b/libs/spandsp/tests/fax_tests.sh @@ -18,8 +18,8 @@ run_fax_test() { rm -f fax_tests_1.tif - echo ./fax_tests ${OPTS} -i ${FILE} - ./fax_tests ${OPTS} -i ${FILE} >xyzzy 2>xyzzy2 + echo -i ${FILE} ${OPTS} + ./fax_tests -i ${FILE} ${OPTS} >xyzzy 2>xyzzy2 RETVAL=$? if [ $RETVAL != 0 ] then diff --git a/libs/spandsp/tests/fax_utils.c b/libs/spandsp/tests/fax_utils.c index 585cfa4f2b..bd69917ef1 100644 --- a/libs/spandsp/tests/fax_utils.c +++ b/libs/spandsp/tests/fax_utils.c @@ -84,25 +84,36 @@ void fax_log_rx_parameters(t30_state_t *s, const char *tag) } /*- End of function --------------------------------------------------------*/ -void fax_log_transfer_statistics(t30_state_t *s, const char *tag) +void fax_log_final_transfer_statistics(t30_state_t *s, const char *tag) { t30_stats_t t; t30_get_transfer_statistics(s, &t); - printf("%s: tx pages %d, rx pages %d\n", tag, t.pages_tx, t.pages_rx); - printf("%s: pages in the file %d\n", tag, t.pages_in_file); - printf("%s: compression type %s (%d)\n", tag, t4_encoding_to_str(t.encoding), t.encoding); - printf("%s: compressed image size %d bytes\n", tag, t.image_size); - printf("%s: image size %d pels x %d pels\n", tag, t.width, t.length); - printf("%s: image resolution %d pels/m x %d pels/m\n", tag, t.x_resolution, t.y_resolution); - printf("%s: bit rate %d\n", tag, t.bit_rate); + printf("%s: Bit rate %d\n", tag, t.bit_rate); printf("%s: ECM %s\n", tag, (t.error_correcting_mode) ? "on" : "off"); - printf("%s: bad rows %d, longest bad row run %d\n", tag, t.bad_rows, t.longest_bad_row_run); - printf("%s: bad ECM frames %d\n", tag, t.error_correcting_mode_retries); //printf("%s: RTP events %d. RTN events %d\n", tag, t.rtp_events, t.rtn_events); + printf("%s: Tx pages %d, rx pages %d\n", tag, t.pages_tx, t.pages_rx); +} +/*- End of function --------------------------------------------------------*/ + +void fax_log_page_transfer_statistics(t30_state_t *s, const char *tag) +{ + t30_stats_t t; + + t30_get_transfer_statistics(s, &t); + printf("%s: Page statistics\n", tag); + printf("%s: Pages in the file %d\n", tag, t.pages_in_file); + printf("%s: Bad rows %d, longest bad row run %d\n", tag, t.bad_rows, t.longest_bad_row_run); + printf("%s: Bad ECM frames %d\n", tag, t.error_correcting_mode_retries); + printf("%s: Compression type %s (%d)\n", tag, t4_encoding_to_str(t.encoding), t.encoding); + printf("%s: Compressed image size %d bytes\n", tag, t.image_size); + printf("%s: Image size %d pels x %d pels\n", tag, t.width, t.length); + printf("%s: Image resolution %d pels/m x %d pels/m\n", tag, t.x_resolution, t.y_resolution); #if defined(WITH_SPANDSP_INTERNALS) - printf("%s: bits per row - min %d, max %d\n", tag, s->t4.min_row_bits, s->t4.max_row_bits); + printf("%s: Bits per row - min %d, max %d\n", tag, s->t4.min_row_bits, s->t4.max_row_bits); #endif + + fax_log_final_transfer_statistics(s, tag); } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/tests/fax_utils.h b/libs/spandsp/tests/fax_utils.h index 5bcdec9113..a2a1c6c12b 100644 --- a/libs/spandsp/tests/fax_utils.h +++ b/libs/spandsp/tests/fax_utils.h @@ -37,7 +37,9 @@ void fax_log_tx_parameters(t30_state_t *s, const char *tag); void fax_log_rx_parameters(t30_state_t *s, const char *tag); -void fax_log_transfer_statistics(t30_state_t *s, const char *tag); +void fax_log_page_transfer_statistics(t30_state_t *s, const char *tag); + +void fax_log_final_transfer_statistics(t30_state_t *s, const char *tag); int get_tiff_total_pages(const char *file); diff --git a/libs/spandsp/tests/g1050_tests.c b/libs/spandsp/tests/g1050_tests.c index 74f8beebac..9befdc3e2b 100644 --- a/libs/spandsp/tests/g1050_tests.c +++ b/libs/spandsp/tests/g1050_tests.c @@ -68,7 +68,6 @@ int main(int argc, char *argv[]) int num_packets; int model_no; int speed_pattern_no; - int use_gui; int simulation_time; int i; int len; @@ -87,11 +86,16 @@ int main(int argc, char *argv[]) int highest_seq_no_got; int opt; FILE *out_file; +#if defined(ENABLE_GUI) + int use_gui; +#endif +#if defined(ENABLE_GUI) + use_gui = FALSE; +#endif model_no = MODEL_NO; speed_pattern_no = SPEED_PATTERN_NO; simulation_time = SIMULATION_TIME; - use_gui = FALSE; while ((opt = getopt(argc, argv, "gm:s:t:")) != -1) { switch (opt) diff --git a/libs/spandsp/tests/g722_tests.c b/libs/spandsp/tests/g722_tests.c index 9089ee64a0..c33d9e67b6 100644 --- a/libs/spandsp/tests/g722_tests.c +++ b/libs/spandsp/tests/g722_tests.c @@ -224,6 +224,7 @@ static void itu_compliance_tests(void) int j; int k; int len_comp; + int len_comp_lower; int len_comp_upper; int len_data; int len; @@ -243,6 +244,11 @@ static void itu_compliance_tests(void) /* Get the reference output data */ len_comp = get_test_vector(encode_test_files[file + 1], itu_ref, MAX_TEST_VECTOR_LEN); + if (len_data != len_comp) + { + printf("Test data length mismatch\n"); + exit(2); + } /* Process the input data */ /* Skip the reset stuff at each end of the data */ for (i = 0; i < len_data; i++) @@ -294,13 +300,18 @@ static void itu_compliance_tests(void) /* Get the input data */ len_data = get_test_vector(decode_test_files[file], (uint16_t *) itu_data, MAX_TEST_VECTOR_LEN); - + /* Get the lower reference output data */ - len_comp = get_test_vector(decode_test_files[file + mode], itu_ref, MAX_TEST_VECTOR_LEN); - + len_comp_lower = get_test_vector(decode_test_files[file + mode], itu_ref, MAX_TEST_VECTOR_LEN); + /* Get the upper reference output data */ len_comp_upper = get_test_vector(decode_test_files[file + 4], itu_ref_upper, MAX_TEST_VECTOR_LEN); - + + if (len_data != len_comp_lower || len_data != len_comp_lower) + { + printf("Test data length mismatch\n"); + exit(2); + } /* Process the input data */ /* Skip the reset stuff at each end of the data */ for (i = 0; i < len_data; i++) @@ -378,6 +389,7 @@ static void signal_to_distortion_tests(void) in_level = power_meter_update(&in_meter, original[i]); len2 = g722_encode(&enc_state, compressed, original, len); len3 = g722_decode(&dec_state, decompressed, compressed, len2); + out_level = 0; for (i = 0; i < len3; i++) out_level = power_meter_update(&out_meter, decompressed[i]); printf("Silence produces %d at the output\n", out_level); diff --git a/libs/spandsp/tests/g726_tests.c b/libs/spandsp/tests/g726_tests.c index 7c7fd15c91..40552bc28d 100644 --- a/libs/spandsp/tests/g726_tests.c +++ b/libs/spandsp/tests/g726_tests.c @@ -1083,7 +1083,6 @@ static void itu_compliance_tests(void) int len3; int i; int test; - int bits_per_code; int bad_samples; int conditioning_samples; int samples; @@ -1106,22 +1105,6 @@ static void itu_compliance_tests(void) itu_test_sets[test].rate, itu_test_sets[test].compression_law, itu_test_sets[test].decompression_law); - switch (itu_test_sets[test].rate) - { - case 16000: - bits_per_code = 2; - break; - case 24000: - bits_per_code = 3; - break; - case 32000: - default: - bits_per_code = 4; - break; - case 40000: - bits_per_code = 5; - break; - } if (itu_test_sets[test].compression_law != G726_ENCODING_NONE) { /* Test the encode side */ @@ -1226,7 +1209,6 @@ int main(int argc, char *argv[]) SNDFILE *outhandle; int16_t amp[1024]; int frames; - int outframes; int adpcm; int packing; @@ -1283,7 +1265,7 @@ int main(int argc, char *argv[]) { adpcm = g726_encode(&enc_state, adpcmdata, amp, frames); frames = g726_decode(&dec_state, amp, adpcmdata, adpcm); - outframes = sf_writef_short(outhandle, amp, frames); + sf_writef_short(outhandle, amp, frames); } if (sf_close_telephony(inhandle)) { diff --git a/libs/spandsp/tests/gsm0610_tests.c b/libs/spandsp/tests/gsm0610_tests.c index b4a96cd1d7..a2c66dd99b 100644 --- a/libs/spandsp/tests/gsm0610_tests.c +++ b/libs/spandsp/tests/gsm0610_tests.c @@ -543,7 +543,6 @@ int main(int argc, char *argv[]) SNDFILE *inhandle; SNDFILE *outhandle; int frames; - int outframes; int bytes; int16_t pre_amp[HIST_LEN]; int16_t post_amp[HIST_LEN]; @@ -605,7 +604,7 @@ int main(int argc, char *argv[]) { bytes = gsm0610_encode(gsm0610_enc_state, gsm0610_data, pre_amp, frames); gsm0610_decode(gsm0610_dec_state, post_amp, gsm0610_data, bytes); - outframes = sf_writef_short(outhandle, post_amp, frames); + sf_writef_short(outhandle, post_amp, frames); } if (sf_close_telephony(inhandle)) diff --git a/libs/spandsp/tests/ima_adpcm_tests.c b/libs/spandsp/tests/ima_adpcm_tests.c index 8458c835c0..2bcadb9d29 100644 --- a/libs/spandsp/tests/ima_adpcm_tests.c +++ b/libs/spandsp/tests/ima_adpcm_tests.c @@ -68,7 +68,6 @@ int main(int argc, char *argv[]) SNDFILE *outhandle; int frames; int dec_frames; - int outframes; int ima_bytes; double pre_energy; double post_energy; @@ -180,7 +179,7 @@ int main(int argc, char *argv[]) hist_out = 0; diff_energy += (double) xx * (double) xx; } - outframes = sf_writef_short(outhandle, post_amp, dec_frames); + sf_writef_short(outhandle, post_amp, dec_frames); } if (sf_close_telephony(inhandle)) { diff --git a/libs/spandsp/tests/line_model_tests.c b/libs/spandsp/tests/line_model_tests.c index 3c2a2b2220..890c29741e 100644 --- a/libs/spandsp/tests/line_model_tests.c +++ b/libs/spandsp/tests/line_model_tests.c @@ -366,24 +366,19 @@ int main(int argc, char *argv[]) { int line_model_no; int speech_test; - int log_audio; int opt; channel_codec = MUNGE_CODEC_NONE; - log_audio = FALSE; line_model_no = 0; rbs_pattern = 0; speech_test = FALSE; - while ((opt = getopt(argc, argv, "c:lm:r:s:")) != -1) + while ((opt = getopt(argc, argv, "c:m:r:s:")) != -1) { switch (opt) { case 'c': channel_codec = atoi(optarg); break; - case 'l': - log_audio = TRUE; - break; case 'm': line_model_no = atoi(optarg); break; diff --git a/libs/spandsp/tests/lpc10_tests.c b/libs/spandsp/tests/lpc10_tests.c index 22a36cad44..9822e6d2c2 100644 --- a/libs/spandsp/tests/lpc10_tests.c +++ b/libs/spandsp/tests/lpc10_tests.c @@ -69,7 +69,6 @@ int main(int argc, char *argv[]) SNDFILE *refhandle; SNDFILE *outhandle; int frames; - int outframes; double pre_energy; double post_energy; double ref_energy; @@ -186,7 +185,7 @@ int main(int argc, char *argv[]) while ((len = read(decompress_file, lpc10_data, BLOCKS_PER_READ*7)) > 0) { lpc10_decode(lpc10_dec_state, post_amp, lpc10_data, len/7); - outframes = sf_writef_short(outhandle, post_amp, BLOCK_LEN*len/7); + sf_writef_short(outhandle, post_amp, BLOCK_LEN*len/7); } } else @@ -216,9 +215,9 @@ int main(int argc, char *argv[]) } block_no++; if (log_error) - outframes = sf_writef_short(outhandle, log_amp, dec_len); + sf_writef_short(outhandle, log_amp, dec_len); else - outframes = sf_writef_short(outhandle, post_amp, dec_len); + sf_writef_short(outhandle, post_amp, dec_len); } if (sf_close_telephony(inhandle)) { diff --git a/libs/spandsp/tests/modem_echo_tests.c b/libs/spandsp/tests/modem_echo_tests.c index ab2c6b627c..07ffa0e7ed 100644 --- a/libs/spandsp/tests/modem_echo_tests.c +++ b/libs/spandsp/tests/modem_echo_tests.c @@ -259,9 +259,6 @@ int main(int argc, char *argv[]) int clean; int16_t rx; int16_t tx; - int local_cur; - int far_cur; - int result_cur; int line_model_no; time_t now; power_meter_t power_before; @@ -302,9 +299,6 @@ int main(int argc, char *argv[]) start_echo_can_monitor(256); #endif - local_cur = 0; - far_cur = 0; - result_cur = 0; channel_model_create(line_model_no); #if defined(ENABLE_GUI) if (use_gui) diff --git a/libs/spandsp/tests/oki_adpcm_tests.c b/libs/spandsp/tests/oki_adpcm_tests.c index 4b4c0e63a1..2e356cdb22 100644 --- a/libs/spandsp/tests/oki_adpcm_tests.c +++ b/libs/spandsp/tests/oki_adpcm_tests.c @@ -69,7 +69,6 @@ int main(int argc, char *argv[]) SNDFILE *outhandle; int frames; int dec_frames; - int outframes; int oki_bytes; int bit_rate; double pre_energy; @@ -192,7 +191,7 @@ int main(int argc, char *argv[]) hist_out = 0; diff_energy += (double) xx * (double) xx; } - outframes = sf_writef_short(outhandle, post_amp, dec_frames); + sf_writef_short(outhandle, post_amp, dec_frames); } close(encoded_fd); } @@ -251,7 +250,7 @@ int main(int argc, char *argv[]) diff_energy += (double) xx * (double) xx; //post_amp[i] = xx; } - outframes = sf_writef_short(outhandle, post_amp, dec_frames); + sf_writef_short(outhandle, post_amp, dec_frames); } printf("Pre samples: %d\n", total_pre_samples); printf("Compressed bytes: %d\n", total_compressed_bytes); diff --git a/libs/spandsp/tests/pcap_parse.c b/libs/spandsp/tests/pcap_parse.c index 900f957068..2571dc7cbf 100644 --- a/libs/spandsp/tests/pcap_parse.c +++ b/libs/spandsp/tests/pcap_parse.c @@ -49,7 +49,6 @@ #endif #include -#include #include #include #include @@ -93,9 +92,18 @@ typedef struct _ether_hdr { char ether_dst[6]; char ether_src[6]; - u_int16_t ether_type; + uint16_t ether_type; } ether_hdr; +typedef struct _linux_sll_hdr +{ + uint16_t packet_type; + uint16_t arphrd; + uint16_t slink_length; + uint8_t bytes[8]; + uint16_t ether_type; +} linux_sll_hdr; + typedef struct _null_hdr { uint32_t pf_type; @@ -129,6 +137,7 @@ int pcap_scan_pkts(const char *file, int total_pkts; uint32_t pktlen; ether_hdr *ethhdr; + linux_sll_hdr *sllhdr; null_hdr *nullhdr; struct iphdr *iphdr; #if !defined(__CYGWIN__) @@ -146,13 +155,22 @@ int pcap_scan_pkts(const char *file, } datalink = pcap_datalink(pcap); /* DLT_EN10MB seems to apply to all forms of ethernet, not just the 10MB kind. */ - if (datalink != DLT_EN10MB && datalink != DLT_NULL) + switch (datalink) { + case DLT_EN10MB: + printf("Datalink type ethernet\n"); + break; + case DLT_LINUX_SLL: + printf("Datalink type cooked Linux socket\n"); + break; + case DLT_NULL: + printf("Datalink type NULL\n"); + break; + default: fprintf(stderr, "Unsupported data link type %d\n", datalink); return -1; } - printf("Datalink type %d\n", datalink); pkthdr = NULL; pktdata = NULL; #if defined(HAVE_PCAP_NEXT_EX) @@ -167,8 +185,9 @@ int pcap_scan_pkts(const char *file, while ((pktdata = (uint8_t *) pcap_next(pcap, pkthdr)) != NULL) { #endif - if (datalink == DLT_EN10MB) + switch (datalink) { + case DLT_EN10MB: ethhdr = (ether_hdr *) pktdata; packet_type = ntohs(ethhdr->ether_type); #if !defined(__CYGWIN__) @@ -182,16 +201,29 @@ int pcap_scan_pkts(const char *file, continue; } iphdr = (struct iphdr *) ((uint8_t *) ethhdr + sizeof(*ethhdr)); - } - else if (datalink == DLT_NULL) - { + break; + case DLT_LINUX_SLL: + sllhdr = (linux_sll_hdr *) pktdata; + packet_type = ntohs(sllhdr->ether_type); +#if !defined(__CYGWIN__) + if (packet_type != 0x0800 /* IPv4 */ + && + packet_type != 0x86DD) /* IPv6 */ +#else + if (packet_type != 0x0800) /* IPv4 */ +#endif + { + continue; + } + iphdr = (struct iphdr *) ((uint8_t *) sllhdr + sizeof(*sllhdr)); + break; + case DLT_NULL: nullhdr = (null_hdr *) pktdata; if (nullhdr->pf_type != PF_INET && nullhdr->pf_type != PF_INET6) continue; iphdr = (struct iphdr *) ((uint8_t *) nullhdr + sizeof(*nullhdr)); - } - else - { + break; + default: continue; } #if 0 diff --git a/libs/spandsp/tests/r2_mf_rx_tests.c b/libs/spandsp/tests/r2_mf_rx_tests.c index 6f71965291..da72fc113d 100644 --- a/libs/spandsp/tests/r2_mf_rx_tests.c +++ b/libs/spandsp/tests/r2_mf_rx_tests.c @@ -244,12 +244,7 @@ static int test_a_tone_set(int fwd) int16_t amp[100000]; r2_mf_rx_state_t mf_state; awgn_state_t noise_source; - const mf_digit_tones_t *tone; - if (fwd) - tone = &r2_mf_fwd_tones[0]; - else - tone = &r2_mf_back_tones[0]; r2_mf_rx_init(&mf_state, fwd, NULL, NULL); /* Test 1: Mitel's test 1 isn't really a test. Its a calibration step, diff --git a/libs/spandsp/tests/r2_mf_tx_tests.c b/libs/spandsp/tests/r2_mf_tx_tests.c index 7ceee190cb..172b92f156 100644 --- a/libs/spandsp/tests/r2_mf_tx_tests.c +++ b/libs/spandsp/tests/r2_mf_tx_tests.c @@ -62,7 +62,6 @@ int main(int argc, char *argv[]) int16_t amp[1000]; int len; SNDFILE *outhandle; - int outframes; int digit; const char *digits = "0123456789BCDEF"; @@ -79,12 +78,12 @@ int main(int argc, char *argv[]) len = r2_mf_tx(&gen, amp, 1000); printf("Generated %d samples of %c\n", len, digits[digit]); if (len > 0) - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); r2_mf_tx_put(&gen, 0); len = r2_mf_tx(&gen, amp, 1000); printf("Generated %d samples\n", len); if (len > 0) - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); } r2_mf_tx_init(&gen, TRUE); @@ -94,12 +93,12 @@ int main(int argc, char *argv[]) len = r2_mf_tx(&gen, amp, 1000); printf("Generated %d samples of %c\n", len, digits[digit]); if (len > 0) - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); r2_mf_tx_put(&gen, 0); len = r2_mf_tx(&gen, amp, 1000); printf("Generated %d samples\n", len); if (len > 0) - outframes = sf_writef_short(outhandle, amp, len); + sf_writef_short(outhandle, amp, len); } if (sf_close_telephony(outhandle)) diff --git a/libs/spandsp/tests/regression_tests.sh b/libs/spandsp/tests/regression_tests.sh index a2b3649da0..4f32ebbc32 100755 --- a/libs/spandsp/tests/regression_tests.sh +++ b/libs/spandsp/tests/regression_tests.sh @@ -179,60 +179,30 @@ echo dtmf_tx_tests completed OK #echo echo_tests completed OK echo echo_tests not enabled -#Try the ITU test pages without ECM -rm -f fax_tests_1.tif -./fax_tests >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo fax_tests failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} fax_tests_1.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo fax_tests failed! - exit $RETVAL -fi -#Try the ITU test pages with ECM -rm -f fax_tests_1.tif -./fax_tests -e >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo fax_tests -e failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} fax_tests_1.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo fax_tests -e failed! - exit $RETVAL -fi -#Try some mixed sized test pages without ECM -rm -f fax_tests_1.tif -./fax_tests -i ${MIXEDSIZES_TIF} >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo fax_tests mixed-sizes failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${MIXEDSIZES_TIF} fax_tests_1.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo fax_tests mixed-sizes failed! - exit $RETVAL -fi +for OPTS in "-p AA" "-p AA -e" "-p TT" "-p TT -e" "-p GG" "-p GG -e" "-p TG" "-p TG -e" "-p GT" "-p GT -e" +do + for FILE in ${ITUTESTS_TIF} ${MIXEDSIZES_TIF} + do + rm -f fax_tests.tif + ./fax_tests ${OPTS} -i ${FILE} >$STDOUT_DEST 2>$STDERR_DEST + RETVAL=$? + if [ $RETVAL != 0 ] + then + echo fax_tests ${OPTS} -i ${FILE} failed! + exit $RETVAL + fi + # Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t + # option means the normal differences in tags will be ignored. + tiffcmp -t ${FILE} fax_tests.tif >/dev/null + RETVAL=$? + if [ $RETVAL != 0 ] + then + echo fax_tests ${OPTS} -i ${FILE} failed! + exit $RETVAL + fi + echo fax_tests ${OPTS} -i ${FILE} completed OK + done +done echo fax_tests completed OK ./fsk_tests >$STDOUT_DEST 2>$STDERR_DEST @@ -518,6 +488,15 @@ then fi echo t31_tests completed OK +./t35_tests -s >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo t35_tests -s failed! + exit $RETVAL +fi +echo t35_tests completed OK + ./t38_core_tests >$STDOUT_DEST 2>$STDERR_DEST RETVAL=$? if [ $RETVAL != 0 ] @@ -527,78 +506,6 @@ then fi echo t38_core_tests completed OK -rm -f t38.tif -./t38_gateway_tests >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_tests failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_tests failed! - exit $RETVAL -fi -rm -f t38.tif -./t38_gateway_tests -e >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_tests -e failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_tests -e failed! - exit $RETVAL -fi -echo t38_gateway_tests completed OK - -rm -f t38.tif -./t38_gateway_to_terminal_tests >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_to_terminal_tests failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_to_terminal_tests failed! - exit $RETVAL -fi -rm -f t38.tif -./t38_gateway_to_terminal_tests -e >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_to_terminal_tests -e failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_gateway_to_terminal_tests -e failed! - exit $RETVAL -fi -echo t38_gateway_to_terminal_tests completed OK - ./t38_non_ecm_buffer_tests >$STDOUT_DEST 2>$STDERR_DEST RETVAL=$? if [ $RETVAL != 0 ] @@ -608,78 +515,6 @@ then fi echo t38_non_ecm_buffer_tests completed OK -rm -f t38.tif -./t38_terminal_to_gateway_tests >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_to_gateway_tests failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_to_gateway_tests failed! - exit $RETVAL -fi -rm -f t38.tif -./t38_terminal_to_gateway_tests -e >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_to_gateway_tests -e failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_to_gateway_tests -e failed! - exit $RETVAL -fi -echo t38_terminal_to_gateway_tests completed OK - -rm -f t38.tif -./t38_terminal_tests >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_tests failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_tests failed! - exit $RETVAL -fi -rm -f t38.tif -./t38_terminal_tests -e >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_tests -e failed! - exit $RETVAL -fi -# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t -# option means the normal differences in tags will be ignored. -tiffcmp -t ${ITUTESTS_TIF} t38.tif >/dev/null -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo t38_terminal_tests -e failed! - exit $RETVAL -fi -echo t38_terminal_tests completed OK - rm -f t4_tests_receive.tif ./t4_tests >$STDOUT_DEST 2>$STDERR_DEST RETVAL=$? @@ -699,6 +534,8 @@ echo t4_tests completed OK # exit $RETVAL #fi #echo t4_t6_tests completed OK +echo t4_t6_tests not enabled + #rm -f t81_t82_arith_coding_tests_receive.tif #./t4_tests >$STDOUT_DEST 2>$STDERR_DEST #RETVAL=$? @@ -711,7 +548,7 @@ echo t4_tests completed OK echo t81_t82_arith_coding_tests not enabled #rm -f t85_tests_receive.tif -#./t4_tests >$STDOUT_DEST 2>$STDERR_DEST +#./t85_tests >$STDOUT_DEST 2>$STDERR_DEST #RETVAL=$? #if [ $RETVAL != 0 ] #then @@ -760,100 +597,67 @@ echo tone_detect_tests not enabled #echo tone_generate_tests completed OK echo tone_generate_tests not enabled -./v17_tests -b 14400 -s -42 -n -66 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v17_tests failed! - exit $RETVAL -fi -./v17_tests -b 12000 -s -42 -n -61 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v17_tests failed! - exit $RETVAL -fi -./v17_tests -b 9600 -s -42 -n -59 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v17_tests failed! - exit $RETVAL -fi -./v17_tests -b 7200 -s -42 -n -56 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v17_tests failed! - exit $RETVAL -fi +for OPTS in "-b 14400 -s -42 -n -66" "-b 12000 -s -42 -n -61" "-b 9600 -s -42 -n -59" "-b 7200 -s -42 -n -56" +do + ./v17_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST + RETVAL=$? + if [ $RETVAL != 0 ] + then + echo v17_tests ${OPTS} failed! + exit $RETVAL + fi +done echo v17_tests completed OK -#./v22bis_tests -b 2400 >$STDOUT_DEST 2>$STDERR_DEST -#RETVAL=$? -#if [ $RETVAL != 0 ] -#then -# echo v22bis_tests failed! -# exit $RETVAL -#fi -#./v22bis_tests -b 1200 >$STDOUT_DEST 2>$STDERR_DEST -#RETVAL=$? -#if [ $RETVAL != 0 ] -#then -# echo v22bis_tests failed! -# exit $RETVAL -#fi +#for OPTS in "-b 2400" "-b 1200" +#do +# ./v22bis_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST +# RETVAL=$? +# if [ $RETVAL != 0 ] +# then +# echo v22bis_tests ${OPTS} failed! +# exit $RETVAL +# fi +#done #echo v22bis_tests completed OK echo v22bis_tests not enabled -./v27ter_tests -b 4800 -s -42 -n -57 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v27ter_tests failed! - exit $RETVAL -fi -./v27ter_tests -b 2400 -s -42 -n -51 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v27ter_tests failed! - exit $RETVAL -fi +for OPTS in "-b 4800 -s -42 -n -57" "-b 2400 -s -42 -n -51" +do + ./v27ter_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST + RETVAL=$? + if [ $RETVAL != 0 ] + then + echo v27ter_tests ${OPTS} failed! + exit $RETVAL + fi +done echo v27ter_tests completed OK -./v29_tests -b 9600 -s -42 -n -62 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v29_tests failed! - exit $RETVAL -fi -./v29_tests -b 7200 -s -42 -n -58 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v29_tests failed! - exit $RETVAL -fi -./v29_tests -b 4800 -s -42 -n -54 >$STDOUT_DEST 2>$STDERR_DEST -RETVAL=$? -if [ $RETVAL != 0 ] -then - echo v29_tests failed! - exit $RETVAL -fi +for OPTS in "-b 9600 -s -42 -n -62" "-b 7200 -s -42 -n -58" "-b 4800 -s -42 -n -55" +do + ./v29_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST + RETVAL=$? + if [ $RETVAL != 0 ] + then + echo v29_tests ${OPTS} failed! + exit $RETVAL + fi +done echo v29_tests completed OK -#./v32bis_tests -b 14400 -s -42 -n -66 >$STDOUT_DEST 2>$STDERR_DEST -#RETVAL=$? -#if [ $RETVAL != 0 ] -#then -# echo v32bis_tests failed! -# exit $RETVAL -#fi +#for OPTS in "-b 14400 -s -42 -n -66" "-b 12000 -s -42 -n -61" "-b 9600 -s -42 -n -59" "-b 7200 -s -42 -n -56" +#do +# ./v32bis_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST +# RETVAL=$? +# if [ $RETVAL != 0 ] +# then +# echo v32bis_tests ${OPTS} failed! +# exit $RETVAL +# fi +#done #echo v32bis_tests completed OK +echo v32bis_tests not enabled ./v42_tests >$STDOUT_DEST 2>$STDERR_DEST RETVAL=$? diff --git a/libs/spandsp/tests/rfc2198_sim_tests.c b/libs/spandsp/tests/rfc2198_sim_tests.c index 34a19ad265..5f45df5431 100644 --- a/libs/spandsp/tests/rfc2198_sim_tests.c +++ b/libs/spandsp/tests/rfc2198_sim_tests.c @@ -70,7 +70,6 @@ int main(int argc, char *argv[]) int num_packets; int model_no; int speed_pattern_no; - int use_gui; int simulation_time; int i; int len; @@ -89,11 +88,16 @@ int main(int argc, char *argv[]) int highest_seq_no_got; int opt; FILE *out_file; +#if defined(ENABLE_GUI) + int use_gui; +#endif +#if defined(ENABLE_GUI) + use_gui = FALSE; +#endif model_no = MODEL_NO; speed_pattern_no = SPEED_PATTERN_NO; simulation_time = SIMULATION_TIME; - use_gui = FALSE; while ((opt = getopt(argc, argv, "gm:s:t:")) != -1) { switch (opt) diff --git a/libs/spandsp/tests/schedule_tests.c b/libs/spandsp/tests/schedule_tests.c index 576d08a1c4..81c467c927 100644 --- a/libs/spandsp/tests/schedule_tests.c +++ b/libs/spandsp/tests/schedule_tests.c @@ -84,23 +84,19 @@ static void callback2(span_sched_state_t *s, void *user_data) int main(int argc, char *argv[]) { int i; - int id1; - int id2; span_sched_state_t sched; uint64_t when; span_schedule_init(&sched); - id1 = span_schedule_event(&sched, 500000, callback1, NULL); - id2 = span_schedule_event(&sched, 550000, callback2, NULL); + span_schedule_event(&sched, 500000, callback1, NULL); + span_schedule_event(&sched, 550000, callback2, NULL); when1 = span_schedule_time(&sched) + 500000; when2 = span_schedule_time(&sched) + 550000; //span_schedule_del(&sched, id); for (i = 0; i < 100000000; i += 20000) - { span_schedule_update(&sched, 20000); - } when = span_schedule_time(&sched); if ((when1 - when) < 0 || (when1 - when) > 500000 || (when2 - when) < 0 || (when2 - when) > 550000) { diff --git a/libs/spandsp/tests/super_tone_rx_tests.c b/libs/spandsp/tests/super_tone_rx_tests.c index de96b365b8..717768d0c5 100644 --- a/libs/spandsp/tests/super_tone_rx_tests.c +++ b/libs/spandsp/tests/super_tone_rx_tests.c @@ -89,6 +89,10 @@ super_tone_tx_step_t *nutone_tree = NULL; super_tone_tx_step_t *congestiontone_tree = NULL; super_tone_tx_step_t *waitingtone_tree = NULL; +int level; + +#define SAMPLES_PER_CHUNK 160 + #if defined(HAVE_LIBXML2) static int parse_tone(super_tone_rx_descriptor_t *desc, int tone_id, super_tone_tx_step_t **tree, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) { @@ -366,52 +370,16 @@ static void tone_segment(void *data, int f1, int f2, int duration) } /*- End of function --------------------------------------------------------*/ -int main(int argc, char *argv[]) +static int talk_off_tests(super_tone_rx_state_t *super) { - int x; int16_t amp[8000]; int sample; int frames; - awgn_state_t noise_source; - super_tone_rx_state_t *super; - super_tone_rx_descriptor_t desc; + int j; + int x; - if ((inhandle = sf_open_telephony_read(IN_FILE_NAME, 1)) == NULL) - { - fprintf(stderr, " Cannot open audio file '%s'\n", IN_FILE_NAME); - exit(2); - } - super_tone_rx_make_descriptor(&desc); -#if defined(HAVE_LIBXML2) - get_tone_set(&desc, "../spandsp/global-tones.xml", (argc > 1) ? argv[1] : "hk"); -#endif - super_tone_rx_fill_descriptor(&desc); - if ((super = super_tone_rx_init(NULL, &desc, wakeup, (void *) "test")) == NULL) - { - printf(" Failed to create detector.\n"); - exit(2); - } - super_tone_rx_segment_callback(super, tone_segment); - awgn_init_dbm0(&noise_source, 1234567, -30.0f); - printf("Processing file\n"); - while ((frames = sf_readf_short(inhandle, amp, 8000))) - { - /* Add some noise to the signal for a more meaningful test. */ - //for (sample = 0; sample < frames; sample++) - // amp[sample] += saturate(amp[sample] + awgn (&noise_source)); - for (sample = 0; sample < frames; ) - { - x = super_tone_rx(super, amp + sample, frames - sample); - sample += x; - } - } - if (sf_close_telephony(inhandle)) - { - fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME); - exit(2); - } -#if 0 /* Test for voice immunity */ + printf("Talk off tests\n"); for (j = 0; bellcore_files[j][0]; j++) { if ((inhandle = sf_open_telephony_read(bellcore_files[j], 1)) == NULL) @@ -433,7 +401,101 @@ int main(int argc, char *argv[]) exit(2); } } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int detection_range_tests(super_tone_rx_state_t *super) +{ + int16_t amp[SAMPLES_PER_CHUNK]; + int i; + int j; + int x; + uint32_t phase; + int32_t phase_inc; + int scale; + + printf("Detection range tests\n"); + super_tone_rx_tone_callback(super, wakeup, (void *) "test"); + phase = 0; + phase_inc = dds_phase_rate(440.0f); + for (level = -80; level < 0; level++) + { + printf("Testing at %ddBm0\n", level); + scale = dds_scaling_dbm0(level); + for (j = 0; j < 100; j++) + { + for (i = 0; i < SAMPLES_PER_CHUNK; i++) + amp[i] = (dds(&phase, phase_inc)*scale) >> 15; + x = super_tone_rx(super, amp, SAMPLES_PER_CHUNK); + } + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int file_decode_tests(super_tone_rx_state_t *super, const char *file_name) +{ + int16_t amp[8000]; + int sample; + int frames; + int x; + awgn_state_t noise_source; + + printf("File decode tests\n"); + super_tone_rx_tone_callback(super, wakeup, (void *) "test"); + awgn_init_dbm0(&noise_source, 1234567, -30.0f); + printf("Processing file\n"); + if ((inhandle = sf_open_telephony_read(file_name, 1)) == NULL) + { + fprintf(stderr, " Cannot open audio file '%s'\n", file_name); + exit(2); + } + while ((frames = sf_readf_short(inhandle, amp, 8000))) + { + /* Add some noise to the signal for a more meaningful test. */ + //for (sample = 0; sample < frames; sample++) + // amp[sample] += saturate(amp[sample] + awgn (&noise_source)); + for (sample = 0; sample < frames; ) + { + x = super_tone_rx(super, amp + sample, frames - sample); + sample += x; + } + } + if (sf_close_telephony(inhandle)) + { + fprintf(stderr, " Cannot close audio file '%s'\n", file_name); + exit(2); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + const char *file_name; + super_tone_rx_state_t *super; + super_tone_rx_descriptor_t desc; + + super_tone_rx_make_descriptor(&desc); +#if defined(HAVE_LIBXML2) + get_tone_set(&desc, "../spandsp/global-tones.xml", (argc > 1) ? argv[1] : "hk"); #endif + super_tone_rx_fill_descriptor(&desc); + if ((super = super_tone_rx_init(NULL, &desc, wakeup, (void *) "test")) == NULL) + { + printf(" Failed to create detector.\n"); + exit(2); + } + super_tone_rx_segment_callback(super, tone_segment); + + detection_range_tests(super); + + file_name = IN_FILE_NAME; + file_decode_tests(super, file_name); + + talk_off_tests(super); + super_tone_rx_free(super); printf("Done\n"); return 0; diff --git a/libs/spandsp/tests/super_tone_tx_tests.c b/libs/spandsp/tests/super_tone_tx_tests.c index 5ab6ddcb50..2fabbbd7c9 100644 --- a/libs/spandsp/tests/super_tone_tx_tests.c +++ b/libs/spandsp/tests/super_tone_tx_tests.c @@ -67,6 +67,7 @@ SNDFILE *outhandle; super_tone_tx_step_t *tone_tree = NULL; +#if defined(HAVE_LIBXML2) static void play_tones(super_tone_tx_state_t *tone, int max_samples) { int16_t amp[8000]; @@ -93,7 +94,6 @@ static void play_tones(super_tone_tx_state_t *tone, int max_samples) } /*- End of function --------------------------------------------------------*/ -#if defined(HAVE_LIBXML2) static int parse_tone(super_tone_tx_step_t **tree, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) { xmlChar *x; @@ -289,7 +289,7 @@ int main(int argc, char *argv[]) #if defined(HAVE_LIBXML2) get_tone_set("../spandsp/global-tones.xml", (argc > 1) ? argv[1] : "hk"); #endif - if (sf_close (outhandle) != 0) + if (sf_close_telephony(outhandle)) { fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME); exit(2); diff --git a/libs/spandsp/tests/t31_tests.c b/libs/spandsp/tests/t31_tests.c index c0c85cc2a1..7f5e7c00a8 100644 --- a/libs/spandsp/tests/t31_tests.c +++ b/libs/spandsp/tests/t31_tests.c @@ -89,11 +89,14 @@ g1050_state_t *path_b_to_a; double when = 0.0; +int t38_mode = FALSE; + #define EXCHANGE(a,b) {a, sizeof(a) - 1, b, sizeof(b) - 1} #define RESPONSE(b) {"", 0, b, sizeof(b) - 1} #define FAST_RESPONSE(b) {NULL, -1, b, sizeof(b) - 1} #define FAST_SEND(b) {(const char *) 1, -2, b, sizeof(b) - 1} #define FAST_SEND_TCF(b) {(const char *) 2, -2, b, sizeof(b) - 1} +#define END_OF_SEQUENCE {NULL, -1, NULL, -1} static const struct command_response_s fax_send_test_seq[] = { @@ -144,7 +147,8 @@ static const struct command_response_s fax_send_test_seq[] = EXCHANGE("AT+FTH=3\r", "\r\nCONNECT\r\n"), // EXCHANGE("\xFF\x13\xFB\x10\x03", "\r\nOK\r\n"), - EXCHANGE("ATH0\r", "\r\nOK\r\n") + EXCHANGE("ATH0\r", "\r\nOK\r\n"), + END_OF_SEQUENCE }; static const struct command_response_s fax_receive_test_seq[] = @@ -187,7 +191,8 @@ static const struct command_response_s fax_receive_test_seq[] = // RESPONSE("\xFF\x13\xfb\x9a\xf6\x10\x03"), RESPONSE("\r\nOK\r\n"), - EXCHANGE("ATH0\r", "\r\nOK\r\n") + EXCHANGE("ATH0\r", "\r\nOK\r\n"), + END_OF_SEQUENCE }; static const struct command_response_s v34_fax_send_test_seq[] = @@ -214,7 +219,8 @@ static const struct command_response_s v34_fax_send_test_seq[] = EXCHANGE("\x10\x03", "\xFF\x13\x8C\xA2\xF1\x10\x03"), // EXCHANGE("\xFF\x13\xFB\x10\x03\x10\x04", "\r\nOK\r\n"), - EXCHANGE("ATH\r", "\r\nOK\r\n") + EXCHANGE("ATH\r", "\r\nOK\r\n"), + END_OF_SEQUENCE }; static const struct command_response_s v34_fax_receive_test_seq[] = @@ -227,7 +233,8 @@ static const struct command_response_s v34_fax_receive_test_seq[] = EXCHANGE("ATA\r", "\r\n+A8M:8185D490\r\nOK\r\n"), EXCHANGE("AT+A8M=8185D490;O\r", "\r\n+A8J:1\r\n+F34:10,1\r\nCONNECT\r\n"), RESPONSE("\x10\x10\x10"), - EXCHANGE("ATH\r", "\r\nOK\r\n") + EXCHANGE("ATH\r", "\r\nOK\r\n"), + END_OF_SEQUENCE }; static const struct command_response_s v34_fax_receive_a_test_seq[] = @@ -242,7 +249,8 @@ static const struct command_response_s v34_fax_receive_a_test_seq[] = EXCHANGE("AT+A8E=,2,\r", "\r\n+A8M:8185D490\r\nOK\r\n"), EXCHANGE("AT+A8M=8185D490\r", "\r\n+A8J:1\r\n+F34:10,1\r\nCONNECT\r\n"), RESPONSE("\x10\x10\x10"), - EXCHANGE("ATH\r", "\r\nOK\r\n") + EXCHANGE("ATH\r", "\r\nOK\r\n"), + END_OF_SEQUENCE }; static const struct command_response_s v34_fax_receive_b_test_seq[] = @@ -255,7 +263,8 @@ static const struct command_response_s v34_fax_receive_b_test_seq[] = EXCHANGE("ATA\r", "\r\nA8I:81\r\n"), RESPONSE("A8I:81\r\n"), EXCHANGE("X", "\r\nOK\r\n"), - EXCHANGE("AT+A8E=,2,\r", "\r\n+A8M:8185D490\r\nOK\r\n") + EXCHANGE("AT+A8E=,2,\r", "\r\n+A8M:8185D490\r\nOK\r\n"), + END_OF_SEQUENCE }; char *decode_test_file = NULL; @@ -267,6 +276,7 @@ int answered = FALSE; int kick = FALSE; int dled = FALSE; int done = FALSE; +int sequence_terminated = FALSE; static const struct command_response_s *fax_test_seq; @@ -295,7 +305,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result) i = (int) (intptr_t) user_data; snprintf(tag, sizeof(tag), "%c: Phase D", i); printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); + fax_log_page_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); return T30_ERR_OK; @@ -310,7 +320,7 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) i = (intptr_t) user_data; snprintf(tag, sizeof(tag), "%c: Phase E", i); printf("Phase E handler on channel %c\n", i); - fax_log_transfer_statistics(s, tag); + fax_log_final_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); //exit(0); @@ -381,6 +391,8 @@ static int at_tx_handler(at_state_t *s, void *user_data, const uint8_t *buf, siz response_buf_ptr = 0; response_buf[response_buf_ptr] = '\0'; test_seq_ptr++; + if (fax_test_seq[test_seq_ptr].command == NULL && fax_test_seq[test_seq_ptr].command == NULL) + sequence_terminated = TRUE; if (fax_test_seq[test_seq_ptr].command) kick = TRUE; break; @@ -418,6 +430,8 @@ static int at_tx_handler(at_state_t *s, void *user_data, const uint8_t *buf, siz { printf("\nMatched\n"); test_seq_ptr++; + if (fax_test_seq[test_seq_ptr].command == NULL && fax_test_seq[test_seq_ptr].command == NULL) + sequence_terminated = TRUE; response_buf_ptr = 0; response_buf[response_buf_ptr] = '\0'; if (fax_test_seq[test_seq_ptr].command) @@ -431,11 +445,9 @@ static int at_tx_handler(at_state_t *s, void *user_data, const uint8_t *buf, siz static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) { - t31_state_t *t; int i; - /* This routine queues messages between two instances of T.38 processing */ - t = (t31_state_t *) user_data; + /* This routine queues messages between two instances of T.38 processing, from the T.38 terminal side. */ span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); for (i = 0; i < count; i++) @@ -449,11 +461,9 @@ static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uin static int t31_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) { - //t38_terminal_state_t *t; int i; - /* This routine queues messages between two instances of T.38 processing */ - //t = (t38_terminal_state_t *) user_data; + /* This routine queues messages between two instances of T.38 processing, from the T.31 modem side. */ span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); for (i = 0; i < count; i++) @@ -465,15 +475,18 @@ static int t31_tx_packet_handler(t38_core_state_t *s, void *user_data, const uin } /*- End of function --------------------------------------------------------*/ -static int t38_tests(int use_gui, int test_sending, int model_no, int speed_pattern_no) +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) { t38_terminal_state_t *t38_state; + fax_state_t *fax_state; int fast_send; int fast_send_tcf; int fast_blocks; uint8_t fast_buf[1000]; - int msg_len; uint8_t msg[1024]; + int msg_len; + int t30_len; + int t31_len; int t38_version; int without_pacing; int use_tep; @@ -484,259 +497,21 @@ static int t38_tests(int use_gui, int test_sending, int model_no, int speed_patt t38_core_state_t *t38_core; logging_state_t *logging; int i; - - t38_version = 1; - without_pacing = FALSE; - use_tep = FALSE; - - srand48(0x1234567); - if ((path_a_to_b = g1050_init(model_no, speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - if ((path_b_to_a = g1050_init(model_no, speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - if ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, t31_tx_packet_handler, NULL)) == NULL) - { - fprintf(stderr, " Cannot start the T.31 T.38 modem\n"); - exit(2); - } - logging = t31_get_logging_state(t31_state); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.31"); - - t38_core = t31_get_t38_core_state(t31_state); - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.31"); - - span_log_set_level(&t31_state->at_state.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(&t31_state->at_state.logging, "T.31"); - - t31_set_mode(t31_state, TRUE); - t38_set_t38_version(t38_core, t38_version); - - if (test_sending) - { - if ((t38_state = t38_terminal_init(NULL, FALSE, t38_tx_packet_handler, t31_state)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t30 = t38_terminal_get_t30_state(t38_state); - t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1); - fax_test_seq = fax_send_test_seq; - countdown = 0; - } - else - { - if ((t38_state = t38_terminal_init(NULL, TRUE, t38_tx_packet_handler, t31_state)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t30 = t38_terminal_get_t30_state(t38_state); - t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1); - fax_test_seq = fax_receive_test_seq; - countdown = 250; - } - - t30 = t38_terminal_get_t30_state(t38_state); - t38_core = t38_terminal_get_t38_core_state(t38_state); - t38_set_t38_version(t38_core, t38_version); - t38_terminal_set_config(t38_state, without_pacing); - t38_terminal_set_tep_mode(t38_state, use_tep); - - t30_set_tx_ident(t30, "11111111"); - t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17); - //t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) 'A'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) 'A'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) 'A'); - - logging = t38_terminal_get_logging_state(t38_state); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38"); - - t38_core = t38_terminal_get_t38_core_state(t38_state); - span_log_set_level(&t38_core->logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(&t38_core->logging, "T.38"); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38"); - - fast_send = FALSE; - fast_send_tcf = TRUE; - fast_blocks = 0; - kick = TRUE; -#if defined(ENABLE_GUI) - if (use_gui) - start_media_monitor(); -#endif - while (!done) - { - logging = t38_terminal_get_logging_state(t38_state); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_terminal_get_t38_core_state(t38_state); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = t38_terminal_get_t30_state(t38_state); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - - logging = t31_get_logging_state(t31_state); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t31_get_t38_core_state(t31_state); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - span_log_bump_samples(&t31_state->at_state.logging, SAMPLES_PER_CHUNK); - - t38_terminal_send_timeout(t38_state, SAMPLES_PER_CHUNK); - t31_t38_send_timeout(t31_state, SAMPLES_PER_CHUNK); - - when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; - - if (kick) - { - kick = FALSE; - if (fax_test_seq[test_seq_ptr].command > (const char *) 2) - { - if (fax_test_seq[test_seq_ptr].command[0]) - { - printf("%s\n", fax_test_seq[test_seq_ptr].command); - t31_at_rx(t31_state, fax_test_seq[test_seq_ptr].command, fax_test_seq[test_seq_ptr].len_command); - } - } - else - { - if (fax_test_seq[test_seq_ptr].command == (const char *) 2) - { - printf("Fast send TCF\n"); - fast_send = TRUE; - fast_send_tcf = TRUE; - fast_blocks = 100; - } - else - { - printf("Fast send image\n"); - fast_send = TRUE; - fast_send_tcf = FALSE; - fast_blocks = 100; - } - } - } - if (fast_send) - { - /* Send fast modem data */ - if (fast_send_tcf) - { - memset(fast_buf, 0, 36); - } - else - { - if (fast_blocks == 1) - { - /* Create the end of page condition */ - for (i = 0; i < 36; i += 2) - { - fast_buf[i] = 0x00; - fast_buf[i + 1] = 0x80; - } - } - else - { - /* Create a chunk of white page */ - for (i = 0; i < 36; i += 4) - { - fast_buf[i] = 0x00; - fast_buf[i + 1] = 0x80; - fast_buf[i + 2] = 0xB2; - fast_buf[i + 3] = 0x01; - } - } - } - if (fast_blocks == 1) - { - /* Insert EOLs */ - fast_buf[35] = ETX; - fast_buf[34] = DLE; - fast_buf[31] = - fast_buf[28] = - fast_buf[25] = - fast_buf[22] = - fast_buf[19] = - fast_buf[16] = 1; - } - t31_at_rx(t31_state, (char *) fast_buf, 36); - if (--fast_blocks == 0) - fast_send = FALSE; - } - if (countdown) - { - if (answered) - { - countdown = 0; - t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED); - } - else if (--countdown == 0) - { - t31_call_event(t31_state, AT_CALL_EVENT_ALERTING); - countdown = 250; - } - } - while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t31_get_t38_core_state(t31_state); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_terminal_get_t38_core_state(t38_state); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_update_display(); -#endif - } - t38_terminal_release(t38_state); - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static int t30_tests(int log_audio, int test_sending) -{ int k; int outframes; - fax_state_t *fax_state; int16_t t30_amp[SAMPLES_PER_CHUNK]; int16_t t31_amp[SAMPLES_PER_CHUNK]; int16_t silence[SAMPLES_PER_CHUNK]; int16_t out_amp[2*SAMPLES_PER_CHUNK]; - int t30_len; - int t31_len; SNDFILE *wave_handle; SNDFILE *in_handle; - int fast_send; - int fast_send_tcf; - int fast_blocks; - uint8_t fast_buf[1000]; - t30_state_t *t30; - logging_state_t *logging; - int i; + + /* Test the T.31 modem against the full FAX machine in spandsp */ + + /* Set up the test environment */ + t38_version = 1; + without_pacing = FALSE; + use_tep = FALSE; wave_handle = NULL; if (log_audio) @@ -748,8 +523,6 @@ static int t30_tests(int log_audio, int test_sending) } } - memset(silence, 0, sizeof(silence)); - in_handle = NULL; if (decode_test_file) { @@ -760,55 +533,155 @@ static int t30_tests(int log_audio, int test_sending) } } - if ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, NULL, NULL)) == NULL) + srand48(0x1234567); + if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) { - fprintf(stderr, " Cannot start the T.31 FAX modem\n"); + fprintf(stderr, "Failed to start IP network path model\n"); + exit(2); + } + if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) + { + fprintf(stderr, "Failed to start IP network path model\n"); exit(2); } - logging = t31_get_logging_state(t31_state); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.31"); + t38_state = NULL; + fax_state = NULL; if (test_sending) { - fax_state = fax_init(NULL, FALSE); - t30 = fax_get_t30_state(fax_state); + if (t38_mode) + { + if ((t38_state = t38_terminal_init(NULL, FALSE, t38_tx_packet_handler, t31_state)) == NULL) + { + fprintf(stderr, "Cannot start the T.38 channel\n"); + exit(2); + } + t30 = t38_terminal_get_t30_state(t38_state); + } + else + { + fax_state = fax_init(NULL, FALSE); + t30 = fax_get_t30_state(fax_state); + } t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1); fax_test_seq = fax_send_test_seq; countdown = 0; } else { - fax_state = fax_init(NULL, TRUE); - t30 = fax_get_t30_state(fax_state); + if (t38_mode) + { + if ((t38_state = t38_terminal_init(NULL, TRUE, t38_tx_packet_handler, t31_state)) == NULL) + { + fprintf(stderr, "Cannot start the T.38 channel\n"); + exit(2); + } + t30 = t38_terminal_get_t30_state(t38_state); + } + else + { + fax_state = fax_init(NULL, TRUE); + t30 = fax_get_t30_state(fax_state); + } t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1); fax_test_seq = fax_receive_test_seq; countdown = 250; } - + + if (t38_mode) + { + t38_core = t38_terminal_get_t38_core_state(t38_state); + t38_set_t38_version(t38_core, t38_version); + t38_terminal_set_config(t38_state, without_pacing); + t38_terminal_set_tep_mode(t38_state, use_tep); + } + t30_set_tx_ident(t30, "11111111"); t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17); + //t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); t30_set_phase_b_handler(t30, phase_b_handler, (void *) 'A'); t30_set_phase_d_handler(t30, phase_d_handler, (void *) 'A'); t30_set_phase_e_handler(t30, phase_e_handler, (void *) 'A'); - memset(t30_amp, 0, sizeof(t30_amp)); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX"); - logging = fax_get_logging_state(fax_state); + if (t38_mode) + logging = t38_terminal_get_logging_state(t38_state); + else + logging = t30_get_logging_state(t30); span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX"); + span_log_set_tag(logging, (t38_mode) ? "T.38" : "FAX"); + + if (t38_mode) + { + t38_core = t38_terminal_get_t38_core_state(t38_state); + span_log_set_level(&t38_core->logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(&t38_core->logging, "T.38"); + + logging = t30_get_logging_state(t30); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, "T.38"); + } + else + { + logging = fax_get_logging_state(fax_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, "FAX"); + } + + memset(silence, 0, sizeof(silence)); + memset(t30_amp, 0, sizeof(t30_amp)); + + /* Now set up and run the T.31 modem */ + if ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, t31_tx_packet_handler, NULL)) == NULL) + { + fprintf(stderr, " Cannot start the T.31 modem\n"); + exit(2); + } + logging = t31_get_logging_state(t31_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, "T.31"); + + if (t38_mode) + { + t38_core = t31_get_t38_core_state(t31_state); + logging = t38_core_get_logging_state(t38_core); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, "T.31"); + + span_log_set_level(&t31_state->at_state.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(&t31_state->at_state.logging, "T.31"); + + t31_set_mode(t31_state, TRUE); + t38_set_t38_version(t38_core, t38_version); + } fast_send = FALSE; fast_send_tcf = TRUE; fast_blocks = 0; kick = TRUE; +#if defined(ENABLE_GUI) + if (use_gui) + start_media_monitor(); +#endif while (!done) { + if (countdown) + { + /* Deal with call setup, through the AT interface. */ + if (answered) + { + countdown = 0; + t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED); + } + else if (--countdown == 0) + { + t31_call_event(t31_state, AT_CALL_EVENT_ALERTING); + countdown = 250; + } + } + if (kick) { + /* Work through the script */ kick = FALSE; if (fax_test_seq[test_seq_ptr].command > (const char *) 2) { @@ -841,22 +714,22 @@ static int t30_tests(int log_audio, int test_sending) /* Send fast modem data */ if (fast_send_tcf) { + /* If we are sending TCF, its simply zeros */ memset(fast_buf, 0, 36); + if (fast_blocks == 1) + { + /* Tell the modem this is the end of the TCF data */ + fast_buf[34] = DLE; + fast_buf[35] = ETX; + } } else { - if (fast_blocks == 1) + /* If we are sending image data, we need to make it look like genuine image data, + with proper EOL and RTC markers. */ + if (fast_blocks > 1) { - /* Create the end of page condition */ - for (i = 0; i < 36; i += 2) - { - fast_buf[i] = 0x00; - fast_buf[i + 1] = 0x80; - } - } - else - { - /* Create a chunk of white page */ + /* Create a chunk of white page, 1728 pixels wide. */ for (i = 0; i < 36; i += 4) { fast_buf[i] = 0x00; @@ -865,81 +738,116 @@ static int t30_tests(int log_audio, int test_sending) fast_buf[i + 3] = 0x01; } } - } - if (fast_blocks == 1) - { - /* Insert EOLs */ - fast_buf[35] = ETX; - fast_buf[34] = DLE; - fast_buf[31] = - fast_buf[28] = - fast_buf[25] = - fast_buf[22] = - fast_buf[19] = - fast_buf[16] = 1; + else + { + /* Create the end of page condition. */ + for (i = 0; i < 36; i += 3) + { + fast_buf[i] = 0x00; + fast_buf[i + 1] = 0x08; + fast_buf[i + 2] = 0x80; + } + /* Tell the modem this is the end of the image data. */ + fast_buf[34] = DLE; + fast_buf[35] = ETX; + } } t31_at_rx(t31_state, (char *) fast_buf, 36); if (--fast_blocks == 0) fast_send = FALSE; } - t30_len = fax_tx(fax_state, t30_amp, SAMPLES_PER_CHUNK); - /* The receive side always expects a full block of samples, but the - transmit side may not be sending any when it doesn't need to. We - may need to pad with some silence. */ - if (t30_len < SAMPLES_PER_CHUNK) + + if (t38_mode) { - memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len)); - t30_len = SAMPLES_PER_CHUNK; - } - if (log_audio) - { - for (k = 0; k < t30_len; k++) - out_amp[2*k] = t30_amp[k]; - } - if (t31_rx(t31_state, t30_amp, t30_len)) - break; - if (countdown) - { - if (answered) + while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) { - countdown = 0; - t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED); +#if defined(ENABLE_GUI) + if (use_gui) + media_monitor_rx(seq_no, tx_when, rx_when); +#endif + t38_core = t31_get_t38_core_state(t31_state); + t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); } - else if (--countdown == 0) + while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) { - t31_call_event(t31_state, AT_CALL_EVENT_ALERTING); - countdown = 250; +#if defined(ENABLE_GUI) + if (use_gui) + media_monitor_rx(seq_no, tx_when, rx_when); +#endif + t38_core = t38_terminal_get_t38_core_state(t38_state); + t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); } - } +#if defined(ENABLE_GUI) + if (use_gui) + media_monitor_update_display(); +#endif + /* Bump the G.1050 models along */ + when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; - t31_len = t31_tx(t31_state, t31_amp, SAMPLES_PER_CHUNK); - if (t31_len < SAMPLES_PER_CHUNK) - { - memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len)); - t31_len = SAMPLES_PER_CHUNK; - } - if (log_audio) - { - for (k = 0; k < t31_len; k++) - out_amp[2*k + 1] = t31_amp[k]; - } - if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK)) - break; + /* Bump things along on the t38_terminal side */ + span_log_bump_samples(t38_terminal_get_logging_state(t38_state), SAMPLES_PER_CHUNK); + t38_core = t38_terminal_get_t38_core_state(t38_state); + span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK); - logging = fax_get_logging_state(fax_state); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t31_get_logging_state(t31_state); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - - if (log_audio) + t38_terminal_send_timeout(t38_state, SAMPLES_PER_CHUNK); + t31_t38_send_timeout(t31_state, SAMPLES_PER_CHUNK); + } + else { - outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK); - if (outframes != SAMPLES_PER_CHUNK) + t30_len = fax_tx(fax_state, t30_amp, SAMPLES_PER_CHUNK); + /* The receive side always expects a full block of samples, but the + transmit side may not be sending any when it doesn't need to. We + may need to pad with some silence. */ + if (t30_len < SAMPLES_PER_CHUNK) + { + memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len)); + t30_len = SAMPLES_PER_CHUNK; + } + if (log_audio) + { + for (k = 0; k < t30_len; k++) + out_amp[2*k] = t30_amp[k]; + } + if (t31_rx(t31_state, t30_amp, t30_len)) break; + t31_len = t31_tx(t31_state, t31_amp, SAMPLES_PER_CHUNK); + if (t31_len < SAMPLES_PER_CHUNK) + { + memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len)); + t31_len = SAMPLES_PER_CHUNK; + } + if (log_audio) + { + for (k = 0; k < t31_len; k++) + out_amp[2*k + 1] = t31_amp[k]; + } + if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK)) + break; + + if (log_audio) + { + outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK); + if (outframes != SAMPLES_PER_CHUNK) + break; + } + + /* Bump things along on the FAX machine side */ + span_log_bump_samples(fax_get_logging_state(fax_state), SAMPLES_PER_CHUNK); } + + /* Bump things along on the FAX machine side */ + span_log_bump_samples(t30_get_logging_state(t30), SAMPLES_PER_CHUNK); + + /* Bump things along on the T.31 modem side */ + t38_core = t31_get_t38_core_state(t31_state); + span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK); + span_log_bump_samples(t31_get_logging_state(t31_state), SAMPLES_PER_CHUNK); + span_log_bump_samples(&t31_state->at_state.logging, SAMPLES_PER_CHUNK); } + + if (t38_mode) + t38_terminal_release(t38_state); + if (decode_test_file) { if (sf_close_telephony(in_handle)) @@ -956,6 +864,13 @@ static int t30_tests(int log_audio, int test_sending) exit(2); } } + + if (!done || !sequence_terminated) + { + printf("Tests failed\n"); + return 2; + } + return 0; } /*- End of function --------------------------------------------------------*/ @@ -966,6 +881,8 @@ int main(int argc, char *argv[]) int t38_mode; int test_sending; int use_gui; + int g1050_model_no; + int g1050_speed_pattern_no; int opt; decode_test_file = NULL; @@ -973,7 +890,9 @@ int main(int argc, char *argv[]) test_sending = FALSE; t38_mode = FALSE; use_gui = FALSE; - while ((opt = getopt(argc, argv, "d:glrst")) != -1) + g1050_model_no = 0; + g1050_speed_pattern_no = 1; + while ((opt = getopt(argc, argv, "d:glM:rS:st")) != -1) { switch (opt) { @@ -991,9 +910,15 @@ int main(int argc, char *argv[]) case 'l': log_audio = TRUE; break; + case 'M': + g1050_model_no = optarg[0] - 'A' + 1; + break; case 'r': test_sending = FALSE; break; + case 'S': + g1050_speed_pattern_no = atoi(optarg); + break; case 's': test_sending = TRUE; break; @@ -1007,14 +932,8 @@ int main(int argc, char *argv[]) } } - if (t38_mode) - t38_tests(use_gui, test_sending, 0, 1); - else - t30_tests(log_audio, test_sending); - if (done) - { - printf("Tests passed\n"); - } + t30_tests(t38_mode, use_gui, log_audio, test_sending, g1050_model_no, g1050_speed_pattern_no); + printf("Tests passed\n"); return 0; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/tests/t35_tests.c b/libs/spandsp/tests/t35_tests.c new file mode 100644 index 0000000000..d5edaf4f50 --- /dev/null +++ b/libs/spandsp/tests/t35_tests.c @@ -0,0 +1,117 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * t35_tests.c - Tests for T.35. + * + * Written by Steve Underwood + * + * Copyright (C) 2012 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \file */ + +/*! \page t35_tests_page T.35 tests +\section t35_tests_page_sec_1 What does it do? +*/ + +/* Enable the following definition to enable direct probing into the structures */ +//#define WITH_SPANDSP_INTERNALS + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +//#if defined(WITH_SPANDSP_INTERNALS) +#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES +//#endif + +#include "spandsp.h" + +int main(int argc, char *argv[]) +{ + int i; + int j; + uint8_t msg[50]; + const char *vendor; + const char *country; + const char *model; + const char *real_country; + int first_hit; + + printf("Sweep through all the possible countries\n"); + for (i = 0; i < 256; i++) + { + country = t35_country_code_to_str(i, 0); + real_country = t35_real_country_code_to_str(i, 0); + if (country || real_country) + { + printf("%3d '%s' %d '%s'\n", + i, + (country) ? country : "???", + t35_real_country_code(i, 0), + (real_country) ? real_country : "???"); + } + } + + printf("\nSweep through all the possible vendors within each country\n"); + for (i = 0; i < 256; i++) + { + msg[0] = i; + msg[1] = '\x00'; + msg[2] = '\x00'; + first_hit = TRUE; + for (j = 0; j < 65536; j++) + { + msg[1] = (j >> 8) & 0xFF; + msg[2] = j & 0xFF; + if ((vendor = t35_vendor_to_str(msg, 3))) + { + if (first_hit) + { + if ((real_country = t35_real_country_code_to_str(i, 0))) + printf("%s\n", real_country); + else + printf("???\n"); + first_hit = FALSE; + } + printf(" 0x%02x 0x%02x 0x%02x '%s'\n", msg[0], msg[1], msg[2], vendor); + } + } + } + + printf("\nTry a decode of a full NSF string\n"); + t35_decode((uint8_t *) "\x00\x00\x0E\x00\x00\x00\x96\x0F\x01\x02\x00\x10\x05\x02\x95\xC8\x08\x01\x49\x02\x41\x53\x54\x47", + 13, + &country, + &vendor, + &model); + printf("Decoded as %s %s %s\n", (country) ? country : "???", (vendor) ? vendor : "???", (model) ? model : "???"); + + printf("Tests passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/tests/t38_core_tests.c b/libs/spandsp/tests/t38_core_tests.c index a07d6b561d..c986d90c5d 100644 --- a/libs/spandsp/tests/t38_core_tests.c +++ b/libs/spandsp/tests/t38_core_tests.c @@ -40,6 +40,9 @@ These tests exercise the T.38 core ASN.1 processing code. #include #include #include +#if !defined(_WIN32) +#include +#endif //#if defined(WITH_SPANDSP_INTERNALS) #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES @@ -50,21 +53,46 @@ These tests exercise the T.38 core ASN.1 processing code. #define MAX_FIELDS 42 #define MAX_FIELD_LEN 8192 -int t38_version; -int succeeded = TRUE; -int ok_indicator_packets; -int bad_indicator_packets; -int ok_data_packets; -int bad_data_packets; -int missing_packets; +static int t38_version; +static int succeeded = TRUE; +static int ok_indicator_packets; +static int bad_indicator_packets; +static int ok_data_packets; +static int bad_data_packets; +static int missing_packets; -int current_indicator; -int current_data_type; -int current_field_type; -int skip; +static int skip; -uint8_t field_body[MAX_FIELDS][MAX_FIELD_LEN]; -int field_len[MAX_FIELDS]; +static uint8_t field_body[MAX_FIELDS][MAX_FIELD_LEN]; +static int field_len[MAX_FIELDS]; +static int seq_no; + +static int msg_list[1000000]; +static int msg_list_ptr; +static int msg_list_ptr2; +static uint8_t concat[1000000]; +static int concat_len; + +static int rx_missing_attack_handler(t38_core_state_t *s, void *user_data, int rx_seq_no, int expected_seq_no) +{ + //printf("Hit missing\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int rx_indicator_attack_handler(t38_core_state_t *s, void *user_data, int indicator) +{ + //printf("Hit indicator %d\n", indicator); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int rx_data_attack_handler(t38_core_state_t *s, void *user_data, int data_type, int field_type, const uint8_t *buf, int len) +{ + //printf("Hit data %d, field %d\n", data_type, field_type); + return 0; +} +/*- End of function --------------------------------------------------------*/ static int rx_missing_handler(t38_core_state_t *s, void *user_data, int rx_seq_no, int expected_seq_no) { @@ -76,7 +104,7 @@ static int rx_missing_handler(t38_core_state_t *s, void *user_data, int rx_seq_n static int rx_indicator_handler(t38_core_state_t *s, void *user_data, int indicator) { - if (indicator == current_indicator) + if (indicator == msg_list[msg_list_ptr2++]) ok_indicator_packets++; else bad_indicator_packets++; @@ -87,20 +115,11 @@ static int rx_indicator_handler(t38_core_state_t *s, void *user_data, int indica static int rx_data_handler(t38_core_state_t *s, void *user_data, int data_type, int field_type, const uint8_t *buf, int len) { - if (--skip >= 0) - { - if (data_type == current_data_type && field_type == current_field_type) - ok_data_packets++; - else - bad_data_packets++; - } + if (data_type == msg_list[msg_list_ptr2] && field_type == msg_list[msg_list_ptr2 + 1]) + ok_data_packets++; else - { - if (data_type == current_data_type && field_type == T38_FIELD_T4_NON_ECM_SIG_END) - ok_data_packets++; - else - bad_data_packets++; - } + bad_data_packets++; + msg_list_ptr2 += 2; //printf("Hit data %d, field %d\n", data_type, field_type); return 0; } @@ -109,7 +128,6 @@ static int rx_data_handler(t38_core_state_t *s, void *user_data, int data_type, static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) { t38_core_state_t *t; - static int seq_no = 0; t = (t38_core_state_t *) user_data; span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); @@ -120,6 +138,16 @@ static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t } /*- End of function --------------------------------------------------------*/ +static int tx_concat_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) +{ + span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); + memcpy(&concat[concat_len], buf, len); + concat_len += len; + seq_no++; + return 0; +} +/*- End of function --------------------------------------------------------*/ + static int encode_decode_tests(t38_core_state_t *a, t38_core_state_t *b) { t38_data_field_t field[MAX_FIELDS]; @@ -132,12 +160,18 @@ static int encode_decode_tests(t38_core_state_t *a, t38_core_state_t *b) bad_data_packets = 0; missing_packets = 0; + msg_list_ptr = 0; + msg_list_ptr2 = 0; + /* Try all the indicator types */ for (i = 0; i < 100; i++) { - current_indicator = i; + msg_list[msg_list_ptr++] = i; if (t38_core_send_indicator(a, i) < 0) + { + msg_list_ptr--; break; + } } /* Try all the data types, as single field messages with no data */ @@ -145,11 +179,14 @@ static int encode_decode_tests(t38_core_state_t *a, t38_core_state_t *b) { for (j = 0; j < 100; j++) { - current_data_type = i; - current_field_type = j; + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = j; skip = 99; if (t38_core_send_data(a, i, j, (uint8_t *) "", 0, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) + { + msg_list_ptr -= 2; break; + } } if (j == 0) break; @@ -160,10 +197,26 @@ static int encode_decode_tests(t38_core_state_t *a, t38_core_state_t *b) { for (j = 0; j < 100; j++) { - current_data_type = i; - current_field_type = j; + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = j; skip = 99; if (t38_core_send_data(a, i, j, (uint8_t *) "ABCD", 4, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) + { + msg_list_ptr -= 2; + break; + } + } + if (j == 0) + break; + } + + /* Try all the data types and field types, as multi-field messages, but with 0 fields */ + for (i = 0; i < 100; i++) + { + for (j = 0; j < 100; j++) + { + skip = 1; + if (t38_core_send_data_multi_field(a, i, field, 0, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) break; } if (j == 0) @@ -175,8 +228,10 @@ static int encode_decode_tests(t38_core_state_t *a, t38_core_state_t *b) { for (j = 0; j < 100; j++) { - current_data_type = i; - current_field_type = j; + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = j; + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = T38_FIELD_T4_NON_ECM_SIG_END; skip = 1; field_len[0] = 444; @@ -189,14 +244,19 @@ static int encode_decode_tests(t38_core_state_t *a, t38_core_state_t *b) field[1].field = field_body[1]; field[1].field_len = field_len[1]; if (t38_core_send_data_multi_field(a, i, field, 2, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) + { + msg_list_ptr -= 4; break; + } } if (j == 0) break; } + printf("Indicator packets: OK = %d, bad = %d\n", ok_indicator_packets, bad_indicator_packets); printf("Data packets: OK = %d, bad = %d\n", ok_data_packets, bad_data_packets); printf("Missing packets = %d\n", missing_packets); + if (t38_version == 0) { if (ok_indicator_packets != 16 || bad_indicator_packets != 0) @@ -232,8 +292,182 @@ static int encode_decode_tests(t38_core_state_t *a, t38_core_state_t *b) } /*- End of function --------------------------------------------------------*/ -static int attack_tests(t38_core_state_t *s) +static int encode_then_decode_tests(t38_core_state_t *a, t38_core_state_t *b) { + t38_data_field_t field[MAX_FIELDS]; + int len; + int i; + int j; + + ok_indicator_packets = 0; + bad_indicator_packets = 0; + ok_data_packets = 0; + bad_data_packets = 0; + missing_packets = 0; + + msg_list_ptr = 0; + msg_list_ptr2 = 0; + + /* Try all the indicator types */ + for (i = 0; i < 100; i++) + { + msg_list[msg_list_ptr++] = i; + if (t38_core_send_indicator(a, i) < 0) + { + msg_list_ptr--; + break; + } + } + + /* Try all the data types, as single field messages with no data */ + for (i = 0; i < 100; i++) + { + for (j = 0; j < 100; j++) + { + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = j; + skip = 99; + if (t38_core_send_data(a, i, j, (uint8_t *) "", 0, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) + { + msg_list_ptr -= 2; + break; + } + } + if (j == 0) + break; + } + + /* Try all the data types and field types, as single field messages with data */ + for (i = 0; i < 100; i++) + { + for (j = 0; j < 100; j++) + { + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = j; + skip = 99; + if (t38_core_send_data(a, i, j, (uint8_t *) "ABCD", 4, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) + { + msg_list_ptr -= 2; + break; + } + } + if (j == 0) + break; + } + + /* Try all the data types and field types, as multi-field messages, but with 0 fields */ + for (i = 0; i < 100; i++) + { + for (j = 0; j < 100; j++) + { + skip = 1; + if (t38_core_send_data_multi_field(a, i, field, 0, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) + break; + } + if (j == 0) + break; + } + + /* Try all the data types and field types, as multi-field messages */ + for (i = 0; i < 100; i++) + { + for (j = 0; j < 100; j++) + { + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = j; + msg_list[msg_list_ptr++] = i; + msg_list[msg_list_ptr++] = T38_FIELD_T4_NON_ECM_SIG_END; + skip = 1; + + field_len[0] = 444; + field_len[1] = 333; + + field[0].field_type = j; + field[0].field = field_body[0]; + field[0].field_len = field_len[0]; + field[1].field_type = T38_FIELD_T4_NON_ECM_SIG_END; + field[1].field = field_body[1]; + field[1].field_len = field_len[1]; + if (t38_core_send_data_multi_field(a, i, field, 2, T38_PACKET_CATEGORY_CONTROL_DATA) < 0) + { + msg_list_ptr -= 4; + break; + } + } + if (j == 0) + break; + } + + /* Now split up the big concatented block of IFP packets. */ + for (i = 0, seq_no = 0; i < concat_len; i += len) + { + if ((len = t38_core_rx_ifp_stream(b, &concat[i], concat_len - i, seq_no)) < 0) + succeeded = FALSE; + seq_no++; + } + + printf("Indicator packets: OK = %d, bad = %d\n", ok_indicator_packets, bad_indicator_packets); + printf("Data packets: OK = %d, bad = %d\n", ok_data_packets, bad_data_packets); + printf("Missing packets = %d\n", missing_packets); + + if (t38_version == 0) + { + if (ok_indicator_packets != 16 || bad_indicator_packets != 0) + { + printf("Tests failed\n"); + return -1; + } + if (ok_data_packets != 288 || bad_data_packets != 0) + { + printf("Tests failed\n"); + return -1; + } + } + else + { + if (ok_indicator_packets != 23 || bad_indicator_packets != 0) + { + printf("Tests failed\n"); + return -1; + } + if (ok_data_packets != 720 || bad_data_packets != 0) + { + printf("Tests failed\n"); + return -1; + } + } + if (missing_packets > 0) + { + printf("Tests failed\n"); + return -1; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int attack_tests(t38_core_state_t *s, int packets) +{ + int i; + int j; + int len; + uint8_t buf[1024]; + int seq_no; + + srand(1234567); + /* Send lots of random junk, of increasing length. Much of this will decode + as valid IFP frames, but none of it should cause trouble. */ + seq_no = 0; + for (len = 1; len < 70; len++) + { + for (i = 0; i < packets; i++) + { + for (j = 0; j < len; j++) + buf[j] = (rand() >> 16) & 0xFF; + t38_core_rx_ifp_packet(s, buf, len, seq_no); + seq_no = (seq_no + 1) & 0xFFFF; + } + } + return 0; } /*- End of function --------------------------------------------------------*/ @@ -242,9 +476,29 @@ int main(int argc, char *argv[]) { t38_core_state_t t38_core_a; t38_core_state_t t38_core_b; + int attack_packets; + int opt; + attack_packets = 10000000; + while ((opt = getopt(argc, argv, "a:")) != -1) + { + switch (opt) + { + case 'a': + attack_packets = atoi(optarg); + break; + default: + //usage(); + exit(2); + break; + } + } + + /* Tests in UDP type mode, for UDPTL and RTP */ for (t38_version = 0; t38_version < 2; t38_version++) { + seq_no = 0; + printf("Using T.38 version %d\n", t38_version); if (t38_core_init(&t38_core_a, @@ -278,17 +532,196 @@ int main(int argc, char *argv[]) span_log_set_level(&t38_core_b.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); span_log_set_tag(&t38_core_b.logging, "T.38-B"); + /* Encode and decode all possible frame types, one by one */ if (encode_decode_tests(&t38_core_a, &t38_core_b)) { printf("Encode/decode tests failed\n"); exit(2); } - if (attack_tests(&t38_core_a)) + + if (t38_core_init(&t38_core_a, + rx_indicator_attack_handler, + rx_data_attack_handler, + rx_missing_attack_handler, + &t38_core_b, + tx_packet_handler, + &t38_core_b) == NULL) + { + fprintf(stderr, "Cannot start the T.38 core\n"); + exit(2); + } + + t38_set_t38_version(&t38_core_a, t38_version); + + //span_log_set_level(&t38_core_a.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); + //span_log_set_tag(&t38_core_a.logging, "T.38-A"); + + if (attack_tests(&t38_core_a, attack_packets)) { printf("Attack tests failed\n"); exit(2); } } + + /* Tests in TCP without TPKT mode, like T.38 version 0 */ + for (t38_version = 0; t38_version < 2; t38_version++) + { + seq_no = 0; + concat_len = 0; + + printf("Using T.38 version %d\n", t38_version); + + if (t38_core_init(&t38_core_a, + rx_indicator_handler, + rx_data_handler, + rx_missing_handler, + &t38_core_b, + tx_concat_packet_handler, + &t38_core_b) == NULL) + { + fprintf(stderr, "Cannot start the T.38 core\n"); + exit(2); + } + if (t38_core_init(&t38_core_b, + rx_indicator_handler, + rx_data_handler, + rx_missing_handler, + &t38_core_a, + tx_concat_packet_handler, + &t38_core_a) == NULL) + { + fprintf(stderr, "Cannot start the T.38 core\n"); + exit(2); + } + + t38_set_t38_version(&t38_core_a, t38_version); + t38_set_t38_version(&t38_core_b, t38_version); + + t38_set_pace_transmission(&t38_core_a, FALSE); + t38_set_pace_transmission(&t38_core_b, FALSE); + + t38_set_data_transport_protocol(&t38_core_a, T38_TRANSPORT_TCP); + t38_set_data_transport_protocol(&t38_core_b, T38_TRANSPORT_TCP); + + span_log_set_level(&t38_core_a.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); + span_log_set_tag(&t38_core_a.logging, "T.38-A"); + span_log_set_level(&t38_core_b.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); + span_log_set_tag(&t38_core_b.logging, "T.38-B"); + + /* Encode all possible frames types into a large block, and then decode them */ + if (encode_then_decode_tests(&t38_core_a, &t38_core_b)) + { + printf("Encode then decode tests failed\n"); + exit(2); + } + + if (t38_core_init(&t38_core_a, + rx_indicator_attack_handler, + rx_data_attack_handler, + rx_missing_attack_handler, + &t38_core_b, + tx_packet_handler, + &t38_core_b) == NULL) + { + fprintf(stderr, "Cannot start the T.38 core\n"); + exit(2); + } + + t38_set_t38_version(&t38_core_a, t38_version); + + t38_set_pace_transmission(&t38_core_a, FALSE); + + t38_set_data_transport_protocol(&t38_core_a, T38_TRANSPORT_TCP); + + //span_log_set_level(&t38_core_a.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); + //span_log_set_tag(&t38_core_a.logging, "T.38-A"); + + if (attack_tests(&t38_core_a, attack_packets)) + { + printf("Attack tests failed\n"); + exit(2); + } + } + + /* Tests in TCP with TPKT mode, like T.38 versions >0 */ + for (t38_version = 0; t38_version < 2; t38_version++) + { + seq_no = 0; + concat_len = 0; + + printf("Using T.38 version %d\n", t38_version); + + if (t38_core_init(&t38_core_a, + rx_indicator_handler, + rx_data_handler, + rx_missing_handler, + &t38_core_b, + tx_concat_packet_handler, + &t38_core_b) == NULL) + { + fprintf(stderr, "Cannot start the T.38 core\n"); + exit(2); + } + if (t38_core_init(&t38_core_b, + rx_indicator_handler, + rx_data_handler, + rx_missing_handler, + &t38_core_a, + tx_concat_packet_handler, + &t38_core_a) == NULL) + { + fprintf(stderr, "Cannot start the T.38 core\n"); + exit(2); + } + + t38_set_t38_version(&t38_core_a, t38_version); + t38_set_t38_version(&t38_core_b, t38_version); + + t38_set_pace_transmission(&t38_core_a, FALSE); + t38_set_pace_transmission(&t38_core_b, FALSE); + + t38_set_data_transport_protocol(&t38_core_a, T38_TRANSPORT_TCP_TPKT); + t38_set_data_transport_protocol(&t38_core_b, T38_TRANSPORT_TCP_TPKT); + + span_log_set_level(&t38_core_a.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); + span_log_set_tag(&t38_core_a.logging, "T.38-A"); + span_log_set_level(&t38_core_b.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); + span_log_set_tag(&t38_core_b.logging, "T.38-B"); + + /* Encode all possible frames types into a large block, and then decode them */ + if (encode_then_decode_tests(&t38_core_a, &t38_core_b)) + { + printf("Encode then decode tests failed\n"); + exit(2); + } + + if (t38_core_init(&t38_core_a, + rx_indicator_attack_handler, + rx_data_attack_handler, + rx_missing_attack_handler, + &t38_core_b, + tx_packet_handler, + &t38_core_b) == NULL) + { + fprintf(stderr, "Cannot start the T.38 core\n"); + exit(2); + } + t38_set_t38_version(&t38_core_a, t38_version); + + t38_set_pace_transmission(&t38_core_a, FALSE); + + t38_set_data_transport_protocol(&t38_core_a, T38_TRANSPORT_TCP_TPKT); + + //span_log_set_level(&t38_core_a.logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG); + //span_log_set_tag(&t38_core_a.logging, "T.38-A"); + + if (attack_tests(&t38_core_a, attack_packets)) + { + printf("Attack tests failed\n"); + exit(2); + } + } + if (!succeeded) { printf("Tests failed\n"); diff --git a/libs/spandsp/tests/t38_decode.c b/libs/spandsp/tests/t38_decode.c index f55f7a3bac..50538b1ddc 100644 --- a/libs/spandsp/tests/t38_decode.c +++ b/libs/spandsp/tests/t38_decode.c @@ -98,7 +98,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result) i = (int) (intptr_t) user_data; snprintf(tag, sizeof(tag), "%c: Phase D", i); printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); + fax_log_page_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); return T30_ERR_OK; @@ -114,7 +114,7 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) i = (int) (intptr_t) user_data; snprintf(tag, sizeof(tag), "%c: Phase E", i); printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result)); - fax_log_transfer_statistics(s, tag); + fax_log_final_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); t30_get_transfer_statistics(s, &t); @@ -422,7 +422,8 @@ int main(int argc, char *argv[]) t38_set_t38_version(t38_core, t38_version); t38_terminal_set_config(t38_terminal_state, options); t38_terminal_set_tep_mode(t38_terminal_state, use_tep); - + t38_terminal_set_fill_bit_removal(t38_terminal_state, fill_removal); + logging = t38_terminal_get_logging_state(t38_terminal_state); span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); span_log_set_tag(logging, "T.38"); @@ -445,7 +446,7 @@ int main(int argc, char *argv[]) t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A'); t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A'); t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A'); - t30_set_ecm_capability(t30, TRUE); + t30_set_ecm_capability(t30, use_ecm); t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION | T30_SUPPORT_T85_COMPRESSION); if (pcap_scan_pkts(input_file_name, src_addr, src_port, dest_addr, dest_port, t38_terminal_timing_update, process_packet, NULL)) @@ -474,7 +475,7 @@ int main(int argc, char *argv[]) t38_core = t38_gateway_get_t38_core_state(t38_gateway_state); t38_gateway_set_transmit_on_idle(t38_gateway_state, use_transmit_on_idle); t38_set_t38_version(t38_core, t38_version); - t38_gateway_set_ecm_capability(t38_gateway_state, TRUE); + t38_gateway_set_ecm_capability(t38_gateway_state, use_ecm); logging = t38_gateway_get_logging_state(t38_gateway_state); span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); @@ -502,7 +503,7 @@ int main(int argc, char *argv[]) t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B'); t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B'); t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B'); - t30_set_ecm_capability(t30, TRUE); + t30_set_ecm_capability(t30, use_ecm); t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); logging = fax_get_logging_state(fax_state); diff --git a/libs/spandsp/tests/t38_gateway_tests.c b/libs/spandsp/tests/t38_gateway_tests.c deleted file mode 100644 index c7eed0c1ab..0000000000 --- a/libs/spandsp/tests/t38_gateway_tests.c +++ /dev/null @@ -1,665 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * t38_gateway_tests.c - Tests for the T.38 FoIP gateway module. - * - * Written by Steve Underwood - * - * Copyright (C) 2005, 2006 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*! \file */ - -/*! \page t38_gateway_tests_page T.38 gateway tests -\section t38_gateway_tests_page_sec_1 What does it do? -These tests exercise the path - - FAX machine <-> T.38 gateway <-> T.38 gateway <-> FAX machine -*/ - -/* Enable the following definition to enable direct probing into the FAX structures */ -//#define WITH_SPANDSP_INTERNALS - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -#if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H) && defined(HAVE_FL_FL_AUDIO_METER_H) -#define ENABLE_GUI -#endif - -#include -#include -#include -#include -#include -#include -#include -#if !defined(_WIN32) -#include -#endif - -//#if defined(WITH_SPANDSP_INTERNALS) -#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES -//#endif - -#include "spandsp.h" -#include "spandsp-sim.h" - -#if defined(ENABLE_GUI) -#include "media_monitor.h" -#endif -#include "fax_utils.h" - -#define SAMPLES_PER_CHUNK 160 - -#define INPUT_FILE_NAME "../test-data/itu/fax/itutests.tif" -#define OUTPUT_FILE_NAME "t38.tif" -#define OUTPUT_FILE_NAME_WAVE "t38_gateway.wav" - -fax_state_t *fax_state_a; -t38_gateway_state_t *t38_state_a; -t38_gateway_state_t *t38_state_b; -fax_state_t *fax_state_b; - -g1050_state_t *path_a_to_b; -g1050_state_t *path_b_to_a; - -double when = 0.0; - -int done[2] = {FALSE, FALSE}; -int succeeded[2] = {FALSE, FALSE}; - -int simulate_incrementing_repeats = FALSE; - -static int phase_b_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase B", i); - printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static int phase_d_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase D", i); - printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static void phase_e_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - t30_stats_t t; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase E", i); - printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - t30_get_transfer_statistics(s, &t); - succeeded[i - 'A'] = (result == T30_ERR_OK) && (t.pages_tx == 12 || t.pages_rx == 12); - done[i - 'A'] = TRUE; -} -/*- End of function --------------------------------------------------------*/ - -static void real_time_frame_handler(t38_gateway_state_t *s, - void *user_data, - int direction, - const uint8_t *msg, - int len) -{ - int i; - - i = (intptr_t) user_data; - printf("%d: Real time frame handler on channel %d - %s, %s, length = %d\n", - i, - i, - (direction) ? "PSTN->T.38" : "T.38->PSTN", - t30_frametype(msg[2]), - len); -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_a(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - g1050_put(path_a_to_b, buf, len, subst_seq, when); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - g1050_put(path_a_to_b, buf, len, s->tx_seq_no, when); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_b(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - g1050_put(path_b_to_a, buf, len, subst_seq, when); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - g1050_put(path_b_to_a, buf, len, s->tx_seq_no, when); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -int main(int argc, char *argv[]) -{ - int16_t silence[SAMPLES_PER_CHUNK]; - int16_t t30_amp_a[SAMPLES_PER_CHUNK]; - int16_t t38_amp_a[SAMPLES_PER_CHUNK]; - int16_t t38_amp_hist_a[8][SAMPLES_PER_CHUNK]; - int16_t t38_amp_b[SAMPLES_PER_CHUNK]; - int16_t t38_amp_hist_b[8][SAMPLES_PER_CHUNK]; - int16_t t30_amp_b[SAMPLES_PER_CHUNK]; - int16_t out_amp[SAMPLES_PER_CHUNK*4]; - int t30_len_a; - int t38_len_a; - int t38_len_b; - int t30_len_b; - int hist_ptr; - int log_audio; - int msg_len; - uint8_t msg[1024]; - int outframes; - SNDFILE *wave_handle; - int use_ecm; - int use_tep; - int feedback_audio; - int use_transmit_on_idle; - int t38_version; - const char *input_file_name; - int i; - int seq_no; - int g1050_model_no; - int g1050_speed_pattern_no; - double tx_when; - double rx_when; - int supported_modems; - int fill_removal; - int use_gui; - int opt; - int drop_frame; - int drop_frame_rate; - t38_stats_t stats; - fax_state_t *fax; - t30_state_t *t30; - t38_gateway_state_t *t38; - t38_core_state_t *t38_core; - logging_state_t *logging; - - log_audio = FALSE; - use_ecm = FALSE; - t38_version = 1; - input_file_name = INPUT_FILE_NAME; - simulate_incrementing_repeats = FALSE; - g1050_model_no = 0; - g1050_speed_pattern_no = 1; - fill_removal = FALSE; - use_gui = FALSE; - use_tep = FALSE; - feedback_audio = FALSE; - use_transmit_on_idle = TRUE; - supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17; - drop_frame = 0; - drop_frame_rate = 0; - while ((opt = getopt(argc, argv, "D:efFgi:Ilm:M:s:tv:")) != -1) - { - switch (opt) - { - case 'D': - drop_frame_rate = - drop_frame = atoi(optarg); - break; - case 'e': - use_ecm = TRUE; - break; - case 'f': - feedback_audio = TRUE; - break; - case 'F': - fill_removal = TRUE; - break; - case 'g': -#if defined(ENABLE_GUI) - use_gui = TRUE; -#else - fprintf(stderr, "Graphical monitoring not available\n"); - exit(2); -#endif - break; - case 'i': - input_file_name = optarg; - break; - case 'I': - simulate_incrementing_repeats = TRUE; - break; - case 'l': - log_audio = TRUE; - break; - case 'm': - supported_modems = atoi(optarg); - break; - case 'M': - g1050_model_no = optarg[0] - 'A' + 1; - break; - case 's': - g1050_speed_pattern_no = atoi(optarg); - break; - case 't': - use_tep = TRUE; - break; - case 'v': - t38_version = atoi(optarg); - break; - default: - //usage(); - exit(2); - break; - } - } - - printf("Using T.38 version %d\n", t38_version); - if (use_ecm) - printf("Using ECM\n"); - - wave_handle = NULL; - if (log_audio) - { - if ((wave_handle = sf_open_telephony_write(OUTPUT_FILE_NAME_WAVE, 4)) == NULL) - { - fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); - exit(2); - } - } - memset(silence, 0, sizeof(silence)); - - srand48(0x1234567); - if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - - if ((fax_state_a = fax_init(NULL, TRUE)) == NULL) - { - fprintf(stderr, "Cannot start FAX\n"); - exit(2); - } - fax = fax_state_a; - t30 = fax_get_t30_state(fax); - fax_set_transmit_on_idle(fax, use_transmit_on_idle); - fax_set_tep_mode(fax, use_tep); - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "11111111"); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_tx_file(t30, input_file_name, -1, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); - t30_set_minimum_scan_line_time(t30, 40); - //t30_set_iaf_mode(t30, T30_IAF_MODE_NO_FILL_BITS); - - logging = fax_get_logging_state(fax); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-A "); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-A "); - - memset(t30_amp_a, 0, sizeof(t30_amp_a)); - memset(t38_amp_hist_a, 0, sizeof(t38_amp_hist_a)); - memset(t38_amp_hist_b, 0, sizeof(t38_amp_hist_b)); - - if ((t38_state_a = t38_gateway_init(NULL, tx_packet_handler_a, t38_state_b)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t38 = t38_state_a; - t38_core = t38_gateway_get_t38_core_state(t38); - t38_gateway_set_transmit_on_idle(t38, use_transmit_on_idle); - t38_gateway_set_supported_modems(t38, supported_modems); - //t38_gateway_set_nsx_suppression(t38, NULL, 0, NULL, 0); - t38_gateway_set_fill_bit_removal(t38, fill_removal); - t38_gateway_set_real_time_frame_handler(t38, real_time_frame_handler, NULL); - t38_set_t38_version(t38_core, t38_version); - t38_gateway_set_ecm_capability(t38, use_ecm); - - logging = t38_gateway_get_logging_state(t38); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - memset(t38_amp_a, 0, sizeof(t38_amp_a)); - - if ((t38_state_b = t38_gateway_init(NULL, tx_packet_handler_b, t38_state_a)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t38 = t38_state_b; - t38_core = t38_gateway_get_t38_core_state(t38); - t38_gateway_set_transmit_on_idle(t38, use_transmit_on_idle); - t38_gateway_set_supported_modems(t38, supported_modems); - //t38_gateway_set_nsx_suppression(t38, FALSE); - t38_gateway_set_fill_bit_removal(t38, fill_removal); - t38_set_t38_version(t38_core, t38_version); - t38_gateway_set_ecm_capability(t38, use_ecm); - - logging = t38_gateway_get_logging_state(t38); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - memset(t38_amp_b, 0, sizeof(t38_amp_b)); - - if ((fax_state_b = fax_init(NULL, FALSE)) == NULL) - { - fprintf(stderr, "Cannot start FAX\n"); - exit(2); - } - fax = fax_state_b; - t30 = fax_get_t30_state(fax); - fax_set_transmit_on_idle(fax, use_transmit_on_idle); - fax_set_tep_mode(fax, use_tep); - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "22222222"); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); - t30_set_minimum_scan_line_time(t30, 40); - - logging = fax_get_logging_state(fax); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-B "); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-B "); - - memset(t30_amp_b, 0, sizeof(t30_amp_b)); - -#if defined(ENABLE_GUI) - if (use_gui) - start_media_monitor(); -#endif - hist_ptr = 0; - for (;;) - { - logging = fax_get_logging_state(fax_state_a); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = fax_get_t30_state(fax_state_a); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t38_gateway_get_logging_state(t38_state_a); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t38_gateway_get_logging_state(t38_state_b); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_gateway_get_t38_core_state(t38_state_b); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = fax_get_logging_state(fax_state_b); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = fax_get_t30_state(fax_state_b); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - memset(out_amp, 0, sizeof(out_amp)); - - t30_len_a = fax_tx(fax_state_a, t30_amp_a, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - /* The receive side always expects a full block of samples, but the - transmit side may not be sending any when it doesn't need to. We - may need to pad with some silence. */ - if (t30_len_a < SAMPLES_PER_CHUNK) - { - memset(t30_amp_a + t30_len_a, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len_a)); - t30_len_a = SAMPLES_PER_CHUNK; - } - } - if (log_audio) - { - for (i = 0; i < t30_len_a; i++) - out_amp[i*4] = t30_amp_a[i]; - } - if (feedback_audio) - { - for (i = 0; i < t30_len_a; i++) - t30_amp_a[i] += t38_amp_hist_a[hist_ptr][i] >> 1; - memcpy(t38_amp_hist_a[hist_ptr], t38_amp_a, sizeof(int16_t)*SAMPLES_PER_CHUNK); - } - if (drop_frame_rate && --drop_frame == 0) - { - drop_frame = drop_frame_rate; - if (t38_gateway_rx_fillin(t38_state_a, t30_len_a)) - break; - } - else - { - if (t38_gateway_rx(t38_state_a, t30_amp_a, t30_len_a)) - break; - } - - t38_len_a = t38_gateway_tx(t38_state_a, t38_amp_a, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - if (t38_len_a < SAMPLES_PER_CHUNK) - { - memset(t38_amp_a + t38_len_a, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len_a)); - t38_len_a = SAMPLES_PER_CHUNK; - } - } - if (log_audio) - { - for (i = 0; i < t38_len_a; i++) - out_amp[i*4 + 1] = t38_amp_a[i]; - } - if (fax_rx(fax_state_a, t38_amp_a, SAMPLES_PER_CHUNK)) - break; - - t30_len_b = fax_tx(fax_state_b, t30_amp_b, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - /* The receive side always expects a full block of samples, but the - transmit side may not be sending any when it doesn't need to. We - may need to pad with some silence. */ - if (t30_len_b < SAMPLES_PER_CHUNK) - { - memset(t30_amp_b + t30_len_b, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len_b)); - t30_len_b = SAMPLES_PER_CHUNK; - } - } - if (log_audio) - { - for (i = 0; i < t30_len_b; i++) - out_amp[i*4 + 3] = t30_amp_b[i]; - } - if (feedback_audio) - { - for (i = 0; i < t30_len_b; i++) - t30_amp_b[i] += t38_amp_hist_b[hist_ptr][i] >> 1; - memcpy(t38_amp_hist_b[hist_ptr], t38_amp_b, sizeof(int16_t)*SAMPLES_PER_CHUNK); - } - if (drop_frame_rate && --drop_frame == 0) - { - drop_frame = drop_frame_rate; - if (t38_gateway_rx_fillin(t38_state_b, t30_len_b)) - break; - } - else - { - if (t38_gateway_rx(t38_state_b, t30_amp_b, t30_len_b)) - break; - } - - t38_len_b = t38_gateway_tx(t38_state_b, t38_amp_b, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - if (t38_len_b < SAMPLES_PER_CHUNK) - { - memset(t38_amp_b + t38_len_b, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len_b)); - t38_len_b = SAMPLES_PER_CHUNK; - } - } - if (log_audio) - { - for (i = 0; i < t38_len_b; i++) - out_amp[i*4 + 2] = t38_amp_b[i]; - } - if (fax_rx(fax_state_b, t38_amp_b, SAMPLES_PER_CHUNK)) - break; - - when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; - - while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_gateway_get_t38_core_state(t38_state_b); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - if (log_audio) - { - outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK); - if (outframes != SAMPLES_PER_CHUNK) - break; - } - - if (done[0] && done[1]) - break; -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_update_display(); -#endif - if (++hist_ptr > 3) - hist_ptr = 0; - } - t38_gateway_get_transfer_statistics(t38_state_a, &stats); - printf("A side exchanged %d pages at %dbps, in %s mode\n", - stats.pages_transferred, - stats.bit_rate, - (stats.error_correcting_mode) ? "ECM" : "non-ECM"); - t38_gateway_get_transfer_statistics(t38_state_a, &stats); - printf("B side exchanged %d pages at %dbps, in %s mode\n", - stats.pages_transferred, - stats.bit_rate, - (stats.error_correcting_mode) ? "ECM" : "non-ECM"); - fax_release(fax_state_a); - fax_release(fax_state_b); - if (log_audio) - { - if (sf_close_telephony(wave_handle) != 0) - { - fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); - exit(2); - } - } - if (!succeeded[0] || !succeeded[1]) - { - printf("Tests failed\n"); - exit(2); - } - printf("Tests passed\n"); - return 0; -} -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/tests/t38_gateway_to_terminal_tests.c b/libs/spandsp/tests/t38_gateway_to_terminal_tests.c deleted file mode 100644 index 8ea2e9551a..0000000000 --- a/libs/spandsp/tests/t38_gateway_to_terminal_tests.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * t38_gateway_to_terminal_tests.c - Joint tests for the T.38 FoIP terminal and gateway modules. - * - * Written by Steve Underwood - * - * Copyright (C) 2005, 2006 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*! \file */ - -/*! \page t38_gateway_to_terminal_tests_page T.38 mixed gateway and termination tests -\section t38_gateway_to_terminal_tests_page_sec_1 What does it do? -These tests exercise the path - - FAX machine -> T.38 gateway -> T.38 termination -*/ - -/* Enable the following definition to enable direct probing into the FAX structures */ -//#define WITH_SPANDSP_INTERNALS - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -#if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H) && defined(HAVE_FL_FL_AUDIO_METER_H) -#define ENABLE_GUI -#endif - -#include -#include -#include -#include -#include -#include -#include -#if !defined(_WIN32) -#include -#endif - -//#if defined(WITH_SPANDSP_INTERNALS) -#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES -//#endif - -#include "spandsp.h" -#include "spandsp-sim.h" - -#if defined(ENABLE_GUI) -#include "media_monitor.h" -#endif -#include "fax_utils.h" - -#define SAMPLES_PER_CHUNK 160 - -#define INPUT_FILE_NAME "../test-data/itu/fax/itutests.tif" -#define OUTPUT_FILE_NAME "t38.tif" -#define OUTPUT_FILE_NAME_WAVE "t38_gateway_to_terminal.wav" - -fax_state_t *fax_state_a; -t38_gateway_state_t *t38_state_a; -t38_terminal_state_t *t38_state_b; - -g1050_state_t *path_a_to_b; -g1050_state_t *path_b_to_a; - -double when = 0.0; - -int done[2] = {FALSE, FALSE}; -int succeeded[2] = {FALSE, FALSE}; - -int simulate_incrementing_repeats = FALSE; - -int t38_version; -int use_ecm; -int use_tep; -int use_transmit_on_idle; -int supported_modems; -int use_gui; -int g1050_model_no; -int g1050_speed_pattern_no; - -static int phase_b_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase B", i); - printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static int phase_d_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase D", i); - printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static void phase_e_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - t30_stats_t t; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase E", i); - printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - t30_get_transfer_statistics(s, &t); - succeeded[i - 'A'] = (result == T30_ERR_OK) && (t.pages_tx == 12 || t.pages_rx == 12); - done[i - 'A'] = TRUE; -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_a(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - g1050_put(path_a_to_b, buf, len, subst_seq, when); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - g1050_put(path_a_to_b, buf, len, s->tx_seq_no, when); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_b(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - g1050_put(path_b_to_a, buf, len, subst_seq, when); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - g1050_put(path_b_to_a, buf, len, s->tx_seq_no, when); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static int decode_test(const char *decode_test_file) -{ - int16_t t38_amp_a[SAMPLES_PER_CHUNK]; - int16_t t30_amp_a[SAMPLES_PER_CHUNK]; - SNDFILE *wave_handle; - t30_state_t *t30; - t38_core_state_t *t38_core; - logging_state_t *logging; - int t38_len_a; - int t30_len_a; - int msg_len; - uint8_t msg[1024]; - int seq_no; - double tx_when; - double rx_when; - - printf("Decode test data file '%s'\n", decode_test_file); - - if ((wave_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL) - { - fprintf(stderr, " Cannot open audio file '%s'\n", decode_test_file); - exit(2); - } - - srand48(0x1234567); - if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - - memset(t30_amp_a, 0, sizeof(t30_amp_a)); - - if ((t38_state_a = t38_gateway_init(NULL, tx_packet_handler_a, t38_state_b)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - t38_gateway_set_transmit_on_idle(t38_state_a, use_transmit_on_idle); - t38_set_t38_version(t38_core, t38_version); - t38_gateway_set_ecm_capability(t38_state_a, use_ecm); - - logging = t38_gateway_get_logging_state(t38_state_a); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = &t38_state_a->audio.modems.v17_rx.logging; - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "V.17-A"); - - memset(t38_amp_a, 0, sizeof(t38_amp_a)); - - if ((t38_state_b = t38_terminal_init(NULL, FALSE, tx_packet_handler_b, t38_state_a)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t30 = t38_terminal_get_t30_state(t38_state_b); - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - t38_set_t38_version(t38_core, t38_version); - - logging = t38_terminal_get_logging_state(t38_state_b); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "22222222"); - t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); - -#if defined(ENABLE_GUI) - if (use_gui) - start_media_monitor(); -#endif - for (;;) - { - t30_len_a = sf_readf_short(wave_handle, t30_amp_a, SAMPLES_PER_CHUNK); - - logging = t38_gateway_get_logging_state(t38_state_a); - span_log_bump_samples(logging, t30_len_a); - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, t30_len_a); - logging = &t38_state_a->audio.modems.v17_rx.logging; - span_log_bump_samples(logging, t30_len_a); - - logging = t38_terminal_get_logging_state(t38_state_b); - span_log_bump_samples(logging, t30_len_a); - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, t30_len_a); - - t30 = t38_terminal_get_t30_state(t38_state_b); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, t30_len_a); - - t38_terminal_send_timeout(t38_state_b, t30_len_a); - - if (t38_gateway_rx(t38_state_a, t30_amp_a, t30_len_a)) - break; - - t38_len_a = t38_gateway_tx(t38_state_a, t38_amp_a, t30_len_a); - if (!use_transmit_on_idle) - { - if (t38_len_a < SAMPLES_PER_CHUNK) - { - memset(t38_amp_a + t38_len_a, 0, sizeof(int16_t)*(t30_len_a - t38_len_a)); - t38_len_a = t30_len_a; - } - } - - when += (float) t30_len_a/(float) SAMPLE_RATE; - - while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - - if (done[0] && done[1]) - break; -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_update_display(); -#endif - } - t38_gateway_release(t38_state_a); - t38_terminal_release(t38_state_b); - if (sf_close_telephony(wave_handle)) - { - fprintf(stderr, " Cannot close audio file '%s'\n", decode_test_file); - exit(2); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -int main(int argc, char *argv[]) -{ - int16_t t38_amp_a[SAMPLES_PER_CHUNK]; - int16_t t30_amp_a[SAMPLES_PER_CHUNK]; - int16_t out_amp[2*SAMPLES_PER_CHUNK]; - int t38_len_a; - int t30_len_a; - int msg_len; - uint8_t msg[1024]; - int log_audio; - int outframes; - int feedback_audio; - SNDFILE *wave_handle; - const char *input_file_name; - int i; - int seq_no; - double tx_when; - double rx_when; - int opt; - t30_state_t *t30; - t38_core_state_t *t38_core; - logging_state_t *logging; - char *decode_test_file; - - log_audio = FALSE; - t38_version = 1; - use_ecm = FALSE; - input_file_name = INPUT_FILE_NAME; - simulate_incrementing_repeats = FALSE; - g1050_model_no = 0; - g1050_speed_pattern_no = 1; - use_gui = FALSE; - use_tep = FALSE; - feedback_audio = FALSE; - use_transmit_on_idle = TRUE; - supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17; - decode_test_file = NULL; - while ((opt = getopt(argc, argv, "d:efgi:Ilm:M:s:tv:")) != -1) - { - switch (opt) - { - case 'd': - decode_test_file = optarg; - break; - case 'e': - use_ecm = TRUE; - break; - case 'f': - feedback_audio = TRUE; - break; - case 'g': -#if defined(ENABLE_GUI) - use_gui = TRUE; -#else - fprintf(stderr, "Graphical monitoring not available\n"); - exit(2); -#endif - break; - case 'i': - input_file_name = optarg; - break; - case 'I': - simulate_incrementing_repeats = TRUE; - break; - case 'l': - log_audio = TRUE; - break; - case 'm': - supported_modems = atoi(optarg); - break; - case 'M': - g1050_model_no = optarg[0] - 'A' + 1; - break; - case 's': - g1050_speed_pattern_no = atoi(optarg); - break; - case 't': - use_tep = TRUE; - break; - case 'v': - t38_version = atoi(optarg); - break; - default: - //usage(); - exit(2); - break; - } - } - - printf("Using T.38 version %d\n", t38_version); - if (use_ecm) - printf("Using ECM\n"); - - if (decode_test_file) - { - decode_test(decode_test_file); - return 0; - } - - wave_handle = NULL; - if (log_audio) - { - if ((wave_handle = sf_open_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == NULL) - { - fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); - exit(2); - } - } - - srand48(0x1234567); - if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - - if ((fax_state_a = fax_init(NULL, TRUE)) == NULL) - { - fprintf(stderr, "Cannot start FAX\n"); - exit(2); - } - t30 = fax_get_t30_state(fax_state_a); - fax_set_transmit_on_idle(fax_state_a, use_transmit_on_idle); - fax_set_tep_mode(fax_state_a, use_tep); - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "11111111"); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_tx_file(t30, input_file_name, -1, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); - - logging = fax_get_logging_state(fax_state_a); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-A "); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-A "); - - memset(t30_amp_a, 0, sizeof(t30_amp_a)); - - if ((t38_state_a = t38_gateway_init(NULL, tx_packet_handler_a, t38_state_b)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - t38_gateway_set_transmit_on_idle(t38_state_a, use_transmit_on_idle); - t38_set_t38_version(t38_core, t38_version); - t38_gateway_set_ecm_capability(t38_state_a, use_ecm); - - logging = t38_gateway_get_logging_state(t38_state_a); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = &t38_state_a->audio.modems.v17_rx.logging; - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "V.17-A"); - - memset(t38_amp_a, 0, sizeof(t38_amp_a)); - - if ((t38_state_b = t38_terminal_init(NULL, FALSE, tx_packet_handler_b, t38_state_a)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t30 = t38_terminal_get_t30_state(t38_state_b); - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - t38_set_t38_version(t38_core, t38_version); - - logging = t38_terminal_get_logging_state(t38_state_b); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "22222222"); - t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); - -#if defined(ENABLE_GUI) - if (use_gui) - start_media_monitor(); -#endif - for (;;) - { - logging = fax_get_logging_state(fax_state_a); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = fax_get_t30_state(fax_state_a); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - - logging = t38_gateway_get_logging_state(t38_state_a); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = &t38_state_a->audio.modems.v17_rx.logging; - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - - logging = t38_terminal_get_logging_state(t38_state_b); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = t38_terminal_get_t30_state(t38_state_b); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - memset(out_amp, 0, sizeof(out_amp)); - - t38_terminal_send_timeout(t38_state_b, SAMPLES_PER_CHUNK); - - t30_len_a = fax_tx(fax_state_a, t30_amp_a, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - /* The receive side always expects a full block of samples, but the - transmit side may not be sending any when it doesn't need to. We - may need to pad with some silence. */ - if (t30_len_a < SAMPLES_PER_CHUNK) - { - memset(t30_amp_a + t30_len_a, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len_a)); - t30_len_a = SAMPLES_PER_CHUNK; - } - } - if (log_audio) - { - for (i = 0; i < t30_len_a; i++) - out_amp[2*i] = t30_amp_a[i]; - } - if (feedback_audio) - { - for (i = 0; i < t30_len_a; i++) - t30_amp_a[i] += t38_amp_a[i] >> 1; - } - if (t38_gateway_rx(t38_state_a, t30_amp_a, t30_len_a)) - break; - - t38_len_a = t38_gateway_tx(t38_state_a, t38_amp_a, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - if (t38_len_a < SAMPLES_PER_CHUNK) - { - memset(t38_amp_a + t38_len_a, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len_a)); - t38_len_a = SAMPLES_PER_CHUNK; - } - } - if (log_audio) - { - for (i = 0; i < t38_len_a; i++) - out_amp[2*i + 1] = t38_amp_a[i]; - } - if (fax_rx(fax_state_a, t38_amp_a, SAMPLES_PER_CHUNK)) - break; - - when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; - - while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_gateway_get_t38_core_state(t38_state_a); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - if (log_audio) - { - outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK); - if (outframes != SAMPLES_PER_CHUNK) - break; - } - - if (done[0] && done[1]) - break; -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_update_display(); -#endif - } - fax_release(fax_state_a); - t38_gateway_release(t38_state_a); - t38_terminal_release(t38_state_b); - if (log_audio) - { - if (sf_close_telephony(wave_handle)) - { - fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); - exit(2); - } - } - if (!succeeded[0] || !succeeded[1]) - { - printf("Tests failed\n"); - exit(2); - } - printf("Tests passed\n"); - return 0; -} -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/tests/t38_terminal_tests.c b/libs/spandsp/tests/t38_terminal_tests.c deleted file mode 100644 index 7b5d22a935..0000000000 --- a/libs/spandsp/tests/t38_terminal_tests.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * t38_terminal_tests.c - Tests for the T.38 FoIP terminal module. - * - * Written by Steve Underwood - * - * Copyright (C) 2005, 2006 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*! \file */ - -/*! \page t38_terminal_tests_page T.38 termination tests -\section t38_terminal_tests_page_sec_1 What does it do? -These tests exercise the path - - T.38 termination <-> T.38 termination -*/ - -//#define WITH_SPANDSP_INTERNALS - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -#if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H) && defined(HAVE_FL_FL_AUDIO_METER_H) -#define ENABLE_GUI -#endif - -#include -#include -#include -#include -#include -#include -#if !defined(_WIN32) -#include -#endif - -//#if defined(WITH_SPANDSP_INTERNALS) -#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES -//#endif - -#include "spandsp.h" -#include "spandsp-sim.h" - -#if defined(ENABLE_GUI) -#include "media_monitor.h" -#endif -#include "fax_utils.h" - -#define SAMPLES_PER_CHUNK 160 - -#define INPUT_FILE_NAME "../test-data/itu/fax/itutests.tif" -#define OUTPUT_FILE_NAME "t38.tif" - -t38_terminal_state_t *t38_state_a; -t38_terminal_state_t *t38_state_b; - -g1050_state_t *path_a_to_b; -g1050_state_t *path_b_to_a; - -double when = 0.0; - -int done[2] = {FALSE, FALSE}; -int succeeded[2] = {FALSE, FALSE}; - -int simulate_incrementing_repeats = FALSE; - -static int phase_b_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase B", i); - printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static int phase_d_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase D", i); - printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static void phase_e_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - t30_stats_t t; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase E", i); - printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - t30_get_transfer_statistics(s, &t); - succeeded[i - 'A'] = (result == T30_ERR_OK) && (t.pages_tx == 12 || t.pages_rx == 12); - //done[i - 'A'] = TRUE; -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_a(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - if (g1050_put(path_a_to_b, buf, len, subst_seq, when) < 0) - printf("Lost packet %d\n", subst_seq); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - { - if (g1050_put(path_a_to_b, buf, len, s->tx_seq_no, when) < 0) - printf("Lost packet %d\n", s->tx_seq_no); - } - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_b(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - g1050_put(path_b_to_a, buf, len, subst_seq, when); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - g1050_put(path_b_to_a, buf, len, s->tx_seq_no, when); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -int main(int argc, char *argv[]) -{ - int msg_len; - uint8_t msg[1024]; - int t38_version; - int seq_no; - int use_ecm; - int options; - int use_tep; - int g1050_model_no; - int g1050_speed_pattern_no; - const char *input_file_name; - double tx_when; - double rx_when; - int use_gui; - int supported_modems; - int opt; - t30_state_t *t30; - t38_core_state_t *t38_core; - logging_state_t *logging; - - t38_version = 1; - options = 0; - use_tep = FALSE; - input_file_name = INPUT_FILE_NAME; - use_ecm = FALSE; - simulate_incrementing_repeats = FALSE; - g1050_model_no = 0; - g1050_speed_pattern_no = 1; - use_gui = FALSE; - supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17; - while ((opt = getopt(argc, argv, "efgi:Im:M:o:s:tv:")) != -1) - { - switch (opt) - { - case 'e': - use_ecm = TRUE; - break; - case 'g': -#if defined(ENABLE_GUI) - use_gui = TRUE; -#else - fprintf(stderr, "Graphical monitoring not available\n"); - exit(2); -#endif - break; - case 'i': - input_file_name = optarg; - break; - case 'I': - simulate_incrementing_repeats = TRUE; - break; - case 'm': - supported_modems = atoi(optarg); - break; - case 'M': - g1050_model_no = optarg[0] - 'A' + 1; - break; - case 'o': - options = atoi(optarg); - break; - case 's': - g1050_speed_pattern_no = atoi(optarg); - break; - case 't': - use_tep = TRUE; - break; - case 'v': - t38_version = atoi(optarg); - break; - default: - //usage(); - exit(2); - break; - } - } - - printf("Using T.38 version %d\n", t38_version); - if (use_ecm) - printf("Using ECM\n"); - - srand48(0x1234567); - if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - - if ((t38_state_a = t38_terminal_init(NULL, TRUE, tx_packet_handler_a, t38_state_b)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t30 = t38_terminal_get_t30_state(t38_state_a); - t38_core = t38_terminal_get_t38_core_state(t38_state_a); - t38_set_t38_version(t38_core, t38_version); - t38_terminal_set_config(t38_state_a, options); - t38_terminal_set_tep_mode(t38_state_a, use_tep); - - logging = t38_terminal_get_logging_state(t38_state_a); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "11111111"); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_tx_file(t30, input_file_name, -1, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION | T30_SUPPORT_T85_COMPRESSION); - - if ((t38_state_b = t38_terminal_init(NULL, FALSE, tx_packet_handler_b, t38_state_a)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t30 = t38_terminal_get_t30_state(t38_state_b); - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - t38_set_t38_version(t38_core, t38_version); - t38_terminal_set_config(t38_state_b, options); - t38_terminal_set_tep_mode(t38_state_b, use_tep); - - logging = t38_terminal_get_logging_state(t38_state_b); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "22222222"); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION | T30_SUPPORT_T85_COMPRESSION); - -#if defined(ENABLE_GUI) - if (use_gui) - start_media_monitor(); -#endif - for (;;) - { - logging = t38_terminal_get_logging_state(t38_state_a); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_terminal_get_t38_core_state(t38_state_a); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = t38_terminal_get_t30_state(t38_state_a); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t38_terminal_get_logging_state(t38_state_b); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = t38_terminal_get_t30_state(t38_state_b); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - - done[0] = t38_terminal_send_timeout(t38_state_a, SAMPLES_PER_CHUNK); - done[1] = t38_terminal_send_timeout(t38_state_b, SAMPLES_PER_CHUNK); - - when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; - - while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_terminal_get_t38_core_state(t38_state_b); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_terminal_get_t38_core_state(t38_state_a); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - if (done[0] && done[1]) - break; -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_update_display(); -#endif - } - t38_terminal_release(t38_state_a); - t38_terminal_release(t38_state_b); - if (!succeeded[0] || !succeeded[1]) - { - printf("Tests failed\n"); - exit(2); - } - printf("Tests passed\n"); - return 0; -} -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/tests/t38_terminal_to_gateway_tests.c b/libs/spandsp/tests/t38_terminal_to_gateway_tests.c deleted file mode 100644 index 6712aea29f..0000000000 --- a/libs/spandsp/tests/t38_terminal_to_gateway_tests.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * t38_terminal_to_gateway_tests.c - Joint tests for the T.38 FoIP terminal and gateway modules. - * - * Written by Steve Underwood - * - * Copyright (C) 2005, 2006 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*! \file */ - -/*! \page t38_terminal_to_gateway_tests_page T.38 mixed gateway and termination tests -\section t38_terminal_to_gateway_tests_page_sec_1 What does it do? -These tests exercise the path - - T.38 termination -> T.38 gateway -> FAX machine -*/ - -/* Enable the following definition to enable direct probing into the FAX structures */ -//#define WITH_SPANDSP_INTERNALS - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -#if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H) && defined(HAVE_FL_FL_AUDIO_METER_H) -#define ENABLE_GUI -#endif - -#include -#include -#include -#include -#include -#include -#include -#if !defined(_WIN32) -#include -#endif - -//#if defined(WITH_SPANDSP_INTERNALS) -#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES -//#endif - -#include "spandsp.h" -#include "spandsp-sim.h" - -#if defined(ENABLE_GUI) -#include "media_monitor.h" -#endif -#include "fax_utils.h" - -#define SAMPLES_PER_CHUNK 160 - -#define INPUT_FILE_NAME "../test-data/itu/fax/itutests.tif" -#define OUTPUT_FILE_NAME "t38.tif" -#define OUTPUT_FILE_NAME_WAVE "t38_terminal_to_gateway.wav" - -t38_terminal_state_t *t38_state_a; -t38_gateway_state_t *t38_state_b; -fax_state_t *fax_state_b; - -g1050_state_t *path_a_to_b; -g1050_state_t *path_b_to_a; - -double when = 0.0; - -int done[2] = {FALSE, FALSE}; -int succeeded[2] = {FALSE, FALSE}; - -int simulate_incrementing_repeats = FALSE; - -static int phase_b_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase B", i); - printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static int phase_d_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase D", i); - printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static void phase_e_handler(t30_state_t *s, void *user_data, int result) -{ - int i; - t30_stats_t t; - char tag[20]; - - i = (int) (intptr_t) user_data; - snprintf(tag, sizeof(tag), "%c: Phase E", i); - printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result)); - fax_log_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - t30_get_transfer_statistics(s, &t); - succeeded[i - 'A'] = (result == T30_ERR_OK) && (t.pages_tx == 12 || t.pages_rx == 12); - done[i - 'A'] = TRUE; -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_a(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - g1050_put(path_a_to_b, buf, len, subst_seq, when); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - g1050_put(path_a_to_b, buf, len, s->tx_seq_no, when); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static int tx_packet_handler_b(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) -{ - t38_terminal_state_t *t; - int i; - static int subst_seq = 0; - - /* This routine queues messages between two instances of T.38 processing */ - t = (t38_terminal_state_t *) user_data; - if (simulate_incrementing_repeats) - { - for (i = 0; i < count; i++) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", subst_seq, len); - - g1050_put(path_b_to_a, buf, len, subst_seq, when); - subst_seq = (subst_seq + 1) & 0xFFFF; - } - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count); - - for (i = 0; i < count; i++) - g1050_put(path_b_to_a, buf, len, s->tx_seq_no, when); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -int main(int argc, char *argv[]) -{ - int16_t t38_amp_b[SAMPLES_PER_CHUNK]; - int16_t t30_amp_b[SAMPLES_PER_CHUNK]; - int16_t out_amp[2*SAMPLES_PER_CHUNK]; - int t38_len_b; - int t30_len_b; - int msg_len; - uint8_t msg[1024]; - int log_audio; - int outframes; - SNDFILE *wave_handle; - int t38_version; - int use_ecm; - int use_tep; - int feedback_audio; - int use_transmit_on_idle; - const char *input_file_name; - int i; - int seq_no; - int g1050_model_no; - int g1050_speed_pattern_no; - double tx_when; - double rx_when; - int use_gui; - int supported_modems; - int opt; - t30_state_t *t30; - t38_core_state_t *t38_core; - logging_state_t *logging; - - log_audio = FALSE; - t38_version = 1; - use_ecm = FALSE; - input_file_name = INPUT_FILE_NAME; - simulate_incrementing_repeats = FALSE; - g1050_model_no = 0; - g1050_speed_pattern_no = 1; - use_gui = FALSE; - use_tep = FALSE; - feedback_audio = FALSE; - use_transmit_on_idle = TRUE; - supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17; - while ((opt = getopt(argc, argv, "efgi:Ilm:M:s:tv:")) != -1) - { - switch (opt) - { - case 'e': - use_ecm = TRUE; - break; - case 'f': - feedback_audio = TRUE; - break; - case 'g': -#if defined(ENABLE_GUI) - use_gui = TRUE; -#else - fprintf(stderr, "Graphical monitoring not available\n"); - exit(2); -#endif - break; - case 'i': - input_file_name = optarg; - break; - case 'I': - simulate_incrementing_repeats = TRUE; - break; - case 'l': - log_audio = TRUE; - break; - case 'm': - supported_modems = atoi(optarg); - break; - case 'M': - g1050_model_no = optarg[0] - 'A' + 1; - break; - case 's': - g1050_speed_pattern_no = atoi(optarg); - break; - case 't': - use_tep = TRUE; - break; - case 'v': - t38_version = atoi(optarg); - break; - default: - //usage(); - exit(2); - break; - } - } - - printf("Using T.38 version %d\n", t38_version); - if (use_ecm) - printf("Using ECM\n"); - - wave_handle = NULL; - if (log_audio) - { - if ((wave_handle = sf_open_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == NULL) - { - fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); - exit(2); - } - } - - srand48(0x1234567); - if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) - { - fprintf(stderr, "Failed to start IP network path model\n"); - exit(2); - } - - if ((t38_state_a = t38_terminal_init(NULL, TRUE, tx_packet_handler_a, &t38_state_b)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t30 = t38_terminal_get_t30_state(t38_state_a); - t38_core = t38_terminal_get_t38_core_state(t38_state_a); - t38_set_t38_version(t38_core, t38_version); - - logging = t38_terminal_get_logging_state(t38_state_a); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-A"); - - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "11111111"); - t30_set_tx_file(t30, input_file_name, -1, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); - - if ((t38_state_b = t38_gateway_init(NULL, tx_packet_handler_b, &t38_state_a)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 channel\n"); - exit(2); - } - t38_core = t38_gateway_get_t38_core_state(t38_state_b); - t38_gateway_set_transmit_on_idle(t38_state_b, use_transmit_on_idle); - t38_set_t38_version(t38_core, t38_version); - t38_gateway_set_ecm_capability(t38_state_b, use_ecm); - - logging = t38_gateway_get_logging_state(t38_state_b); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - logging = t38_core_get_logging_state(t38_core); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "T.38-B"); - - memset(t38_amp_b, 0, sizeof(t38_amp_b)); - - if ((fax_state_b = fax_init(NULL, FALSE)) == NULL) - { - fprintf(stderr, "Cannot start FAX\n"); - exit(2); - } - t30 = fax_get_t30_state(fax_state_b); - fax_set_transmit_on_idle(fax_state_b, use_transmit_on_idle); - fax_set_tep_mode(fax_state_b, use_tep); - t30_set_supported_modems(t30, supported_modems); - t30_set_tx_ident(t30, "22222222"); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B'); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B'); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B'); - t30_set_ecm_capability(t30, use_ecm); - if (use_ecm) - t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION); - - logging = fax_get_logging_state(fax_state_b); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-B "); - - logging = t30_get_logging_state(t30); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, "FAX-B "); - - memset(t30_amp_b, 0, sizeof(t30_amp_b)); - -#if defined(ENABLE_GUI) - if (use_gui) - start_media_monitor(); -#endif - for (;;) - { - logging = t38_terminal_get_logging_state(t38_state_a); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_terminal_get_t38_core_state(t38_state_a); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = t38_terminal_get_t30_state(t38_state_a); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t38_gateway_get_logging_state(t38_state_b); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t38_core = t38_gateway_get_t38_core_state(t38_state_b); - logging = t38_core_get_logging_state(t38_core); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = fax_get_logging_state(fax_state_b); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - t30 = fax_get_t30_state(fax_state_b); - logging = t30_get_logging_state(t30); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - memset(out_amp, 0, sizeof(out_amp)); - - t38_terminal_send_timeout(t38_state_a, SAMPLES_PER_CHUNK); - - t30_len_b = fax_tx(fax_state_b, t30_amp_b, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - /* The receive side always expects a full block of samples, but the - transmit side may not be sending any when it doesn't need to. We - may need to pad with some silence. */ - if (t30_len_b < SAMPLES_PER_CHUNK) - { - memset(t30_amp_b + t30_len_b, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len_b)); - t30_len_b = SAMPLES_PER_CHUNK; - } - } - if (feedback_audio) - { - for (i = 0; i < t30_len_b; i++) - t30_amp_b[i] += t38_amp_b[i] >> 1; - } - if (log_audio) - { - for (i = 0; i < t30_len_b; i++) - out_amp[2*i + 1] = t30_amp_b[i]; - } - if (t38_gateway_rx(t38_state_b, t30_amp_b, t30_len_b)) - break; - - t38_len_b = t38_gateway_tx(t38_state_b, t38_amp_b, SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - if (t38_len_b < SAMPLES_PER_CHUNK) - { - memset(t38_amp_b + t38_len_b, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len_b)); - t38_len_b = SAMPLES_PER_CHUNK; - } - } - if (log_audio) - { - for (i = 0; i < t38_len_b; i++) - out_amp[2*i] = t38_amp_b[i]; - } - if (fax_rx(fax_state_b, t38_amp_b, SAMPLES_PER_CHUNK)) - break; - - when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; - - while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_gateway_get_t38_core_state(t38_state_b); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) - { -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_rx(seq_no, tx_when, rx_when); -#endif - t38_core = t38_terminal_get_t38_core_state(t38_state_a); - t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no); - } - if (log_audio) - { - outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK); - if (outframes != SAMPLES_PER_CHUNK) - break; - } - - if (done[0] && done[1]) - break; -#if defined(ENABLE_GUI) - if (use_gui) - media_monitor_update_display(); -#endif - } - t38_terminal_release(t38_state_a); - fax_release(fax_state_b); - if (log_audio) - { - if (sf_close_telephony(wave_handle)) - { - fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE); - exit(2); - } - } - if (!succeeded[0] || !succeeded[1]) - { - printf("Tests failed\n"); - exit(2); - } - printf("Tests passed\n"); - return 0; -} -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/tests/t4_tests.c b/libs/spandsp/tests/t4_tests.c index 8eb9c159a0..a2967948b7 100644 --- a/libs/spandsp/tests/t4_tests.c +++ b/libs/spandsp/tests/t4_tests.c @@ -283,18 +283,21 @@ int main(int argc, char *argv[]) T4_COMPRESSION_ITU_T4_1D, T4_COMPRESSION_ITU_T4_2D, T4_COMPRESSION_ITU_T6, +#if defined(SPANDSP_SUPPORT_T42x) + T4_COMPRESSION_ITU_T42, + T4_COMPRESSION_ITU_SYCC_T42, +#endif +#if defined(SPANDSP_SUPPORT_T43x) + T4_COMPRESSION_ITU_T43, +#endif #if defined(SPANDSP_SUPPORT_T85) T4_COMPRESSION_ITU_T85, T4_COMPRESSION_ITU_T85_L0, #endif - //T4_COMPRESSION_ITU_T43, //T4_COMPRESSION_ITU_T45, - //T4_COMPRESSION_ITU_T81, - //T4_COMPRESSION_ITU_SYCC_T81, -1 }; int sends; - int page_no; int bit; int end_of_page; int end_marks; @@ -337,33 +340,53 @@ int main(int argc, char *argv[]) block_size = 1; bit_error_rate = 0; dump_as_xxx = FALSE; - while ((opt = getopt(argc, argv, "1268b:d:ehHri:m:t:x")) != -1) + while ((opt = getopt(argc, argv, "b:c:d:ehHri:m:t:x")) != -1) { switch (opt) { - case '1': - compression = T4_COMPRESSION_ITU_T4_1D; - compression_step = -1; - break; - case '2': - compression = T4_COMPRESSION_ITU_T4_2D; - compression_step = -1; - break; - case '6': - compression = T4_COMPRESSION_ITU_T6; - compression_step = -1; - break; -#if defined(SPANDSP_SUPPORT_T85) - case '8': - compression = T4_COMPRESSION_ITU_T85; - compression_step = -1; - break; -#endif case 'b': block_size = atoi(optarg); if (block_size > 1024) block_size = 1024; break; + case 'c': + if (strcmp(optarg, "T41D") == 0) + { + compression = T4_COMPRESSION_ITU_T4_1D; + compression_step = -1; + } + else if (strcmp(optarg, "T42D") == 0) + { + compression = T4_COMPRESSION_ITU_T4_2D; + compression_step = -1; + } + else if (strcmp(optarg, "T6") == 0) + { + compression = T4_COMPRESSION_ITU_T6; + compression_step = -1; + } +#if defined(SPANDSP_SUPPORT_T42) + else if (strcmp(optarg, "T42") == 0) + { + compression = T4_COMPRESSION_ITU_T42; + compression_step = -1; + } +#endif +#if defined(SPANDSP_SUPPORT_T43) + else if (strcmp(optarg, "T43") == 0) + { + compression = T4_COMPRESSION_ITU_T43; + compression_step = -1; + } +#endif +#if defined(SPANDSP_SUPPORT_T85) + else if (strcmp(optarg, "T85") == 0) + { + compression = T4_COMPRESSION_ITU_T85; + compression_step = -1; + } +#endif + break; case 'd': decode_file_name = optarg; break; @@ -421,7 +444,6 @@ int main(int argc, char *argv[]) t4_rx_set_y_resolution(&receive_state, T4_Y_RESOLUTION_STANDARD); t4_rx_set_image_width(&receive_state, XSIZE); - page_no = 1; t4_rx_start_page(&receive_state); last_pkt_no = 0; file = fopen(decode_file_name, "r"); @@ -449,7 +471,7 @@ int main(int argc, char *argv[]) break; } } - else if (strlen(buf) > 62 && sscanf(buf + 57, "Rx %d: IFP %x %x", &pkt_no, (unsigned int *) &bit, (unsigned int *) &bit) == 3) + else if (sscanf(buf, "%*d:%*d:%*d.%*d T.38 Rx %d: IFP %x %x", &pkt_no, (unsigned int *) &bit, (unsigned int *) &bit) == 3) { /* Useful for breaking up T.38 non-ECM logs */ if (pkt_no != last_pkt_no + 1) @@ -457,7 +479,7 @@ int main(int argc, char *argv[]) last_pkt_no = pkt_no; for (i = 0; i < 256; i++) { - if (sscanf(&buf[57 + 29 + 3*i], "%x", (unsigned int *) &bit) != 1) + if (sscanf(&buf[47 + 3*i], "%x", (unsigned int *) &bit) != 1) break; bit = bit_reverse8(bit); if ((end_of_page = t4_rx_put_byte(&receive_state, bit))) @@ -545,7 +567,6 @@ int main(int argc, char *argv[]) t4_rx_set_y_resolution(&receive_state, t4_tx_get_y_resolution(&send_state)); /* Now send and receive the test data with all compression modes. */ - page_no = 1; /* If we are stepping around the compression schemes, reset to the start of the sequence. */ if (compression_step > 0) compression_step = 0; @@ -665,7 +686,6 @@ int main(int argc, char *argv[]) t4_rx_set_image_width(&receive_state, t4_tx_get_image_width(&send_state)); /* Now send and receive all the pages in the source TIFF file */ - page_no = 1; sends = 0; /* If we are stepping around the compression schemes, reset to the start of the sequence. */ if (compression_step > 0) diff --git a/libs/spandsp/tests/tone_generate_tests.c b/libs/spandsp/tests/tone_generate_tests.c index 469bfced5a..f61753da37 100644 --- a/libs/spandsp/tests/tone_generate_tests.c +++ b/libs/spandsp/tests/tone_generate_tests.c @@ -55,7 +55,6 @@ int main(int argc, char *argv[]) int16_t amp[16384]; int len; SNDFILE *outhandle; - int outframes; if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL) { diff --git a/libs/spandsp/tests/tsb85_tests.c b/libs/spandsp/tests/tsb85_tests.c index 7a2913bc19..aa78e5dfba 100644 --- a/libs/spandsp/tests/tsb85_tests.c +++ b/libs/spandsp/tests/tsb85_tests.c @@ -220,7 +220,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result) snprintf(tag, sizeof(tag), "%c: Phase D", i); printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result)); - fax_log_transfer_statistics(s, tag); + fax_log_page_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); @@ -262,7 +262,7 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) i = (intptr_t) user_data; snprintf(tag, sizeof(tag), "%c: Phase E", i); printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result)); - fax_log_transfer_statistics(s, tag); + fax_log_final_transfer_statistics(s, tag); fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); } diff --git a/libs/spandsp/tests/v17_tests.c b/libs/spandsp/tests/v17_tests.c index ddf1b27104..33aef4d2ba 100644 --- a/libs/spandsp/tests/v17_tests.c +++ b/libs/spandsp/tests/v17_tests.c @@ -122,7 +122,11 @@ static void v17_rx_status(void *user_data, int status) v17_rx_state_t *s; int i; int len; +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t *coeffs; +#else complexf_t *coeffs; +#endif printf("V.17 rx status is %s (%d)\n", signal_status_to_str(status), status); s = (v17_rx_state_t *) user_data; @@ -132,7 +136,11 @@ static void v17_rx_status(void *user_data, int status) len = v17_rx_equalizer_state(s, &coeffs); printf("Equalizer:\n"); for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINTx) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f); +#else printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif break; } } @@ -165,7 +173,11 @@ static int v17getbit(void *user_data) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static void qam_report(void *user_data, const complexi16_t *constel, const complexi16_t *target, int symbol) +#else static void qam_report(void *user_data, const complexf_t *constel, const complexf_t *target, int symbol) +#endif { int i; int len; @@ -208,10 +220,18 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex len = v17_rx_equalizer_state(rx, &coeffs); printf("Equalizer A:\n"); for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINTx) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f); +#else printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif #if defined(ENABLE_GUI) if (use_gui) +#if defined(SPANDSP_USE_FIXED_POINTx) + qam_monitor_update_int_equalizer(qam_monitor, coeffs, len); +#else qam_monitor_update_equalizer(qam_monitor, coeffs, len); +#endif #endif update_interval = 100; } @@ -405,7 +425,7 @@ int main(int argc, char *argv[]) tx = v17_tx_init(NULL, test_bps, tep, v17getbit, NULL); logging = v17_tx_get_logging_state(tx); span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); - span_log_set_tag(logging, "V.17 tx"); + span_log_set_tag(logging, "V.17-tx"); v17_tx_power(tx, signal_level); v17_tx_set_modem_status_handler(tx, v17_tx_status, (void *) tx); #if defined(WITH_SPANDSP_INTERNALS) @@ -429,11 +449,11 @@ int main(int argc, char *argv[]) } rx = v17_rx_init(NULL, test_bps, v17putbit, NULL); - v17_rx_set_modem_status_handler(rx, v17_rx_status, (void *) rx); - v17_rx_set_qam_report_handler(rx, qam_report, (void *) rx); logging = v17_rx_get_logging_state(rx); span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); - span_log_set_tag(logging, "V.17 rx"); + span_log_set_tag(logging, "V.17-rx"); + v17_rx_set_modem_status_handler(rx, v17_rx_status, (void *) rx); + v17_rx_set_qam_report_handler(rx, qam_report, (void *) rx); #if defined(ENABLE_GUI) if (use_gui) @@ -550,7 +570,7 @@ int main(int argc, char *argv[]) #endif if (decode_test_file) { - if (sf_close(inhandle)) + if (sf_close_telephony(inhandle)) { fprintf(stderr, " Cannot close audio file '%s'\n", decode_test_file); exit(2); @@ -558,7 +578,7 @@ int main(int argc, char *argv[]) } if (log_audio) { - if (sf_close(outhandle)) + if (sf_close_telephony(outhandle)) { fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME); exit(2); diff --git a/libs/spandsp/tests/v22bis_tests.c b/libs/spandsp/tests/v22bis_tests.c index f1527a4c91..f7d7ef7703 100644 --- a/libs/spandsp/tests/v22bis_tests.c +++ b/libs/spandsp/tests/v22bis_tests.c @@ -109,33 +109,50 @@ static void reporter(void *user_data, int reason, bert_results_t *results) } /*- End of function --------------------------------------------------------*/ +static void v22bis_rx_status(void *user_data, int status) +{ + endpoint_t *s; + int bit_rate; + int i; + int len; +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t *coeffs; +#else + complexf_t *coeffs; +#endif + + /* Special conditions */ + s = (endpoint_t *) user_data; + printf("V.22bis rx %p status is %s (%d)\n", user_data, signal_status_to_str(status), status); + switch (status) + { + case SIG_STATUS_TRAINING_SUCCEEDED: + bit_rate = v22bis_get_current_bit_rate(s->v22bis); + printf("Negotiated bit rate: %d\n", bit_rate); + len = v22bis_rx_equalizer_state(s->v22bis, &coeffs); + printf("Equalizer:\n"); + for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINTx) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/1024.0f, coeffs[i].im/1024.0f); +#else + printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif + break; + } +} +/*- End of function --------------------------------------------------------*/ + static void v22bis_putbit(void *user_data, int bit) { endpoint_t *s; - int i; - int len; - int bit_rate; - complexf_t *coeffs; - - s = (endpoint_t *) user_data; + if (bit < 0) { - /* Special conditions */ - printf("V.22bis rx %p status is %s (%d)\n", user_data, signal_status_to_str(bit), bit); - switch (bit) - { - case SIG_STATUS_TRAINING_SUCCEEDED: - bit_rate = v22bis_get_current_bit_rate(s->v22bis); - printf("Negotiated bit rate: %d\n", bit_rate); - len = v22bis_rx_equalizer_state(s->v22bis, &coeffs); - printf("Equalizer:\n"); - for (i = 0; i < len; i++) - printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); - break; - } + v22bis_rx_status(user_data, bit); return; } + s = (endpoint_t *) user_data; if (decode_test_file) printf("Rx bit %p-%d - %d\n", user_data, rx_bits++, bit); else @@ -154,11 +171,20 @@ static int v22bis_getbit(void *user_data) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static void qam_report(void *user_data, const complexi16_t *constel, const complexi16_t *target, int symbol) +#else static void qam_report(void *user_data, const complexf_t *constel, const complexf_t *target, int symbol) +#endif { int i; int len; +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t *coeffs; + complexf_t constel_point; +#else complexf_t *coeffs; +#endif float fpower; endpoint_t *s; @@ -195,10 +221,18 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex len = v22bis_rx_equalizer_state(s->v22bis, &coeffs); printf("Equalizer A:\n"); for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINTx) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/1024.0f, coeffs[i].im/1024.0f); +#else printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif #if defined(ENABLE_GUI) if (use_gui) +#if defined(SPANDSP_USE_FIXED_POINTx) + qam_monitor_update_int_equalizer(s->qam_monitor, coeffs, len); +#else qam_monitor_update_equalizer(s->qam_monitor, coeffs, len); +#endif #endif } } diff --git a/libs/spandsp/tests/v27ter_tests.c b/libs/spandsp/tests/v27ter_tests.c index 25ead86f01..cd05b13738 100644 --- a/libs/spandsp/tests/v27ter_tests.c +++ b/libs/spandsp/tests/v27ter_tests.c @@ -115,7 +115,30 @@ static void reporter(void *user_data, int reason, bert_results_t *results) static void v27ter_rx_status(void *user_data, int status) { + v27ter_rx_state_t *s; + int i; + int len; +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t *coeffs; +#else + complexf_t *coeffs; +#endif + printf("V.27ter rx status is %s (%d)\n", signal_status_to_str(status), status); + s = (v27ter_rx_state_t *) user_data; + switch (status) + { + case SIG_STATUS_TRAINING_SUCCEEDED: + len = v27ter_rx_equalizer_state(s, &coeffs); + printf("Equalizer:\n"); + for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINTx) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f); +#else + printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif + break; + } } /*- End of function --------------------------------------------------------*/ @@ -126,6 +149,7 @@ static void v27terputbit(void *user_data, int bit) v27ter_rx_status(user_data, bit); return; } + if (decode_test_file) printf("Rx bit %d - %d\n", rx_bits++, bit); else @@ -145,11 +169,20 @@ static int v27tergetbit(void *user_data) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static void qam_report(void *user_data, const complexi16_t *constel, const complexi16_t *target, int symbol) +#else static void qam_report(void *user_data, const complexf_t *constel, const complexf_t *target, int symbol) +#endif { int i; int len; +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t *coeffs; + complexf_t constel_point; +#else complexf_t *coeffs; +#endif float fpower; float error; v27ter_rx_state_t *rx; @@ -189,7 +222,11 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex len = v27ter_rx_equalizer_state(rx, &coeffs); printf("Equalizer B:\n"); for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINTx) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/1024.0f, coeffs[i].im/1024.0f); +#else printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif #if defined(WITH_SPANDSP_INTERNALS) printf("Gardtest %d %f %d\n", symbol_no, v27ter_rx_symbol_timing_correction(rx), rx->gardner_integrate); #endif @@ -199,7 +236,11 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex { if (++reports >= 1000) { +#if defined(SPANDSP_USE_FIXED_POINTx) + qam_monitor_update_int_equalizer(qam_monitor, coeffs, len); +#else qam_monitor_update_equalizer(qam_monitor, coeffs, len); +#endif reports = 0; } } @@ -212,10 +253,18 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex len = v27ter_rx_equalizer_state(rx, &coeffs); printf("Equalizer A:\n"); for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINTx) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/1024.0f, coeffs[i].im/1024.0f); +#else printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif #if defined(ENABLE_GUI) if (use_gui) +#if defined(SPANDSP_USE_FIXED_POINTx) + qam_monitor_update_int_equalizer(qam_monitor, coeffs, len); +#else qam_monitor_update_equalizer(qam_monitor, coeffs, len); +#endif #endif } } @@ -397,6 +446,9 @@ int main(int argc, char *argv[]) { /* We will generate V.27ter audio, and add some noise to it. */ tx = v27ter_tx_init(NULL, test_bps, tep, v27tergetbit, NULL); + logging = v27ter_tx_get_logging_state(tx); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "V.27ter-tx"); v27ter_tx_power(tx, signal_level); v27ter_tx_set_modem_status_handler(tx, v27ter_tx_status, (void *) tx); /* Move the carrier off a bit */ @@ -414,11 +466,11 @@ int main(int argc, char *argv[]) } rx = v27ter_rx_init(NULL, test_bps, v27terputbit, NULL); - v27ter_rx_set_modem_status_handler(rx, v27ter_rx_status, (void *) rx); - v27ter_rx_set_qam_report_handler(rx, qam_report, (void *) rx); logging = v27ter_rx_get_logging_state(rx); span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); span_log_set_tag(logging, "V.27ter-rx"); + v27ter_rx_set_modem_status_handler(rx, v27ter_rx_status, (void *) rx); + v27ter_rx_set_qam_report_handler(rx, qam_report, (void *) rx); #if defined(ENABLE_GUI) if (use_gui) diff --git a/libs/spandsp/tests/v29_tests.c b/libs/spandsp/tests/v29_tests.c index c32bca6340..4b3b3858dc 100644 --- a/libs/spandsp/tests/v29_tests.c +++ b/libs/spandsp/tests/v29_tests.c @@ -114,7 +114,7 @@ static void reporter(void *user_data, int reason, bert_results_t *results) static void v29_rx_status(void *user_data, int status) { - v29_rx_state_t *rx; + v29_rx_state_t *s; int i; int len; #if defined(SPANDSP_USE_FIXED_POINT) @@ -124,20 +124,17 @@ static void v29_rx_status(void *user_data, int status) #endif printf("V.29 rx status is %s (%d)\n", signal_status_to_str(status), status); - rx = (v29_rx_state_t *) user_data; + s = (v29_rx_state_t *) user_data; switch (status) { case SIG_STATUS_TRAINING_SUCCEEDED: printf("Training succeeded\n"); -#if defined(SPANDSP_USE_FIXED_POINT) - len = v29_rx_equalizer_state(rx, &coeffs); + len = v29_rx_equalizer_state(s, &coeffs); printf("Equalizer:\n"); for (i = 0; i < len; i++) +#if defined(SPANDSP_USE_FIXED_POINT) printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f); #else - len = v29_rx_equalizer_state(rx, &coeffs); - printf("Equalizer:\n"); - for (i = 0; i < len; i++) printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); #endif break; @@ -147,15 +144,12 @@ static void v29_rx_status(void *user_data, int status) static void v29putbit(void *user_data, int bit) { - v29_rx_state_t *rx; - if (bit < 0) { v29_rx_status(user_data, bit); return; } - rx = (v29_rx_state_t *) user_data; if (decode_test_file) printf("Rx bit %d - %d\n", rx_bits++, bit); else @@ -175,12 +169,17 @@ static int v29getbit(void *user_data) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static void qam_report(void *user_data, const complexi16_t *constel, const complexi16_t *target, int symbol) +#else static void qam_report(void *user_data, const complexf_t *constel, const complexf_t *target, int symbol) +#endif { int i; int len; #if defined(SPANDSP_USE_FIXED_POINT) complexi16_t *coeffs; + complexf_t constel_point; #else complexf_t *coeffs; #endif @@ -194,11 +193,20 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex { fpower = (constel->re - target->re)*(constel->re - target->re) + (constel->im - target->im)*(constel->im - target->im); +#if defined(SPANDSP_USE_FIXED_POINT) + fpower /= 4096.0*4096.0; +#endif smooth_power = 0.95f*smooth_power + 0.05f*fpower; #if defined(ENABLE_GUI) if (use_gui) { +#if defined(SPANDSP_USE_FIXED_POINTx) + constel_point.re = constel->re/4096.0; + constel_point.im = constel->im/4096.0; + qam_monitor_update_constel(qam_monitor, &constel_point); +#else qam_monitor_update_constel(qam_monitor, constel); +#endif qam_monitor_update_carrier_tracking(qam_monitor, v29_rx_carrier_frequency(rx)); //qam_monitor_update_carrier_tracking(qam_monitor, (fpower) ? fpower : 0.001f); qam_monitor_update_symbol_tracking(qam_monitor, v29_rx_symbol_timing_correction(rx)); @@ -206,10 +214,17 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex #endif printf("%8d [%8.4f, %8.4f] [%8.4f, %8.4f] %2x %8.4f %8.4f %9.4f %7.3f %7.4f\n", symbol_no, +#if defined(SPANDSP_USE_FIXED_POINTx) + constel->re/4096.0, + constel->im/4096.0, + target->re/4096.0, + target->im/4096.0, +#else constel->re, constel->im, target->re, target->im, +#endif symbol, fpower, smooth_power, @@ -219,22 +234,19 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex symbol_no++; if (--update_interval <= 0) { + len = v29_rx_equalizer_state(rx, &coeffs); + printf("Equalizer A:\n"); + for (i = 0; i < len; i++) #if defined(SPANDSP_USE_FIXED_POINT) - len = v29_rx_equalizer_state(rx, &coeffs); - printf("Equalizer A:\n"); - for (i = 0; i < len; i++) printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f); -#if defined(ENABLE_GUI) - if (use_gui) - qam_monitor_update_int_equalizer(qam_monitor, coeffs, len); -#endif #else - len = v29_rx_equalizer_state(rx, &coeffs); - printf("Equalizer A:\n"); - for (i = 0; i < len; i++) printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); +#endif #if defined(ENABLE_GUI) if (use_gui) +#if defined(SPANDSP_USE_FIXED_POINT) + qam_monitor_update_int_equalizer(qam_monitor, coeffs, len); +#else qam_monitor_update_equalizer(qam_monitor, coeffs, len); #endif #endif @@ -420,6 +432,9 @@ int main(int argc, char *argv[]) { /* We will generate V.29 audio, and add some noise to it. */ tx = v29_tx_init(NULL, test_bps, tep, v29getbit, NULL); + logging = v29_tx_get_logging_state(tx); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "V.29-tx"); v29_tx_power(tx, signal_level); v29_tx_set_modem_status_handler(tx, v29_tx_status, (void *) tx); #if defined(WITH_SPANDSP_INTERNALS) @@ -439,6 +454,9 @@ int main(int argc, char *argv[]) } rx = v29_rx_init(NULL, test_bps, v29putbit, NULL); + logging = v29_rx_get_logging_state(rx); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "V.29-rx"); v29_rx_signal_cutoff(rx, -45.5f); v29_rx_set_modem_status_handler(rx, v29_rx_status, (void *) rx); v29_rx_set_qam_report_handler(rx, qam_report, (void *) rx); @@ -446,9 +464,6 @@ int main(int argc, char *argv[]) /* Rotate the starting phase */ rx->carrier_phase = 0x80000000; #endif - logging = v29_rx_get_logging_state(rx); - span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); - span_log_set_tag(logging, "V.29-rx"); #if defined(ENABLE_GUI) if (use_gui) diff --git a/libs/spandsp/tests/v42_tests.c b/libs/spandsp/tests/v42_tests.c index a8e7259d63..c485fd17bb 100644 --- a/libs/spandsp/tests/v42_tests.c +++ b/libs/spandsp/tests/v42_tests.c @@ -66,7 +66,7 @@ static void v42_status(void *user_data, int status) } /*- End of function --------------------------------------------------------*/ -static int v42_get_frames(void *user_data, uint8_t *msg, int len) +static int v42_get_frames(void *user_data, uint8_t msg[], int len) { int i; int j; @@ -98,7 +98,7 @@ static int v42_get_frames(void *user_data, uint8_t *msg, int len) } /*- End of function --------------------------------------------------------*/ -static void v42_put_frames(void *user_data, const uint8_t *msg, int len) +static void v42_put_frames(void *user_data, const uint8_t msg[], int len) { int i; v42_state_t *s; diff --git a/libs/spandsp/tests/v42bis_tests.c b/libs/spandsp/tests/v42bis_tests.c index e59d80711b..3c97adc81c 100644 --- a/libs/spandsp/tests/v42bis_tests.c +++ b/libs/spandsp/tests/v42bis_tests.c @@ -155,7 +155,7 @@ int main(int argc, char *argv[]) time(&now); v42bis_init(&state_a, 3, 512, 6, frame_handler, (void *) (intptr_t) v42bis_fd, 512, data_handler, NULL, 512); span_log_set_level(&state_a.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); - span_log_set_tag(&state_a.logging, "XXX"); + span_log_set_tag(&state_a.logging, "V.42bis"); //v42bis_compression_control(&state_a, V42BIS_COMPRESSION_MODE_ALWAYS); in_octets_to_date = 0; out_octets_to_date = 0; @@ -206,7 +206,7 @@ int main(int argc, char *argv[]) time(&now); v42bis_init(&state_b, 3, 512, 6, frame_handler, (void *) (intptr_t) v42bis_fd, 512, data_handler, (void *) (intptr_t) out_fd, 512); span_log_set_level(&state_b.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); - span_log_set_tag(&state_b.logging, "XXX"); + span_log_set_tag(&state_b.logging, "V.42bis"); in_octets_to_date = 0; out_octets_to_date = 0; while ((len = read(v42bis_fd, buf, 1024)) > 0) diff --git a/libs/spandsp/tests/v8_tests.c b/libs/spandsp/tests/v8_tests.c index 35f1eb20e5..4c48143099 100644 --- a/libs/spandsp/tests/v8_tests.c +++ b/libs/spandsp/tests/v8_tests.c @@ -90,7 +90,6 @@ static void handler(void *user_data, v8_parms_t *result) case V8_STATUS_IN_PROGRESS: printf("V.8 negotiation in progress\n"); return; - break; case V8_STATUS_V8_OFFERED: printf("V.8 offered by the other party\n"); break;