]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
This update brings the fax modem handling into line with the upstream code
authorSteve Underwood <steveu@x100e.coppice.org>
Tue, 28 Aug 2012 05:32:43 +0000 (13:32 +0800)
committerSteve Underwood <steveu@x100e.coppice.org>
Tue, 28 Aug 2012 05:32:43 +0000 (13:32 +0800)
libs/spandsp/src/fax.c
libs/spandsp/src/fax_modems.c
libs/spandsp/src/spandsp/fax_modems.h
libs/spandsp/src/spandsp/private/fax_modems.h
libs/spandsp/src/t31.c
libs/spandsp/src/t38_gateway.c

index 2a2b6437b865515a9eb51d6d4b53c134f5ef337b..1437255284299aacdc5177552335ee8e108313a0 100644 (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;
index 46524b4e0fb77ccb6494778e75271e5ababaf45c..8887f571f80375468df2cb9d6faadd35aedef767 100644 (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;
index 28612e54738adba1b95c493c4469b410d4568616..db9b9984491417225ec56b9f6879f5edac2a761e 100644 (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);
index b0df18c00cb04f3f2f2fddc9353a3b4bf07b7062..280be1d1cf0e1c7aec546da16d80f657fc5dc14b 100644 (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
index f8a2b079664091be050ce3f79cc737a00cbdc34c..467dd30ed005482e53ff051ae2db8bbabdd0fc8e 100644 (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
index 200bdcfde786c919879ad5393613bc187d371c90..9da2f0b9107554b66f6730c73c6486286b4e3bfa 100644 (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 --------------------------------------------------------*/