From 1b3710d5d0edb86ce421ac46f5d03949ee087b28 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Tue, 28 Aug 2012 13:32:43 +0800 Subject: [PATCH] This update brings the fax modem handling into line with the upstream code --- libs/spandsp/src/fax.c | 42 ++----- libs/spandsp/src/fax_modems.c | 61 ++++------ libs/spandsp/src/spandsp/fax_modems.h | 2 - libs/spandsp/src/spandsp/private/fax_modems.h | 3 +- libs/spandsp/src/t31.c | 109 ++---------------- libs/spandsp/src/t38_gateway.c | 67 +++-------- 6 files changed, 66 insertions(+), 218 deletions(-) diff --git a/libs/spandsp/src/fax.c b/libs/spandsp/src/fax.c index 2a2b6437b8..1437255284 100644 --- a/libs/spandsp/src/fax.c +++ b/libs/spandsp/src/fax.c @@ -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; diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c index 46524b4e0f..8887f571f8 100644 --- a/libs/spandsp/src/fax_modems.c +++ b/libs/spandsp/src/fax_modems.c @@ -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; diff --git a/libs/spandsp/src/spandsp/fax_modems.h b/libs/spandsp/src/spandsp/fax_modems.h index 28612e5473..db9b998449 100644 --- a/libs/spandsp/src/spandsp/fax_modems.h +++ b/libs/spandsp/src/spandsp/fax_modems.h @@ -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); diff --git a/libs/spandsp/src/spandsp/private/fax_modems.h b/libs/spandsp/src/spandsp/private/fax_modems.h index b0df18c00c..280be1d1cf 100644 --- a/libs/spandsp/src/spandsp/private/fax_modems.h +++ b/libs/spandsp/src/spandsp/private/fax_modems.h @@ -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 diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c index f8a2b07966..467dd30ed0 100644 --- a/libs/spandsp/src/t31.c +++ b/libs/spandsp/src/t31.c @@ -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 diff --git a/libs/spandsp/src/t38_gateway.c b/libs/spandsp/src/t38_gateway.c index 200bdcfde7..9da2f0b910 100644 --- a/libs/spandsp/src/t38_gateway.c +++ b/libs/spandsp/src/t38_gateway.c @@ -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 --------------------------------------------------------*/