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");
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:
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
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;
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;
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;
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 --------------------------------------------------------*/
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 --------------------------------------------------------*/
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 --------------------------------------------------------*/
}
/*- 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)
}
/*- 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;
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 --------------------------------------------------------*/
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;
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);
/*! \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 */
/*! \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
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);
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 --------------------------------------------------------*/
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);
}
}
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;
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);
}
}
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;
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);
}
}
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;
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);
}
}
/*- 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;
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 --------------------------------------------------------*/
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;
}
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
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;
{
/* 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;
{
/* 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;
{
/* 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;
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);
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)
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);
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);
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);
/*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);
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);
/*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;
}
/* 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 --------------------------------------------------------*/