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 \
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 \
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
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
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
int16_t amp[16384];
int len;
SNDFILE *outhandle;
- int outframes;
int add_digits;
if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
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))
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))
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:
int i;
int idum = 1234567;
int16_t dirty;
- int16_t clean;
int estimate;
int min;
int max;
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",
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;
int16_t amp[16384];
int len;
SNDFILE *outhandle;
- int outframes;
int add_digits;
if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
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");
}
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");
}
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");
}
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");
}
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))
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");
}
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");
}
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");
}
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");
}
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");
}
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");
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");
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))
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];
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];
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];
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];
int16_t rout;
int16_t sin;
int16_t sout;
- int32_t samples;
mode |= ECHO_CAN_USE_ADAPTION;
txfile = NULL;
ctx = echo_can_init(TEST_EC_TAPS, 0);
echo_can_adaption_mode(ctx, mode);
- samples = 0;
do
{
if (two_channel_file)
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:
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;
}
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;
}
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;
}
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;
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;
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,
/*! \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 <stdlib.h>
#include <inttypes.h>
#include <stdio.h>
#include <unistd.h>
#endif
+#if defined(HAVE_LIBXML_XMLMEMORY_H)
+#include <libxml/xmlmemory.h>
+#endif
+#if defined(HAVE_LIBXML_PARSER_H)
+#include <libxml/parser.h>
+#endif
+#if defined(HAVE_LIBXML_XINCLUDE_H)
+#include <libxml/xinclude.h>
+#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"
+enum
+{
+ AUDIO_FAX,
+ T38_TERMINAL_FAX,
+ T38_GATEWAY_FAX
+};
-#define FAX_MACHINES 2
+int mode[2] = {AUDIO_FAX, AUDIO_FAX};
-struct machine_s
-{
- 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];
+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 --------------------------------------------------------*/
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);
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
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:
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 --------------------------------------------------------*/
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);
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 --------------------------------------------------------*/
-int main(int argc, char *argv[])
+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)
{
- SNDFILE *wave_handle;
- SNDFILE *input_wave_handle;
int i;
- int j;
- int k;
- struct machine_s *mc;
- int outframes;
- char buf[128 + 1];
+
+ 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 out_amp[2*SAMPLES_PER_CHUNK];
- int alldone;
- const char *input_tiff_file_name;
- const char *input_audio_file_name;
+ 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 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;
input_tiff_file_name = optarg;
break;
case 'I':
- input_audio_file_name = optarg;
+ t38_simulate_incrementing_repeats = TRUE;
break;
case 'l':
log_audio = TRUE;
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;
- break;
- case 'r':
- reverse_flow = 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':
- 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;
use_tep = TRUE;
break;
case 'T':
- use_page_limits = TRUE;
+ start_page = 0;
+ end_page = atoi(optarg);
+ break;
+ 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 'w':
- t30_state_to_wreck = atoi(optarg);
+ case 'v':
+ t38_version = atoi(optarg);
break;
case 'z':
page_header_tz = optarg;
}
}
- 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)
+ {
+ }
+ else
+ {
+ if (decode_file_name)
+ {
+ 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);
+ }
+ }
+ }
+
+ for (i = 0; i < 2; i++)
{
- machines[j].chan = j;
- mc = &machines[j];
+ 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);
- 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);
+ 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
- mc->fax = fax_init(NULL, (mc->chan & 1) ? FALSE : TRUE);
- mc->awgn = NULL;
- signal_scaling = 1.0f;
- if (noise_level > -99)
- {
- 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);
- }
- 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);
+ {
+ 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
| 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)
- {
- 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);
- }
+ 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);
}
- else
+ if (mode[i] != AUDIO_FAX)
{
- 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);
- }
+ t38_set_t38_version(t38_core_state[i], t38_version);
}
- 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))
+ if (mode[i] == T38_TERMINAL_FAX)
{
- 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);
+ //t30_set_iaf_mode(t30_state[i], T30_IAF_MODE_NO_FILL_BITS);
+ switch (t38_transport)
+ {
+ 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
{
- 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);
+ fax_set_transmit_on_idle(fax_state[i], use_transmit_on_idle);
+ fax_set_tep_mode(fax_state[i], use_tep);
}
- 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++)
+ memset(out_amp, 0, sizeof(out_amp));
+
+ for (i = 0; i < 2; i++)
{
- mc = &machines[j];
+ /* Update T.30 timing */
+ logging = t30_get_logging_state(t30_state[i]);
+ span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
- if ((j & 1) == 0 && input_audio_file_name)
+ 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)
+ /* Update audio FAX timing */
+ logging = fax_get_logging_state(fax_state[i]);
+ span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
+
+ fax_rx(fax_state[i], fax_rx_buf[i], SAMPLES_PER_CHUNK);
+ if (!t30_call_active(t30_state[i]))
{
- for (k = 0; k < mc->len; k++)
- mc->amp[k] = ((int16_t) (mc->amp[k]*signal_scaling)) + awgn(mc->awgn);
+ completed[i] = TRUE;
+ continue;
}
- }
- 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)
+
+ if (i == 0 && input_wave_handle)
{
- memset(mc->amp + mc->len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - mc->len));
- mc->len = SAMPLES_PER_CHUNK;
+ 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)
+ {
+ /* 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 (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);
}
- }
- 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);
- 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)
+ if (mode[i] == T38_GATEWAY_FAX)
{
- if (++mc->error_delay == 100)
+ /* 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)
{
- fprintf(stderr, "HIT %d!\n", j);
- mc->error_delay = 0;
- for (k = 0; k < 5; k++)
- mc->amp[k] = 0;
+ for (j = 0; j < t38_len[i]; j++)
+ out_amp[4*j + 2*i + 1] = t38_amp[i][j];
}
- }
+ }
}
- if (t30->state == t30_state_to_wreck)
- memset(machines[j ^ 1].amp, 0, sizeof(int16_t)*SAMPLES_PER_CHUNK);
+ 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
- if (fax_rx(mc->fax, machines[j ^ 1].amp, SAMPLES_PER_CHUNK))
- break;
- if (!mc->done)
- alldone = FALSE;
+ 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);
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 (log_audio)
+ if (input_wave_handle)
{
- if (sf_close(wave_handle))
+ if (sf_close_telephony(input_wave_handle))
{
- fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE);
+ fprintf(stderr, " Cannot close audio file '%s'\n", decode_file_name);
exit(2);
}
}
- if (input_audio_file_name)
+ if (log_audio)
{
- if (sf_close(input_wave_handle))
+ if (sf_close_telephony(wave_handle))
{
- fprintf(stderr, " Cannot close audio file '%s'\n", input_audio_file_name);
+ fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
exit(2);
}
}
- printf("Total audio time = %ds (wall time %ds)\n", machines[0].total_audio_time/8000, (int) (end_time - start_time));
+
+ /* 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 (!phase_e_reached[i])
+ break;
+ if (!succeeded[i])
+ break;
+ t30_get_transfer_statistics(t30_state[i], &t30_stats);
+ if (i & 1)
+ {
+ 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]);
+ }
+ if (i < 2)
+ {
+ printf("Tests failed\n");
+ exit(2);
+ }
+ printf("Tests passed\n");
return 0;
}
/*- End of function --------------------------------------------------------*/
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
}
/*- 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 --------------------------------------------------------*/
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);
int num_packets;
int model_no;
int speed_pattern_no;
- int use_gui;
int simulation_time;
int i;
int len;
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)
int j;
int k;
int len_comp;
+ int len_comp_lower;
int len_comp_upper;
int len_data;
int len;
/* 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++)
/* 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++)
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);
int len3;
int i;
int test;
- int bits_per_code;
int bad_samples;
int conditioning_samples;
int samples;
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 */
SNDFILE *outhandle;
int16_t amp[1024];
int frames;
- int outframes;
int adpcm;
int packing;
{
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))
{
SNDFILE *inhandle;
SNDFILE *outhandle;
int frames;
- int outframes;
int bytes;
int16_t pre_amp[HIST_LEN];
int16_t post_amp[HIST_LEN];
{
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))
SNDFILE *outhandle;
int frames;
int dec_frames;
- int outframes;
int ima_bytes;
double pre_energy;
double post_energy;
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))
{
{
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;
SNDFILE *refhandle;
SNDFILE *outhandle;
int frames;
- int outframes;
double pre_energy;
double post_energy;
double ref_energy;
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
}
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))
{
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;
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)
SNDFILE *outhandle;
int frames;
int dec_frames;
- int outframes;
int oki_bytes;
int bit_rate;
double pre_energy;
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);
}
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);
#endif
#include <string.h>
-#include <pcap.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <time.h>
{
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;
int total_pkts;
uint32_t pktlen;
ether_hdr *ethhdr;
+ linux_sll_hdr *sllhdr;
null_hdr *nullhdr;
struct iphdr *iphdr;
#if !defined(__CYGWIN__)
}
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)
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__)
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
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,
int16_t amp[1000];
int len;
SNDFILE *outhandle;
- int outframes;
int digit;
const char *digits = "0123456789BCDEF";
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);
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))
#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
fi
echo t31_tests completed OK
-./t38_core_tests >$STDOUT_DEST 2>$STDERR_DEST
-RETVAL=$?
-if [ $RETVAL != 0 ]
-then
- echo t38_core_tests failed!
- exit $RETVAL
-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
+./t35_tests -s >$STDOUT_DEST 2>$STDERR_DEST
RETVAL=$?
if [ $RETVAL != 0 ]
then
- echo t38_gateway_tests failed!
+ echo t35_tests -s 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
+echo t35_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
+./t38_core_tests >$STDOUT_DEST 2>$STDERR_DEST
RETVAL=$?
if [ $RETVAL != 0 ]
then
- echo t38_gateway_to_terminal_tests -e failed!
+ echo t38_core_tests failed!
exit $RETVAL
fi
-echo t38_gateway_to_terminal_tests completed OK
+echo t38_core_tests completed OK
./t38_non_ecm_buffer_tests >$STDOUT_DEST 2>$STDERR_DEST
RETVAL=$?
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=$?
# 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=$?
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
#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=$?
int num_packets;
int model_no;
int speed_pattern_no;
- int use_gui;
int simulation_time;
int i;
int len;
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)
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)
{
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)
{
}
/*- 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)
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;
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];
}
/*- 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;
#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);
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[] =
{
EXCHANGE("AT+FTH=3\r", "\r\nCONNECT\r\n"),
// <DCN frame data>
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[] =
//<DCN frame data>
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[] =
EXCHANGE("\x10\x03", "\xFF\x13\x8C\xA2\xF1\x10\x03"),
//<DCN frame>
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[] =
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<ctrl>\x10<p224>\x10<C12>"),
- 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[] =
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<ctrl>\x10<p224>\x10<C12>"),
- 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[] =
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;
int kick = FALSE;
int dled = FALSE;
int done = FALSE;
+int sequence_terminated = FALSE;
static const struct command_response_s *fax_test_seq;
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;
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);
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;
{
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)
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++)
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++)
}
/*- 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;
t38_core_state_t *t38_core;
logging_state_t *logging;
int i;
+ int k;
+ int outframes;
+ 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];
+ SNDFILE *wave_handle;
+ SNDFILE *in_handle;
+ /* 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;
- srand48(0x1234567);
- if ((path_a_to_b = g1050_init(model_no, speed_pattern_no, 100, 33)) == NULL)
+ wave_handle = NULL;
+ if (log_audio)
{
- fprintf(stderr, "Failed to start IP network path model\n");
- exit(2);
+ if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
+ {
+ fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
+ exit(2);
+ }
}
- if ((path_b_to_a = g1050_init(model_no, speed_pattern_no, 100, 33)) == NULL)
+
+ in_handle = NULL;
+ if (decode_test_file)
+ {
+ if ((in_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
+ {
+ fprintf(stderr, " Cannot create 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 ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, t31_tx_packet_handler, NULL)) == NULL)
+ if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
{
- fprintf(stderr, " Cannot start the T.31 T.38 modem\n");
+ 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_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);
+ t38_state = NULL;
+ fax_state = NULL;
if (test_sending)
{
- if ((t38_state = t38_terminal_init(NULL, FALSE, t38_tx_packet_handler, t31_state)) == NULL)
+ if (t38_mode)
{
- fprintf(stderr, "Cannot start the T.38 channel\n");
- exit(2);
+ 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 = 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)
+ if (t38_mode)
{
- fprintf(stderr, "Cannot start the T.38 channel\n");
- exit(2);
+ 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 = 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);
+ 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_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);
+ 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, "T.38");
+ 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");
+ }
- 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");
+ memset(silence, 0, sizeof(silence));
+ memset(t30_amp, 0, sizeof(t30_amp));
- logging = t30_get_logging_state(t30);
+ /* 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.38");
+ 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;
#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 (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)
{
/* 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)
+ /* Create a chunk of white page, 1728 pixels wide. */
+ 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;
}
}
else
{
- /* Create a chunk of white page */
- for (i = 0; i < 36; i += 4)
+ /* Create the end of page condition. */
+ for (i = 0; i < 36; i += 3)
{
fast_buf[i] = 0x00;
- fast_buf[i + 1] = 0x80;
- fast_buf[i + 2] = 0xB2;
- fast_buf[i + 3] = 0x01;
+ 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;
}
}
- 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 (t38_mode)
{
- 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;
- }
- }
- 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);
+ 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)
- {
+ 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_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();
+ media_monitor_update_display();
#endif
- }
- t38_terminal_release(t38_state);
- return 0;
-}
-/*- End of function --------------------------------------------------------*/
+ /* Bump the G.1050 models along */
+ when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;
-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;
-
- wave_handle = NULL;
- if (log_audio)
- {
- if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
- {
- fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
- exit(2);
- }
- }
+ /* 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);
- memset(silence, 0, sizeof(silence));
-
- in_handle = NULL;
- if (decode_test_file)
- {
- if ((in_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
- {
- fprintf(stderr, " Cannot create audio file '%s'\n", decode_test_file);
- exit(2);
+ t38_terminal_send_timeout(t38_state, SAMPLES_PER_CHUNK);
+ t31_t38_send_timeout(t31_state, SAMPLES_PER_CHUNK);
}
- }
-
- if ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, NULL, NULL)) == NULL)
- {
- fprintf(stderr, " Cannot start the T.31 FAX 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 (test_sending)
- {
- 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);
- t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1);
- fax_test_seq = fax_receive_test_seq;
- countdown = 250;
- }
-
- t30_set_tx_ident(t30, "11111111");
- t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
- 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);
- span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
- span_log_set_tag(logging, "FAX");
-
- fast_send = FALSE;
- fast_send_tcf = TRUE;
- fast_blocks = 0;
- kick = TRUE;
- while (!done)
- {
- 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)
+ else
{
- /* Send fast modem data */
- if (fast_send_tcf)
+ 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(fast_buf, 0, 36);
+ memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len));
+ t30_len = SAMPLES_PER_CHUNK;
}
- else
+ if (log_audio)
{
- 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;
- }
- }
+ for (k = 0; k < t30_len; k++)
+ out_amp[2*k] = t30_amp[k];
}
- if (fast_blocks == 1)
+ 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)
{
- /* 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;
+ memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len));
+ t31_len = SAMPLES_PER_CHUNK;
}
- 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)
- {
- 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)
+ if (log_audio)
{
- countdown = 0;
- t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED);
+ for (k = 0; k < t31_len; k++)
+ out_amp[2*k + 1] = t31_amp[k];
}
- else if (--countdown == 0)
+ if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK))
+ break;
+
+ if (log_audio)
{
- t31_call_event(t31_state, AT_CALL_EVENT_ALERTING);
- countdown = 250;
+ outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
+ if (outframes != SAMPLES_PER_CHUNK)
+ 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;
+ /* Bump things along on the FAX machine side */
+ span_log_bump_samples(fax_get_logging_state(fax_state), 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;
- 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);
+ /* Bump things along on the FAX machine side */
+ span_log_bump_samples(t30_get_logging_state(t30), SAMPLES_PER_CHUNK);
- 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 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))
exit(2);
}
}
+
+ if (!done || !sequence_terminated)
+ {
+ printf("Tests failed\n");
+ return 2;
+ }
+
return 0;
}
/*- End of function --------------------------------------------------------*/
int t38_mode;
int test_sending;
int use_gui;
+ int g1050_model_no;
+ int g1050_speed_pattern_no;
int opt;
decode_test_file = NULL;
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)
{
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;
}
}
- 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 --------------------------------------------------------*/
--- /dev/null
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * t35_tests.c - Tests for T.35.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <sndfile.h>
+
+//#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 ------------------------------------------------------------*/
#include <string.h>
#include <assert.h>
#include <errno.h>
+#if !defined(_WIN32)
+#include <unistd.h>
+#endif
//#if defined(WITH_SPANDSP_INTERNALS)
#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
#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;
+
+static int skip;
+
+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 --------------------------------------------------------*/
-int current_indicator;
-int current_data_type;
-int current_field_type;
-int skip;
+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 --------------------------------------------------------*/
-uint8_t field_body[MAX_FIELDS][MAX_FIELD_LEN];
-int field_len[MAX_FIELDS];
+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)
{
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++;
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;
}
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);
}
/*- 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];
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;
+ }
+
+ 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 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++)
{
- 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 */
{
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;
{
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)
{
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;
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)
}
/*- End of function --------------------------------------------------------*/
-static int attack_tests(t38_core_state_t *s)
+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 --------------------------------------------------------*/
{
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,
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");
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;
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);
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");
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))
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);
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);
+++ /dev/null
-/*
- * SpanDSP - a series of DSP components for telephony
- *
- * t38_gateway_tests.c - Tests for the T.38 FoIP gateway module.
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <sndfile.h>
-#if !defined(_WIN32)
-#include <unistd.h>
-#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 ------------------------------------------------------------*/
+++ /dev/null
-/*
- * 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 <steveu@coppice.org>
- *
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <sndfile.h>
-#if !defined(_WIN32)
-#include <unistd.h>
-#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 ------------------------------------------------------------*/
+++ /dev/null
-/*
- * SpanDSP - a series of DSP components for telephony
- *
- * t38_terminal_tests.c - Tests for the T.38 FoIP terminal module.
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#if !defined(_WIN32)
-#include <unistd.h>
-#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 ------------------------------------------------------------*/
+++ /dev/null
-/*
- * 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 <steveu@coppice.org>
- *
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <sndfile.h>
-#if !defined(_WIN32)
-#include <unistd.h>
-#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 ------------------------------------------------------------*/
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;
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;
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");
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)
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)))
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;
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)
int16_t amp[16384];
int len;
SNDFILE *outhandle;
- int outframes;
if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
{
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);
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);
}
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;
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;
}
}
}
/*- 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;
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;
}
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)
}
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)
#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);
}
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);
}
/*- End of function --------------------------------------------------------*/
-static void v22bis_putbit(void *user_data, int bit)
+static void v22bis_rx_status(void *user_data, int status)
{
endpoint_t *s;
+ int bit_rate;
int i;
int len;
- int bit_rate;
+#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;
+
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
}
/*- 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;
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
}
}
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 --------------------------------------------------------*/
v27ter_rx_status(user_data, bit);
return;
}
+
if (decode_test_file)
printf("Rx bit %d - %d\n", rx_bits++, bit);
else
}
/*- 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;
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
{
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;
}
}
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
}
}
{
/* 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 */
}
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)
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)
#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;
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
}
/*- 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
{
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));
#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,
symbol_no++;
if (--update_interval <= 0)
{
-#if defined(SPANDSP_USE_FIXED_POINT)
len = v29_rx_equalizer_state(rx, &coeffs);
printf("Equalizer A:\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);
-#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
{
/* 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)
}
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);
/* 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)
}
/*- 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;
}
/*- 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;
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;
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)
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;