This update brings the fax modem handling into line with the upstream code

This commit is contained in:
Steve Underwood 2012-08-28 13:32:43 +08:00
parent a8cd9b82da
commit 1b3710d5d0
6 changed files with 66 additions and 218 deletions

View File

@ -354,35 +354,22 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t
t->current_rx_type = type;
t->rx_bit_rate = bit_rate;
if (use_hdlc)
{
fax_modems_set_put_bit(t, (put_bit_func_t) hdlc_rx_put_bit, &t->hdlc_rx);
hdlc_rx_init(&t->hdlc_rx, FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, t30_hdlc_accept, &s->t30);
}
else
{
fax_modems_set_put_bit(t, (put_bit_func_t) t30_non_ecm_put_bit, &s->t30);
}
switch (type)
{
case T30_MODEM_V21:
fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, t->put_bit_user_data);
fsk_rx_signal_cutoff(&t->v21_rx, -45.5f);
fax_modems_start_slow_modem(t, FAX_MODEM_V21_RX);
fax_modems_set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
break;
case T30_MODEM_V17:
fax_modems_start_fast_modem(t, FAX_MODEM_V17_RX, bit_rate, short_train, use_hdlc);
break;
case T30_MODEM_V27TER:
v27ter_rx_restart(&t->fast_modems.v27ter_rx, bit_rate, FALSE);
v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, t->put_bit, t->put_bit_user_data);
fax_modems_set_rx_handler(t, &v27ter_v21_rx, s, &fax_modems_v27ter_v21_rx_fillin, t);
fax_modems_start_fast_modem(t, FAX_MODEM_V27TER_RX, bit_rate, short_train, use_hdlc);
break;
case T30_MODEM_V29:
v29_rx_restart(&t->fast_modems.v29_rx, bit_rate, FALSE);
v29_rx_set_put_bit(&t->fast_modems.v29_rx, t->put_bit, t->put_bit_user_data);
fax_modems_set_rx_handler(t, &v29_v21_rx, s, &fax_modems_v29_v21_rx_fillin, t);
break;
case T30_MODEM_V17:
v17_rx_restart(&t->fast_modems.v17_rx, bit_rate, short_train);
v17_rx_set_put_bit(&t->fast_modems.v17_rx, t->put_bit, t->put_bit_user_data);
fax_modems_set_rx_handler(t, &v17_v21_rx, s, &fax_modems_v17_v21_rx_fillin, t);
fax_modems_start_fast_modem(t, FAX_MODEM_V29_RX, bit_rate, short_train, use_hdlc);
break;
case T30_MODEM_DONE:
span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
@ -404,10 +391,6 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
span_log(&s->logging, SPAN_LOG_FLOW, "Set tx type %d\n", type);
if (t->current_tx_type == type)
return;
if (use_hdlc)
fax_modems_set_get_bit(t, (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx);
else
fax_modems_set_get_bit(t, (get_bit_func_t) t30_non_ecm_get_bit, &s->t30);
switch (type)
{
case T30_MODEM_PAUSE:
@ -428,7 +411,7 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
t->transmit = TRUE;
break;
case T30_MODEM_V21:
fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], t->get_bit, t->get_bit_user_data);
fax_modems_start_slow_modem(t, FAX_MODEM_V21_TX);
/* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */
fax_modems_hdlc_tx_flags(t, 32);
/* Pause before switching from phase C, as per T.30 5.3.2.2. If we omit this, the receiver
@ -444,8 +427,7 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
/* For any fast modem, set 200ms of preamble flags */
fax_modems_hdlc_tx_flags(t, bit_rate/(8*5));
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, t->get_bit, t->get_bit_user_data);
fax_modems_start_fast_modem(t, FAX_MODEM_V17_TX, bit_rate, short_train, use_hdlc);
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);
t->transmit = TRUE;
@ -454,8 +436,7 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
/* For any fast modem, set 200ms of preamble flags */
fax_modems_hdlc_tx_flags(t, bit_rate/(8*5));
v27ter_tx_restart(&t->fast_modems.v27ter_tx, bit_rate, t->use_tep);
v27ter_tx_set_get_bit(&t->fast_modems.v27ter_tx, t->get_bit, t->get_bit_user_data);
fax_modems_start_fast_modem(t, FAX_MODEM_V27TER_TX, bit_rate, short_train, use_hdlc);
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);
t->transmit = TRUE;
@ -464,8 +445,7 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
/* For any fast modem, set 200ms of preamble flags */
fax_modems_hdlc_tx_flags(t, bit_rate/(8*5));
v29_tx_restart(&t->fast_modems.v29_tx, bit_rate, t->use_tep);
v29_tx_set_get_bit(&t->fast_modems.v29_tx, t->get_bit, t->get_bit_user_data);
fax_modems_start_fast_modem(t, FAX_MODEM_V29_TX, bit_rate, short_train, use_hdlc);
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);
t->transmit = TRUE;

