|
|
|
@ -196,43 +196,31 @@ static void non_ecm_remove_fill_and_put_bit(void *user_data, int bit);
|
|
|
|
|
static void non_ecm_push_residue(t38_gateway_state_t *s);
|
|
|
|
|
static void tone_detected(void *user_data, int tone, int level, int delay);
|
|
|
|
|
|
|
|
|
|
static void set_rx_handler(t38_gateway_state_t *s,
|
|
|
|
|
static void set_rx_handler(fax_modems_state_t *s,
|
|
|
|
|
span_rx_handler_t handler,
|
|
|
|
|
void *user_data,
|
|
|
|
|
span_rx_fillin_handler_t fillin_handler,
|
|
|
|
|
void *rx_fillin_user_data)
|
|
|
|
|
void *fillin_user_data)
|
|
|
|
|
{
|
|
|
|
|
if (s->audio.modems.rx_handler != span_dummy_rx)
|
|
|
|
|
{
|
|
|
|
|
s->audio.modems.rx_handler = handler;
|
|
|
|
|
s->audio.modems.rx_fillin_handler = fillin_handler;
|
|
|
|
|
}
|
|
|
|
|
/* Only update the actual handlers if they are not currently sidelined to dummy targets */
|
|
|
|
|
if (s->rx_handler != span_dummy_rx)
|
|
|
|
|
s->rx_handler = handler;
|
|
|
|
|
/*endif*/
|
|
|
|
|
s->audio.base_rx_handler = handler;
|
|
|
|
|
s->audio.base_rx_fillin_handler = fillin_handler;
|
|
|
|
|
s->audio.modems.rx_user_data = user_data;
|
|
|
|
|
s->audio.modems.rx_fillin_user_data = rx_fillin_user_data;
|
|
|
|
|
}
|
|
|
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
|
s->base_rx_handler = handler;
|
|
|
|
|
s->rx_user_data = user_data;
|
|
|
|
|
|
|
|
|
|
static void set_tx_handler(t38_gateway_state_t *s, span_tx_handler_t handler, void *user_data)
|
|
|
|
|
{
|
|
|
|
|
s->audio.modems.tx_handler = handler;
|
|
|
|
|
s->audio.modems.tx_user_data = user_data;
|
|
|
|
|
}
|
|
|
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static void set_next_tx_handler(t38_gateway_state_t *s, span_tx_handler_t handler, void *user_data)
|
|
|
|
|
{
|
|
|
|
|
s->audio.modems.next_tx_handler = handler;
|
|
|
|
|
s->audio.modems.next_tx_user_data = user_data;
|
|
|
|
|
if (s->rx_fillin_handler != span_dummy_rx_fillin)
|
|
|
|
|
s->rx_fillin_handler = fillin_handler;
|
|
|
|
|
/*endif*/
|
|
|
|
|
s->base_rx_fillin_handler = fillin_handler;
|
|
|
|
|
s->rx_fillin_user_data = fillin_user_data;
|
|
|
|
|
}
|
|
|
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static void set_rx_active(t38_gateway_state_t *s, int active)
|
|
|
|
|
{
|
|
|
|
|
s->audio.modems.rx_handler = (active) ? s->audio.base_rx_handler : span_dummy_rx;
|
|
|
|
|
s->audio.modems.rx_fillin_handler = (active) ? s->audio.base_rx_fillin_handler : span_dummy_rx_fillin;
|
|
|
|
|
s->audio.modems.rx_handler = (active) ? s->audio.modems.base_rx_handler : span_dummy_rx;
|
|
|
|
|
s->audio.modems.rx_fillin_handler = (active) ? s->audio.modems.base_rx_fillin_handler : span_dummy_rx_fillin;
|
|
|
|
|
}
|
|
|
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
@ -259,18 +247,17 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
|
|
|
|
|
v17_rx(&s->fast_modems.v17_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->fast_modems.v17_rx));
|
|
|
|
|
set_rx_handler(t, (span_rx_handler_t) &v17_rx, &s->fast_modems.v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
|
|
|
|
|
/* The fast modem has trained, so we no longer need to run the slow one in parallel. */
|
|
|
|
|
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
|
|
|
|
|
set_rx_handler(s, (span_rx_handler_t) &v17_rx, &s->fast_modems.v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fsk_rx(&s->v21_rx, amp, len);
|
|
|
|
|
if (s->rx_signal_present)
|
|
|
|
|
{
|
|
|
|
|
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
|
|
|
|
|
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
|
|
|
|
|
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
|
|
|
|
|
set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
|
|
|
|
|
}
|
|
|
|
|
/*endif*/
|
|
|
|
|
}
|
|
|
|
@ -302,18 +289,17 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
|
|
|
|
|
v27ter_rx(&s->fast_modems.v27ter_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->fast_modems.v27ter_rx));
|
|
|
|
|
set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, &s->fast_modems.v27ter_rx);
|
|
|
|
|
/* The fast modem has trained, so we no longer need to run the slow one in parallel. */
|
|
|
|
|
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
|
|
|
|
|
set_rx_handler(s, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, &s->fast_modems.v27ter_rx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fsk_rx(&s->v21_rx, amp, len);
|
|
|
|
|
if (s->rx_signal_present)
|
|
|
|
|
{
|
|
|
|
|
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
|
|
|
|
|
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
|
|
|
|
|
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
|
|
|
|
|
set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
|
|
|
|
|
}
|
|
|
|
|
/*endif*/
|
|
|
|
|
}
|
|
|
|
@ -345,18 +331,17 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
|
|
|
|
|
v29_rx(&s->fast_modems.v29_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->fast_modems.v29_rx));
|
|
|
|
|
set_rx_handler(t, (span_rx_handler_t) &v29_rx, &s->fast_modems.v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
|
|
|
|
|
/* The fast modem has trained, so we no longer need to run the slow one in parallel. */
|
|
|
|
|
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
|
|
|
|
|
set_rx_handler(s, (span_rx_handler_t) &v29_rx, &s->fast_modems.v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fsk_rx(&s->v21_rx, amp, len);
|
|
|
|
|
if (s->rx_signal_present)
|
|
|
|
|
{
|
|
|
|
|
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
|
|
|
|
|
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
|
|
|
|
|
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
|
|
|
|
|
set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
|
|
|
|
|
}
|
|
|
|
|
/*endif*/
|
|
|
|
|
}
|
|
|
|
@ -434,8 +419,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
|
|
|
|
if (t->next_tx_handler)
|
|
|
|
|
{
|
|
|
|
|
/* There is a handler queued, so that is the next one. */
|
|
|
|
|
set_tx_handler(s, t->next_tx_handler, t->next_tx_user_data);
|
|
|
|
|
set_next_tx_handler(s, NULL, NULL);
|
|
|
|
|
fax_modems_set_tx_handler(t, t->next_tx_handler, t->next_tx_user_data);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, NULL, NULL);
|
|
|
|
|
if (t->tx_handler == (span_tx_handler_t) &silence_gen
|
|
|
|
|
||
|
|
|
|
|
t->tx_handler == (span_tx_handler_t) &tone_gen)
|
|
|
|
@ -485,23 +470,23 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
|
|
|
|
t->tx_bit_rate = 0;
|
|
|
|
|
/* Impose 75ms minimum on transmitted silence */
|
|
|
|
|
//silence_gen_set(&t->silence_gen, ms_to_samples(75));
|
|
|
|
|
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
|
|
|
|
|
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
|
|
|
|
|
set_rx_active(s, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
case T38_IND_CNG:
|
|
|
|
|
t->tx_bit_rate = 0;
|
|
|
|
|
modem_connect_tones_tx_init(&t->connect_tx, MODEM_CONNECT_TONES_FAX_CNG);
|
|
|
|
|
set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
|
|
|
|
|
fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
|
|
|
|
|
silence_gen_set(&t->silence_gen, 0);
|
|
|
|
|
set_next_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
set_rx_active(s, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
case T38_IND_CED:
|
|
|
|
|
t->tx_bit_rate = 0;
|
|
|
|
|
modem_connect_tones_tx_init(&t->connect_tx, MODEM_CONNECT_TONES_FAX_CED);
|
|
|
|
|
set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
|
|
|
|
|
set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
|
|
|
|
|
fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
|
|
|
|
|
set_rx_active(s, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
case T38_IND_V21_PREAMBLE:
|
|
|
|
@ -511,8 +496,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
|
|
|
|
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
|
|
|
|
u->buf[u->in].len = 0;
|
|
|
|
|
fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx);
|
|
|
|
|
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
set_next_tx_handler(s, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
|
|
|
|
|
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
|
|
|
|
|
set_rx_active(s, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
case T38_IND_V27TER_2400_TRAINING:
|
|
|
|
@ -522,8 +507,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
|
|
|
|
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
|
|
|
|
v27ter_tx_restart(&t->fast_modems.v27ter_tx, t->tx_bit_rate, t->use_tep);
|
|
|
|
|
v27ter_tx_set_get_bit(&t->fast_modems.v27ter_tx, get_bit_func, get_bit_user_data);
|
|
|
|
|
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
set_next_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
|
|
|
|
|
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
|
|
|
|
|
set_rx_active(s, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
case T38_IND_V29_7200_TRAINING:
|
|
|
|
@ -533,8 +518,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
|
|
|
|
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
|
|
|
|
v29_tx_restart(&t->fast_modems.v29_tx, t->tx_bit_rate, t->use_tep);
|
|
|
|
|
v29_tx_set_get_bit(&t->fast_modems.v29_tx, get_bit_func, get_bit_user_data);
|
|
|
|
|
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
set_next_tx_handler(s, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
|
|
|
|
|
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
|
|
|
|
|
set_rx_active(s, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
case T38_IND_V17_7200_SHORT_TRAINING:
|
|
|
|
@ -582,8 +567,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
|
|
|
|
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
|
|
|
|
v17_tx_restart(&t->fast_modems.v17_tx, t->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);
|
|
|
|
|
set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
set_next_tx_handler(s, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
|
|
|
|
|
fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
|
|
|
|
|
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
|
|
|
|
|
set_rx_active(s, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
case T38_IND_V8_ANSAM:
|
|
|
|
@ -2150,23 +2135,23 @@ static int restart_rx_modem(t38_gateway_state_t *s)
|
|
|
|
|
case FAX_MODEM_V27TER_RX:
|
|
|
|
|
v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->core.fast_bit_rate, FALSE);
|
|
|
|
|
v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data);
|
|
|
|
|
set_rx_handler(s, &v27ter_v21_rx, s, &v27ter_v21_rx_fillin, s);
|
|
|
|
|
set_rx_handler(t, &v27ter_v21_rx, s, &v27ter_v21_rx_fillin, s);
|
|
|
|
|
s->core.fast_rx_active = FAX_MODEM_V27TER_RX;
|
|
|
|
|
break;
|
|
|
|
|
case FAX_MODEM_V29_RX:
|
|
|
|
|
v29_rx_restart(&t->fast_modems.v29_rx, s->core.fast_bit_rate, FALSE);
|
|
|
|
|
v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data);
|
|
|
|
|
set_rx_handler(s, &v29_v21_rx, s, &v29_v21_rx_fillin, s);
|
|
|
|
|
set_rx_handler(t, &v29_v21_rx, s, &v29_v21_rx_fillin, s);
|
|
|
|
|
s->core.fast_rx_active = FAX_MODEM_V29_RX;
|
|
|
|
|
break;
|
|
|
|
|
case FAX_MODEM_V17_RX:
|
|
|
|
|
v17_rx_restart(&t->fast_modems.v17_rx, s->core.fast_bit_rate, s->core.short_train);
|
|
|
|
|
v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data);
|
|
|
|
|
set_rx_handler(s, &v17_v21_rx, s, &v17_v21_rx_fillin, s);
|
|
|
|
|
set_rx_handler(t, &v17_v21_rx, s, &v17_v21_rx_fillin, s);
|
|
|
|
|
s->core.fast_rx_active = FAX_MODEM_V17_RX;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
|
|
|
|
|
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
|
|
|
|
|
s->core.fast_rx_active = FAX_MODEM_NONE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|