View File

@ -125,10 +125,10 @@ static void v17_rx_status_handler(void *user_data, int status)
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));
fax_modems_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);
v17_rx_set_modem_status_handler(&s->fast_modems.v17_rx, NULL, s);
s->fast_modems.v17_rx.put_bit(s->fast_modems.v17_rx.put_bit_user_data, status);
break;
}
/*endswitch*/
s->fast_modems.v17_rx.put_bit(s->fast_modems.v17_rx.put_bit_user_data, status);
}
/*- End of function --------------------------------------------------------*/
@ -172,10 +172,10 @@ static void v27ter_rx_status_handler(void *user_data, int status)
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));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
v27ter_rx_set_modem_status_handler(&s->fast_modems.v27ter_rx, NULL, s);
s->fast_modems.v27ter_rx.put_bit(s->fast_modems.v27ter_rx.put_bit_user_data, status);
break;
}
/*endswitch*/
s->fast_modems.v27ter_rx.put_bit(s->fast_modems.v27ter_rx.put_bit_user_data, status);
}
/*- End of function --------------------------------------------------------*/
@ -219,10 +219,10 @@ static void v29_rx_status_handler(void *user_data, int status)
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));
fax_modems_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);
v29_rx_set_modem_status_handler(&s->fast_modems.v29_rx, NULL, s);
s->fast_modems.v29_rx.put_bit(s->fast_modems.v29_rx.put_bit_user_data, status);
break;
}
/*endswitch*/
s->fast_modems.v29_rx.put_bit(s->fast_modems.v29_rx.put_bit_user_data, status);
}
/*- End of function --------------------------------------------------------*/
@ -255,11 +255,6 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len)
}
/*- End of function --------------------------------------------------------*/
static void v21_rx_status_handler(void *user_data, int status)
{
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which)
{
switch (which)
@ -393,25 +388,6 @@ SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which)
{
switch (which)
{
case FAX_MODEM_V17_RX:
v17_rx_set_modem_status_handler(&s->fast_modems.v17_rx, v17_rx_status_handler, s);
break;
case FAX_MODEM_V27TER_RX:
v27ter_rx_set_modem_status_handler(&s->fast_modems.v27ter_rx, v27ter_rx_status_handler, s);
break;
case FAX_MODEM_V29_RX:
v29_rx_set_modem_status_handler(&s->fast_modems.v29_rx, v29_rx_status_handler, s);
break;
}
/*endswitch*/
fsk_rx_set_modem_status_handler(&s->v21_rx, v21_rx_status_handler, s);
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fax_modems_set_put_bit(fax_modems_state_t *s, put_bit_func_t put_bit, void *user_data)
{
s->put_bit = put_bit;
@ -432,9 +408,25 @@ SPAN_DECLARE(void) fax_modems_set_rx_handler(fax_modems_state_t *s,
span_rx_fillin_handler_t rx_fillin_handler,
void *rx_fillin_user_data)
{
s->rx_handler = rx_handler;
if (s->deferred_rx_handler_updates)
{
/* Only update the actual handlers if they are not currently sidelined to dummy targets */
if (s->rx_handler != span_dummy_rx)
s->rx_handler = rx_handler;
/*endif*/
s->base_rx_handler = rx_handler;
if (s->rx_fillin_handler != span_dummy_rx_fillin)
s->rx_fillin_handler = rx_fillin_handler;
/*endif*/
s->base_rx_fillin_handler = rx_fillin_handler;
}
else
{
s->rx_handler = rx_handler;
s->rx_fillin_handler = rx_fillin_handler;
}
s->rx_user_data = rx_user_data;
s->rx_fillin_handler = rx_fillin_handler;
s->rx_fillin_user_data = rx_fillin_user_data;
}
/*- End of function --------------------------------------------------------*/
@ -521,16 +513,9 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, fax_modems_hdlc_accept, s);
hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, user_data);
fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx);
fsk_rx_signal_cutoff(&s->v21_rx, -39.09f);
fax_modems_start_slow_modem(s, FAX_MODEM_V21_RX);
fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);
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);
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.5f);
v29_tx_init(&s->fast_modems.v29_tx, 9600, s->use_tep, non_ecm_get_bit, 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);
silence_gen_init(&s->silence_gen, 0);
s->rx_signal_present = FALSE;

View File

@ -69,8 +69,6 @@ SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_
SPAN_DECLARE(void) fax_modems_hdlc_tx_flags(fax_modems_state_t *s, int flags);
SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which);
SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, int bit_rate, int short_train, int hdlc_mode);
SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which);

View File

@ -52,7 +52,7 @@ struct fax_modems_state_s
/*! \brief A V.21 FSK modem context used when receiving HDLC over V.21
messages. */
fsk_rx_state_t v21_rx;
struct
union
{
/*! \brief A V.17 modem context used when sending FAXes at 7200bps, 9600bps
12000bps or 14400bps */
@ -113,6 +113,7 @@ struct fax_modems_state_s
/*! \brief TRUE if an HDLC frame has been received correctly. */
int rx_frame_received;
int deferred_rx_handler_updates;
/*! \brief The current receive signal handler */
span_rx_handler_t rx_handler;
/*! \brief The current receive signal handler. Actual receiving hops between this

View File

@ -186,9 +186,6 @@ enum
static int restart_modem(t31_state_t *s, int new_modem);
static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int ok);
static int v17_v21_rx(void *user_data, const int16_t amp[], int len);
static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len);
static int v29_v21_rx(void *user_data, const int16_t amp[], int len);
static int silence_rx(void *user_data, const int16_t amp[], int len);
static int cng_rx(void *user_data, const int16_t amp[], int len);
static void non_ecm_put_bit(void *user_data, int bit);
@ -1616,8 +1613,7 @@ static void t31_v21_rx(t31_state_t *s)
s->hdlc_tx.len = 0;
s->dled = FALSE;
hdlc_rx_init(&s->audio.modems.hdlc_rx, FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept_frame, s);
fsk_rx_init(&s->audio.modems.v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, &s->audio.modems.hdlc_rx);
fsk_rx_signal_cutoff(&s->audio.modems.v21_rx, -39.09f);
fax_modems_start_slow_modem(&s->audio.modems, FAX_MODEM_V21_RX);
s->at_state.transmit = TRUE;
}
/*- End of function --------------------------------------------------------*/
@ -1707,7 +1703,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
hdlc_tx_init(&t->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, s);
/* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */
hdlc_tx_flags(&t->hdlc_tx, 32);
fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx);
fax_modems_start_slow_modem(t, FAX_MODEM_V21_TX);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
}
@ -1753,9 +1749,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
}
else
{
v17_tx_restart(&t->fast_modems.v17_tx, s->bit_rate, FALSE, s->short_train);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
}
s->tx.out_bytes = 0;
s->tx.data_started = FALSE;
@ -1764,8 +1758,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V17_RX:
if (!s->t38_mode)
{
fax_modems_set_rx_handler(t, (span_rx_handler_t) &v17_v21_rx, t, (span_rx_fillin_handler_t) &fax_modems_v17_v21_rx_fillin, t);
v17_rx_restart(&t->fast_modems.v17_rx, s->bit_rate, s->short_train);
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
}
@ -1790,9 +1783,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
}
else
{
v27ter_tx_restart(&t->fast_modems.v27ter_tx, s->bit_rate, FALSE);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
}
s->tx.out_bytes = 0;
s->tx.data_started = FALSE;
@ -1801,8 +1792,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V27TER_RX:
if (!s->t38_mode)
{
fax_modems_set_rx_handler(t, (span_rx_handler_t) &v27ter_v21_rx, t, (span_rx_fillin_handler_t) &fax_modems_v27ter_v21_rx_fillin, t);
v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->bit_rate, FALSE);
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
}
@ -1827,9 +1817,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
}
else
{
v29_tx_restart(&t->fast_modems.v29_tx, s->bit_rate, FALSE);
fax_modems_set_tx_handler(t, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
}
s->tx.out_bytes = 0;
s->tx.data_started = FALSE;
@ -1838,8 +1826,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V29_RX:
if (!s->t38_mode)
{
fax_modems_set_rx_handler(t, (span_rx_handler_t) &v29_v21_rx, t, (span_rx_fillin_handler_t) &fax_modems_v29_v21_rx_fillin, t);
v29_rx_restart(&t->fast_modems.v29_rx, s->bit_rate, FALSE);
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
}
@ -2296,81 +2283,6 @@ static int cng_rx(void *user_data, const int16_t amp[], int len)
}
/*- End of function --------------------------------------------------------*/
static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_modems_state_t *s;
s = (fax_modems_state_t *) user_data;
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(&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));
fax_modems_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 if (s->rx_frame_received)
{
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
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));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
}
return len;
}
/*- End of function --------------------------------------------------------*/
static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_modems_state_t *s;
s = (fax_modems_state_t *) user_data;
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(&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));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
}
else if (s->rx_frame_received)
{
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
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));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
}
return len;
}
/*- End of function --------------------------------------------------------*/
static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_modems_state_t *s;
s = (fax_modems_state_t *) user_data;
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(&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));
fax_modems_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 if (s->rx_frame_received)
{
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
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));
fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
}
return len;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len)
{
int i;
@ -2411,8 +2323,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len)
restart_modem(s, FAX_MODEM_SILENCE_TX);
}
if (!s->at_state.transmit || s->modem == FAX_MODEM_CNG_TONE)
s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
return 0;
}
/*- End of function --------------------------------------------------------*/
@ -2436,6 +2347,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx_fillin(t31_state_t *s, int len)
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_ERROR);
restart_modem(s, FAX_MODEM_SILENCE_TX);
}
s->audio.modems.rx_fillin_handler(s->audio.modems.rx_fillin_user_data, len);
return 0;
}
@ -2608,6 +2520,7 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
non_ecm_get_bit,
tone_detected,
(void *) s);
fax_modems_set_rx_handler(&s->audio.modems, (span_rx_handler_t) &span_dummy_rx, NULL, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX;
v8_parms.modulations = V8_MOD_V21

View File

@ -196,27 +196,6 @@ 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(fax_modems_state_t *s,
span_rx_handler_t handler,
void *user_data,
span_rx_fillin_handler_t fillin_handler,
void *fillin_user_data)
{
/* 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->base_rx_handler = handler;
s->rx_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 int v17_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_modems_state_t *s;
@ -228,13 +207,13 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
{
/* 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);
fax_modems_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 if (s->rx_signal_present)
{
/* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
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);
fax_modems_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*/
return 0;
@ -252,13 +231,13 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{
/* 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_rx_fillin, &s->fast_modems.v27ter_rx);
fax_modems_set_rx_handler(s, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
}
else if (s->rx_signal_present)
{
/* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
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);
fax_modems_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*/
return 0;
@ -276,13 +255,13 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
{
/* 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);
fax_modems_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 if (s->rx_signal_present)
{
/* We have received something, and the fast modem has not trained. We must be receiving valid V.21 */
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);
fax_modems_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*/
return 0;
@ -350,7 +329,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
t38_gateway_hdlc_state_t *u;
int bit_rate;
int short_train;
//int use_hdlc;
int use_hdlc;
t = &s->audio.modems;
t38_non_ecm_buffer_report_output_status(&s->core.non_ecm_to_modem, &s->logging);
@ -393,13 +372,13 @@ static int set_next_tx_type(t38_gateway_state_t *s)
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC mode\n");
hdlc_tx_init(&t->hdlc_tx, FALSE, 2, TRUE, hdlc_underflow_handler, s);
fax_modems_set_get_bit(t, (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx);
//use_hdlc = TRUE;
use_hdlc = TRUE;
}
else
{
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM mode\n");
fax_modems_set_get_bit(t, (get_bit_func_t) t38_non_ecm_buffer_get_bit, &s->core.non_ecm_to_modem);
//use_hdlc = FALSE;
use_hdlc = FALSE;
}
/*endif*/
switch (indicator)
@ -433,7 +412,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
hdlc_tx_flags(&t->hdlc_tx, 32);
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);
fax_modems_start_slow_modem(t, FAX_MODEM_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);
fax_modems_set_rx_active(t, TRUE);
@ -443,8 +422,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
bit_rate =
t->tx_bit_rate = (indicator == T38_IND_V27TER_4800_TRAINING) ? 4800 : 2400;
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, t->get_bit, t->get_bit_user_data);
fax_modems_start_fast_modem(t, FAX_MODEM_V27TER_TX, bit_rate, s->core.short_train, use_hdlc);
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);
fax_modems_set_rx_active(t, TRUE);
@ -454,8 +432,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
bit_rate =
t->tx_bit_rate = (indicator == T38_IND_V29_9600_TRAINING) ? 9600 : 7200;
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, t->get_bit, t->get_bit_user_data);
fax_modems_start_fast_modem(t, FAX_MODEM_V29_TX, bit_rate, s->core.short_train, use_hdlc);
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);
fax_modems_set_rx_active(t, TRUE);
@ -503,8 +480,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
/*endswitch*/
t->tx_bit_rate = bit_rate;
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, t->get_bit, t->get_bit_user_data);
fax_modems_start_fast_modem(t, FAX_MODEM_V17_TX, bit_rate, short_train, use_hdlc);
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);
fax_modems_set_rx_active(t, TRUE);
@ -2044,6 +2020,7 @@ static int restart_rx_modem(t38_gateway_state_t *s)
t->rx_trained = FALSE;
/* Default to the transmit data being V.21, unless a faster modem pops up trained. */
s->t38x.current_tx_data_type = T38_DATA_V21;
//fax_modems_start_slow_modem(t, FAX_MODEM_V21_RX);
fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) t38_hdlc_rx_put_bit, &t->hdlc_rx);
#if 0
fsk_rx_signal_cutoff(&t->v21_rx, -39.09f);
@ -2063,28 +2040,23 @@ static int restart_rx_modem(t38_gateway_state_t *s)
/*endif*/
to_t38_buffer_init(&s->core.to_t38);
s->core.to_t38.octets_per_data_packet = 1;
t->deferred_rx_handler_updates = TRUE;
switch (s->core.fast_rx_modem)
{
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, t->put_bit, t->put_bit_user_data);
set_rx_handler(t, &v27ter_v21_rx, t, &fax_modems_v27ter_v21_rx_fillin, t);
fax_modems_start_fast_modem(t, s->core.fast_rx_modem, s->core.fast_bit_rate, s->core.short_train, FALSE);
s->core.fast_rx_active = s->core.fast_rx_modem;
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, t->put_bit, t->put_bit_user_data);
set_rx_handler(t, &v29_v21_rx, t, &fax_modems_v29_v21_rx_fillin, t);
fax_modems_start_fast_modem(t, s->core.fast_rx_modem, s->core.fast_bit_rate, s->core.short_train, FALSE);
s->core.fast_rx_active = s->core.fast_rx_modem;
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, t->put_bit, t->put_bit_user_data);
set_rx_handler(t, &v17_v21_rx, t, &fax_modems_v17_v21_rx_fillin, t);
fax_modems_start_fast_modem(t, s->core.fast_rx_modem, s->core.fast_bit_rate, s->core.short_train, FALSE);
s->core.fast_rx_active = s->core.fast_rx_modem;
break;
default:
set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
fax_modems_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;
}
@ -2317,7 +2289,6 @@ static int t38_gateway_audio_init(t38_gateway_state_t *s)
/* TODO: Don't use the very low cutoff levels we would like to. We get some quirks if we do.
We need to sort this out. */
fsk_rx_signal_cutoff(&s->audio.modems.v21_rx, -30.0f);
v29_rx_signal_cutoff(&s->audio.modems.fast_modems.v29_rx, -28.5f);
return 0;
}
/*- End of function --------------------------------------------------------*/