]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Various fax_modems.c related improvements
authorSteve Underwood <steveu@coppice.org>
Sun, 26 Aug 2012 07:43:15 +0000 (15:43 +0800)
committerSteve Underwood <steveu@coppice.org>
Sun, 26 Aug 2012 07:43:15 +0000 (15:43 +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 1edba28eea1e2a325f46d3927274bc53f08f5a5b..3e8048d7cd89bfeff485227d150511be9b484683 100644 (file)
 
 #define HDLC_FRAMING_OK_THRESHOLD       8
 
-static void fax_send_hdlc(void *user_data, const uint8_t *msg, int len)
+static void fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len)
 {
-    fax_state_t *s;
+    fax_modems_state_t *s;
 
-    s = (fax_state_t *) user_data;
+    s = (fax_modems_state_t *) user_data;
     
-    hdlc_tx_frame(&s->modems.hdlc_tx, msg, len);
+    hdlc_tx_frame(&s->hdlc_tx, msg, len);
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -142,7 +142,6 @@ static void tone_detected(void *user_data, int tone, int level, int delay)
 }
 /*- End of function --------------------------------------------------------*/
 
-#if 0
 static void v8_handler(void *user_data, v8_parms_t *result)
 {
     fax_state_t *s;
@@ -151,7 +150,6 @@ static void v8_handler(void *user_data, v8_parms_t *result)
     span_log(&s->logging, SPAN_LOG_FLOW, "V.8 report received\n");
 }
 /*- End of function --------------------------------------------------------*/
-#endif
 
 static void hdlc_underflow_handler(void *user_data)
 {
@@ -162,31 +160,6 @@ static void hdlc_underflow_handler(void *user_data)
 }
 /*- End of function --------------------------------------------------------*/
 
-static void set_rx_handler(fax_state_t *s,
-                           span_rx_handler_t rx_handler,
-                           span_rx_fillin_handler_t fillin_handler,
-                           void *user_data)
-{
-    s->modems.rx_handler = rx_handler;
-    s->modems.rx_fillin_handler = fillin_handler;
-    s->modems.rx_user_data = user_data;
-}
-/*- End of function --------------------------------------------------------*/
-
-static void fax_modems_set_tx_handler(fax_state_t *s, span_tx_handler_t handler, void *user_data)
-{
-    s->modems.tx_handler = handler;
-    s->modems.tx_user_data = user_data;
-}
-/*- End of function --------------------------------------------------------*/
-
-static void fax_modems_set_next_tx_handler(fax_state_t *s, span_tx_handler_t handler, void *user_data)
-{
-    s->modems.next_tx_handler = handler;
-    s->modems.next_tx_user_data = user_data;
-}
-/*- End of function --------------------------------------------------------*/
-
 static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
 {
     fax_state_t *t;
@@ -195,23 +168,20 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
     t = (fax_state_t *) user_data;
     s = &t->modems;
     v17_rx(&s->fast_modems.v17_rx, amp, len);
+    fsk_rx(&s->v21_rx, amp, len);
     if (t->t30.rx_trained)
     {
         /* The fast modem has trained, so we no longer need to run the slow one in parallel. */
-        span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
+        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
+    else if (t->t30.rx_frame_received)
     {
-        fsk_rx(&s->v21_rx, amp, len);
-        if (t->t30.rx_frame_received)
-        {
-            /* We have received something, and the fast modem has not trained. We must
-               be receiving valid V.21 */
-            span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
-        }
+        /* 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);
     }
+    /*endif*/
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -237,23 +207,20 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
     t = (fax_state_t *) user_data;
     s = &t->modems;
     v27ter_rx(&s->fast_modems.v27ter_rx, amp, len);
+    fsk_rx(&s->v21_rx, amp, len);
     if (t->t30.rx_trained)
     {
         /* The fast modem has trained, so we no longer need to run the slow one in parallel. */
-        span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
+        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
+    else if (t->t30.rx_frame_received)
     {
-        fsk_rx(&s->v21_rx, amp, len);
-        if (t->t30.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));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
-        }
+        /* 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);
     }
+    /*endif*/
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -279,23 +246,20 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
     t = (fax_state_t *) user_data;
     s = &t->modems;
     v29_rx(&s->fast_modems.v29_rx, amp, len);
+    fsk_rx(&s->v21_rx, amp, len);
     if (t->t30.rx_trained)
     {
         /* The fast modem has trained, so we no longer need to run the slow one in parallel. */
-        span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
+        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
+    else if (t->t30.rx_frame_received)
     {
-        fsk_rx(&s->v21_rx, amp, len);
-        if (t->t30.rx_frame_received)
-        {
-            /* We have received something, and the fast modem has not trained. We must
-               be receiving valid V.21 */
-            span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
-        }
+        /* 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);
     }
+    /*endif*/
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -351,7 +315,7 @@ SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len)
     }
 #endif
     /* Call the fillin function of the current modem (if there is one). */
-    s->modems.rx_fillin_handler(s->modems.rx_user_data, len);
+    s->modems.rx_fillin_handler(s->modems.rx_fillin_user_data, len);
     t30_timer_update(&s->t30, len);
     return 0;
 }
@@ -364,14 +328,14 @@ static int set_next_tx_type(fax_state_t *s)
     t = &s->modems;
     if (t->next_tx_handler)
     {
-        fax_modems_set_tx_handler(s, t->next_tx_handler, t->next_tx_user_data);
+        fax_modems_set_tx_handler(t, t->next_tx_handler, t->next_tx_user_data);
         t->next_tx_handler = NULL;
         return 0;
     }
     /* If there is nothing else to change to, so use zero length silence */
     silence_gen_alter(&t->silence_gen, 0);
-    fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-    fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+    fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+    fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
     t->transmit = FALSE;
     return -1;
 }
@@ -456,27 +420,27 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t
     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, put_bit_user_data);
         fsk_rx_signal_cutoff(&t->v21_rx, -45.5f);
-        set_rx_handler(s, (span_rx_handler_t) &fsk_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);
         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, put_bit_func, put_bit_user_data);
-        set_rx_handler(s, &v27ter_v21_rx, &v27ter_v21_rx_fillin, s);
+        fax_modems_set_rx_handler(t, &v27ter_v21_rx, s, &v27ter_v21_rx_fillin, s);
         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, put_bit_func, put_bit_user_data);
-        set_rx_handler(s, &v29_v21_rx, &v29_v21_rx_fillin, s);
+        fax_modems_set_rx_handler(t, &v29_v21_rx, s, &v29_v21_rx_fillin, s);
         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, put_bit_func, put_bit_user_data);
-        set_rx_handler(s, &v17_v21_rx, &v17_v21_rx_fillin, s);
+        fax_modems_set_rx_handler(t, &v17_v21_rx, s, &v17_v21_rx_fillin, s);
         break;
     case T30_MODEM_DONE:
         span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
     default:
-        set_rx_handler(s, (span_rx_handler_t) &span_dummy_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
+        fax_modems_set_rx_handler(t, (span_rx_handler_t) &span_dummy_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
         break;
     }
 }
@@ -509,8 +473,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
     {
     case T30_MODEM_PAUSE:
         silence_gen_alter(&t->silence_gen, ms_to_samples(short_train));
-        fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-        fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+        fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+        fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         t->transmit = TRUE;
         break;
     case T30_MODEM_CED:
@@ -520,8 +484,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
         else
             tone = MODEM_CONNECT_TONES_FAX_CNG;
         modem_connect_tones_tx_init(&t->connect_tx, tone);
-        fax_modems_set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
-        fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+        fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
+        fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         t->transmit = TRUE;
         break;
     case T30_MODEM_V21:
@@ -533,8 +497,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
            a 75ms gap before any V.21 transmission is harmless, adds little to the overall length of
            a call, and ensures the receiving end is ready. */
         silence_gen_alter(&t->silence_gen, ms_to_samples(75));
-        fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-        fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
+        fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+        fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
         t->transmit = TRUE;
         break;
     case T30_MODEM_V17:
@@ -543,8 +507,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
         hdlc_tx_flags(&t->hdlc_tx, 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, get_bit_func, get_bit_user_data);
-        fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-        fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
+        fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+        fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
         t->transmit = TRUE;
         break;
     case T30_MODEM_V27TER:
@@ -553,8 +517,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
         hdlc_tx_flags(&t->hdlc_tx, 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, get_bit_func, get_bit_user_data);
-        fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-        fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
+        fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+        fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
         t->transmit = TRUE;
         break;
     case T30_MODEM_V29:
@@ -563,8 +527,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
         hdlc_tx_flags(&t->hdlc_tx, 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, get_bit_func, get_bit_user_data);
-        fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-        fax_modems_set_next_tx_handler(s, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
+        fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+        fax_modems_set_next_tx_handler(t, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
         t->transmit = TRUE;
         break;
     case T30_MODEM_DONE:
@@ -572,8 +536,8 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
         /* Fall through */
     default:
         silence_gen_alter(&t->silence_gen, 0);
-        fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-        fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+        fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+        fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         t->transmit = FALSE;
         break;
     }
@@ -590,7 +554,7 @@ SPAN_DECLARE(void) fax_set_transmit_on_idle(fax_state_t *s, int transmit_on_idle
 
 SPAN_DECLARE(void) fax_set_tep_mode(fax_state_t *s, int use_tep)
 {
-    s->modems.use_tep = use_tep;
+    fax_modems_set_tep_mode(&s->modems, use_tep);
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -608,12 +572,9 @@ SPAN_DECLARE(logging_state_t *) fax_get_logging_state(fax_state_t *s)
 
 SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
 {
-#if 0
     v8_parms_t v8_parms;
-#endif
 
     fax_modems_restart(&s->modems);
-#if 0
     v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
     v8_parms.call_function = V8_CALL_T30_RX;
     v8_parms.modulations = V8_MOD_V21;
@@ -631,7 +592,6 @@ SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
     v8_parms.nsf = -1;
     v8_parms.t66 = -1;
     v8_restart(&s->v8, calling_party, &v8_parms);
-#endif
     t30_restart(&s->t30);
 #if defined(LOG_FAX_AUDIO)
     {
@@ -669,9 +629,7 @@ SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
 
 SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
 {
-#if 0
     v8_parms_t v8_parms;
-#endif
 
     if (s == NULL)
     {
@@ -695,10 +653,9 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
              (void *) s,
              fax_set_tx_type,
              (void *) s,
-             fax_send_hdlc,
-             (void *) s);
+             fax_modems_hdlc_tx_frame,
+             (void *) &s->modems);
     t30_set_supported_modems(&s->t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
-#if 0
     v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
     v8_parms.call_function = V8_CALL_T30_RX;
     v8_parms.modulations = V8_MOD_V21;
@@ -716,7 +673,6 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
     v8_parms.nsf = -1;
     v8_parms.t66 = -1;
     v8_init(&s->v8, calling_party, &v8_parms, v8_handler, s);
-#endif
     fax_restart(s, calling_party);
     return s;
 }
index c2d20df2b75a20c3900f0ecf14a9e9dc31d813a8..e012e5a7672f04c7bbbf8254c298ff561b2579a5 100644 (file)
 
 #define HDLC_FRAMING_OK_THRESHOLD               5
 
+SPAN_DECLARE(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len)
+{
+    fax_modems_state_t *s;
+
+    s = (fax_modems_state_t *) user_data;
+
+    hdlc_tx_frame(&s->hdlc_tx, msg, len);
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(void) fax_modems_hdlc_tx_flags(fax_modems_state_t *s, int flags)
+{
+    hdlc_tx_flags(&s->hdlc_tx, flags);
+}
+/*- End of function --------------------------------------------------------*/
+
+static void v17_rx_status_handler(void *user_data, int status)
+{
+    fax_modems_state_t *s;
+
+    s = (fax_modems_state_t *) user_data;
+    switch (status)
+    {
+    case SIG_STATUS_TRAINING_SUCCEEDED:
+        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*/
+}
+/*- End of function --------------------------------------------------------*/
+
 SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len)
 {
     fax_modems_state_t *s;
@@ -97,10 +131,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t am
     {
         /* 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));
-        s->rx_handler = (span_rx_handler_t) &fsk_rx;
-        s->rx_fillin_handler = (span_rx_fillin_handler_t) &fsk_rx_fillin;
-        s->rx_user_data = &s->v21_rx;
-        s->rx_fillin_user_data = &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;
@@ -118,6 +149,24 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len)
 }
 /*- End of function --------------------------------------------------------*/
 
+static void v27ter_rx_status_handler(void *user_data, int status)
+{
+    fax_modems_state_t *s;
+
+    s = (fax_modems_state_t *) user_data;
+    switch (status)
+    {
+    case SIG_STATUS_TRAINING_SUCCEEDED:
+        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*/
+}
+/*- End of function --------------------------------------------------------*/
+
 SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
 {
     fax_modems_state_t *s;
@@ -129,10 +178,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t
     {
         /* 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));
-        s->rx_handler = (span_rx_handler_t) &fsk_rx;
-        s->rx_fillin_handler = (span_rx_fillin_handler_t) &fsk_rx_fillin;
-        s->rx_user_data = &s->v21_rx;
-        s->rx_fillin_user_data = &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;
@@ -150,6 +196,24 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int le
 }
 /*- End of function --------------------------------------------------------*/
 
+static void v29_rx_status_handler(void *user_data, int status)
+{
+    fax_modems_state_t *s;
+
+    s = (fax_modems_state_t *) user_data;
+    switch (status)
+    {
+    case SIG_STATUS_TRAINING_SUCCEEDED:
+        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*/
+}
+/*- End of function --------------------------------------------------------*/
+
 SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len)
 {
     fax_modems_state_t *s;
@@ -161,10 +225,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t am
     {
         /* 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));
-        s->rx_handler = (span_rx_handler_t) &fsk_rx;
-        s->rx_fillin_handler = (span_rx_fillin_handler_t) &fsk_rx_fillin;
-        s->rx_user_data = &s->v21_rx;
-        s->rx_fillin_user_data = &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;
@@ -192,60 +253,136 @@ static void v21_rx_status_handler(void *user_data, int status)
 }
 /*- End of function --------------------------------------------------------*/
 
-static void v17_rx_status_handler(void *user_data, int status)
+SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which)
 {
-    fax_modems_state_t *s;
-
-    s = (fax_modems_state_t *) user_data;
-    switch (status)
+    switch (which)
     {
-    case SIG_STATUS_TRAINING_SUCCEEDED:
-        span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
-        s->rx_handler = (span_rx_handler_t) &v17_rx;
-        s->rx_fillin_handler = (span_rx_fillin_handler_t) &v17_rx_fillin;
-        s->rx_user_data = &s->fast_modems.v17_rx;
-        s->rx_fillin_user_data = &s->fast_modems.v17_rx;
+    case FAX_MODEM_V21_RX:
+        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);
+        s->rx_frame_received = FALSE;
+        break;
+    case FAX_MODEM_V21_TX:
+        fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);
         break;
     }
-    /*endswitch*/
 }
 /*- End of function --------------------------------------------------------*/
 
-static void v27ter_rx_status_handler(void *user_data, int status)
+SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, int bit_rate, int short_train, int hdlc_mode)
 {
-    fax_modems_state_t *s;
+    put_bit_func_t put_bit;
+    get_bit_func_t get_bit;
+    void *get_bit_user_data;
+    void *put_bit_user_data;
 
-    s = (fax_modems_state_t *) user_data;
-    switch (status)
+    s->bit_rate = bit_rate;
+    if (hdlc_mode)
     {
-    case SIG_STATUS_TRAINING_SUCCEEDED:
-        span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
-        s->rx_handler = (span_rx_handler_t) &v27ter_rx;
-        s->rx_fillin_handler = (span_rx_fillin_handler_t) &v27ter_rx_fillin;
-        s->rx_user_data = &s->fast_modems.v27ter_rx;
-        s->rx_fillin_user_data = &s->fast_modems.v27ter_rx;
-        break;
+        get_bit = (get_bit_func_t) hdlc_tx_get_bit;
+        get_bit_user_data = (void *) &s->hdlc_tx;
+        put_bit = (put_bit_func_t) hdlc_rx_put_bit;
+        put_bit_user_data = (void *) &s->hdlc_rx;
     }
-    /*endswitch*/
-}
-/*- End of function --------------------------------------------------------*/
-
-static void v29_rx_status_handler(void *user_data, int status)
-{
-    fax_modems_state_t *s;
+    else
+    {
+        get_bit = s->get_bit;
+        get_bit_user_data = s->get_bit_user_data;
+        put_bit = s->put_bit;
+        put_bit_user_data = s->put_bit_user_data;
+    }
+    /*endif*/
 
-    s = (fax_modems_state_t *) user_data;
-    switch (status)
+    /* If we change modems we need to do a complete reinitialisation of the modem, because
+       the modems use overlapping memory. */
+    if (s->fast_modem != which)
     {
-    case SIG_STATUS_TRAINING_SUCCEEDED:
-        span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
-        s->rx_handler = (span_rx_handler_t) &v29_rx;
-        s->rx_fillin_handler = (span_rx_fillin_handler_t) &v29_rx_fillin;
-        s->rx_user_data = &s->fast_modems.v29_rx;
-        s->rx_fillin_user_data = &s->fast_modems.v29_rx;
-        break;
+        s->current_rx_type = which;
+        s->short_train = FALSE;
+        s->fast_modem = which;
+        if (hdlc_mode)
+            s->rx_frame_received = FALSE;
+        switch (s->fast_modem)
+        {
+        case FAX_MODEM_V27TER_RX:
+            v27ter_rx_init(&s->fast_modems.v27ter_rx, s->bit_rate, put_bit, put_bit_user_data);
+            v27ter_rx_set_modem_status_handler(&s->fast_modems.v27ter_rx, v27ter_rx_status_handler, s);
+            fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v27ter_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v27ter_v21_rx_fillin, s);
+            break;
+        case FAX_MODEM_V29_RX:
+            v29_rx_init(&s->fast_modems.v29_rx, s->bit_rate, put_bit, put_bit_user_data);
+            v29_rx_signal_cutoff(&s->fast_modems.v29_rx, -45.5f);
+            v29_rx_set_modem_status_handler(&s->fast_modems.v29_rx, v29_rx_status_handler, s);
+            fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v29_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v29_v21_rx_fillin, s);
+            break;
+        case FAX_MODEM_V17_RX:
+            v17_rx_init(&s->fast_modems.v17_rx, s->bit_rate, put_bit, put_bit_user_data);
+            v17_rx_set_modem_status_handler(&s->fast_modems.v17_rx, v17_rx_status_handler, s);
+            fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v17_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v17_v21_rx_fillin, s);
+            break;
+        case FAX_MODEM_V27TER_TX:
+            v27ter_tx_init(&s->fast_modems.v27ter_tx, s->bit_rate, s->use_tep, get_bit, get_bit_user_data);
+            fax_modems_set_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &s->fast_modems.v27ter_tx);
+            fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            break;
+        case FAX_MODEM_V29_TX:
+            v29_tx_init(&s->fast_modems.v29_tx, s->bit_rate, s->use_tep, get_bit, get_bit_user_data);
+            fax_modems_set_tx_handler(s, (span_tx_handler_t) &v29_tx, &s->fast_modems.v29_tx);
+            fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            break;
+        case FAX_MODEM_V17_TX:
+            v17_tx_init(&s->fast_modems.v17_tx, s->bit_rate, s->use_tep, get_bit, get_bit_user_data);
+            fax_modems_set_tx_handler(s, (span_tx_handler_t) &v17_tx, &s->fast_modems.v17_tx);
+            fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            break;
+        }
+        /*endswitch*/
     }
-    /*endswitch*/
+    else
+    {
+        s->short_train = short_train;
+        switch (s->fast_modem)
+        {
+        case FAX_MODEM_V27TER_RX:
+            v27ter_rx_restart(&s->fast_modems.v27ter_rx, s->bit_rate, FALSE);
+            v27ter_rx_set_put_bit(&s->fast_modems.v27ter_rx, put_bit, put_bit_user_data);
+            v27ter_rx_set_modem_status_handler(&s->fast_modems.v27ter_rx, v27ter_rx_status_handler, s);
+            fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v27ter_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v27ter_v21_rx_fillin, s);
+            break;
+        case FAX_MODEM_V29_RX:
+            v29_rx_restart(&s->fast_modems.v29_rx, s->bit_rate, FALSE);
+            v29_rx_set_put_bit(&s->fast_modems.v29_rx, put_bit, put_bit_user_data);
+            v29_rx_set_modem_status_handler(&s->fast_modems.v29_rx, v29_rx_status_handler, s);
+            fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v29_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v29_v21_rx_fillin, s);
+            break;
+        case FAX_MODEM_V17_RX:
+            v17_rx_restart(&s->fast_modems.v17_rx, s->bit_rate, s->short_train);
+            v17_rx_set_put_bit(&s->fast_modems.v17_rx, put_bit, put_bit_user_data);
+            v17_rx_set_modem_status_handler(&s->fast_modems.v17_rx, v17_rx_status_handler, s);
+            fax_modems_set_rx_handler(s, (span_rx_handler_t) &fax_modems_v17_v21_rx, s, (span_rx_fillin_handler_t) &fax_modems_v17_v21_rx_fillin, s);
+            break;
+        case FAX_MODEM_V27TER_TX:
+            v27ter_tx_restart(&s->fast_modems.v27ter_tx, s->bit_rate, s->use_tep);
+            v27ter_tx_set_get_bit(&s->fast_modems.v27ter_tx, get_bit, get_bit_user_data);
+            fax_modems_set_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &s->fast_modems.v27ter_tx);
+            fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            break;
+        case FAX_MODEM_V29_TX:
+            v29_tx_restart(&s->fast_modems.v29_tx, s->bit_rate, s->use_tep);
+            v29_tx_set_get_bit(&s->fast_modems.v29_tx, get_bit, get_bit_user_data);
+            fax_modems_set_tx_handler(s, (span_tx_handler_t) &v29_tx, &s->fast_modems.v29_tx);
+            fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            break;
+        case FAX_MODEM_V17_TX:
+            v17_tx_restart(&s->fast_modems.v17_tx, s->bit_rate, s->use_tep, s->short_train);
+            v17_tx_set_get_bit(&s->fast_modems.v17_tx, get_bit, get_bit_user_data);
+            fax_modems_set_tx_handler(s, (span_tx_handler_t) &v17_tx, &s->fast_modems.v17_tx);
+            fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            break;
+        }
+        /*endswitch*/
+    }
+    /*endif*/
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -268,6 +405,42 @@ SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which)
 }
 /*- End of function --------------------------------------------------------*/
 
+SPAN_DECLARE(void) fax_modems_set_rx_handler(fax_modems_state_t *s,
+                                             span_rx_handler_t rx_handler,
+                                             void *rx_user_data,
+                                             span_rx_fillin_handler_t rx_fillin_handler,
+                                             void *rx_fillin_user_data)
+{
+    s->rx_handler = rx_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 --------------------------------------------------------*/
+
+#if 0
+SPAN_DECLARE(void) fax_modems_set_rx_active(fax_modems_state_t *s, int active)
+{
+    s->rx_handler = (active)  ?  s->base_rx_handler  :  span_dummy_rx;
+    s->rx_fillin_handler = (active)  ?  s->base_rx_fillin_handler  :  span_dummy_rx_fillin;
+}
+/*- End of function --------------------------------------------------------*/
+#endif
+
+SPAN_DECLARE(void) fax_modems_set_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data)
+{
+    s->tx_handler = handler;
+    s->tx_user_data = user_data;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(void) fax_modems_set_next_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data)
+{
+    s->next_tx_handler = handler;
+    s->next_tx_user_data = user_data;
+}
+/*- End of function --------------------------------------------------------*/
+
 SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep)
 {
     s->use_tep = use_tep;
@@ -304,8 +477,31 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
     memset(s, 0, sizeof(*s));
     s->use_tep = use_tep;
 
+    modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG);
+    if (tone_callback)
+    {
+        modem_connect_tones_rx_init(&s->connect_rx,
+                                    MODEM_CONNECT_TONES_FAX_CNG,
+                                    tone_callback,
+                                    user_data);
+    }
+    /*endif*/
+    span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
+    span_log_set_protocol(&s->logging, "FAX modems");
+
+    dc_restore_init(&s->dc_restore);
+
+    s->get_bit = non_ecm_get_bit;
+    s->get_bit_user_data = user_data;
+    s->put_bit = non_ecm_put_bit;
+    s->put_bit_user_data = user_data;
+
+    s->hdlc_accept = hdlc_accept;
+    s->hdlc_accept_user_data = user_data;
+
     hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data);
     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);
     fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);
@@ -317,16 +513,6 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
     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);
-    modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG);
-    if (tone_callback)
-    {
-        modem_connect_tones_rx_init(&s->connect_rx,
-                                    MODEM_CONNECT_TONES_FAX_CNG,
-                                    tone_callback,
-                                    user_data);
-    }
-    /*endif*/
-    dc_restore_init(&s->dc_restore);
 
     s->rx_signal_present = FALSE;
     s->rx_handler = (span_rx_handler_t) &span_dummy_rx;
index a3f77dcc002a142dae63c0e12e2dcafbc80d3fbb..9c309f88620ab9f5de9c33804e81aaeb06e20fdf 100644 (file)
@@ -65,10 +65,30 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len);
 SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len);
 SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len);
 
+SPAN_DECLARE(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len);
+
+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);
+
 SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep);
 
+SPAN_DECLARE(void) fax_modems_set_rx_handler(fax_modems_state_t *s,
+                                             span_rx_handler_t rx_handler,
+                                             void *rx_user_data,
+                                             span_rx_fillin_handler_t rx_fillin_handler,
+                                             void *rx_fillin_user_data);
+
+SPAN_DECLARE(void) fax_modems_set_rx_active(fax_modems_state_t *s, int active);
+
+SPAN_DECLARE(void) fax_modems_set_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data);
+
+SPAN_DECLARE(void) fax_modems_set_next_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data);
+
 SPAN_DECLARE(int) fax_modems_restart(fax_modems_state_t *s);
 
 /*! Get a pointer to the logging context associated with a FAX modems context.
index 90aa47367a79496d593f0892a2cfb21a0439e5aa..e9adaa47b63989c89ae332a9c19b1ce5c662a517 100644 (file)
@@ -82,11 +82,30 @@ struct fax_modems_state_s
     /*! \brief */
     dc_restore_state_t dc_restore;
 
+    /*! \brief The fast modem type currently in use */
+    int fast_modem;
+
     /*! \brief The currently selected receiver type */
     int current_rx_type;
     /*! \brief The currently selected transmitter type */
     int current_tx_type;
 
+    int bit_rate;
+    int short_train;
+
+    /*! \brief The callback function used to put each bit received. */
+    put_bit_func_t put_bit;
+    /*! \brief A user specified opaque pointer passed to the put_bit routine. */
+    void *put_bit_user_data;
+
+    /*! \brief The callback function used to get the next bit to be transmitted. */
+    get_bit_func_t get_bit;
+    /*! \brief A user specified opaque pointer passed to the get_bit function. */
+    void *get_bit_user_data;
+
+    hdlc_frame_handler_t hdlc_accept;
+    void *hdlc_accept_user_data;
+
     /*! \brief TRUE if a carrier is present. Otherwise FALSE. */
     int rx_signal_present;
     /*! \brief TRUE if a modem has trained correctly. */
@@ -96,9 +115,9 @@ struct fax_modems_state_s
 
     /*! \brief The current receive signal handler */
     span_rx_handler_t rx_handler;
+    void *rx_user_data;
     /*! \brief The current receive missing signal fill-in handler */
     span_rx_fillin_handler_t rx_fillin_handler;
-    void *rx_user_data;
     void *rx_fillin_user_data;
 
     /*! \brief The current transmit signal handler */
index 163de33c103ed7762a5b3a6643e8f496bc0dc3c6..b1c46206f72d5e0437b62a4c213dd9b25b93a020 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 void set_rx_handler(t31_state_t *s, span_rx_handler_t rx_handler, span_rx_fillin_handler_t fillin_handler, void *user_data);
-static void set_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data);
-static void set_next_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data);
 static int v17_v21_rx(void *user_data, const int16_t amp[], int len);
 static int v17_v21_rx_fillin(void *user_data, int len);
 static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len);
@@ -1194,12 +1191,14 @@ static void non_ecm_rx_status(void *user_data, int status)
         break;
     case SIG_STATUS_TRAINING_FAILED:
         s->at_state.rx_trained = FALSE;
+        s->audio.modems.rx_trained = FALSE;
         break;
     case SIG_STATUS_TRAINING_SUCCEEDED:
         /* The modem is now trained */
         at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
         s->at_state.rx_signal_present = TRUE;
         s->at_state.rx_trained = TRUE;
+        s->audio.modems.rx_trained = TRUE;
         break;
     case SIG_STATUS_CARRIER_UP:
         break;
@@ -1218,6 +1217,7 @@ static void non_ecm_rx_status(void *user_data, int status)
         }
         s->at_state.rx_signal_present = FALSE;
         s->at_state.rx_trained = FALSE;
+        s->audio.modems.rx_trained = FALSE;
         break;
     default:
         if (s->at_state.p.result_code_format)
@@ -1394,7 +1394,6 @@ static void tone_detected(void *user_data, int tone, int level, int delay)
 }
 /*- End of function --------------------------------------------------------*/
 
-#if 0
 static void v8_handler(void *user_data, v8_parms_t *result)
 {
     t31_state_t *s;
@@ -1403,7 +1402,6 @@ static void v8_handler(void *user_data, v8_parms_t *result)
     span_log(&s->logging, SPAN_LOG_FLOW, "V.8 report received\n");
 }
 /*- End of function --------------------------------------------------------*/
-#endif
 
 static void hdlc_tx_underflow(void *user_data)
 {
@@ -1435,17 +1433,20 @@ static void hdlc_rx_status(void *user_data, int status)
         break;
     case SIG_STATUS_TRAINING_FAILED:
         s->at_state.rx_trained = FALSE;
+        s->audio.modems.rx_trained = FALSE;
         break;
     case SIG_STATUS_TRAINING_SUCCEEDED:
         /* The modem is now trained */
         s->at_state.rx_signal_present = TRUE;
         s->at_state.rx_trained = TRUE;
+        s->audio.modems.rx_trained = TRUE;
         break;
     case SIG_STATUS_CARRIER_UP:
         if (s->modem == FAX_MODEM_CNG_TONE  ||  s->modem == FAX_MODEM_NOCNG_TONE  ||  s->modem == FAX_MODEM_V21_RX)
         {
             s->at_state.rx_signal_present = TRUE;
             s->rx_frame_received = FALSE;
+            s->audio.modems.rx_frame_received = FALSE;
         }
         break;
     case SIG_STATUS_CARRIER_DOWN:
@@ -1473,6 +1474,7 @@ static void hdlc_rx_status(void *user_data, int status)
         }
         s->at_state.rx_signal_present = FALSE;
         s->at_state.rx_trained = FALSE;
+        s->audio.modems.rx_trained = FALSE;
         break;
     case SIG_STATUS_FRAMING_OK:
         if (s->modem == FAX_MODEM_CNG_TONE  ||  s->modem == FAX_MODEM_NOCNG_TONE)
@@ -1492,6 +1494,7 @@ static void hdlc_rx_status(void *user_data, int status)
             {
                 s->at_state.rx_signal_present = TRUE;
                 s->rx_frame_received = TRUE;
+                s->audio.modems.rx_frame_received = TRUE;
                 s->modem = FAX_MODEM_V21_RX;
                 s->at_state.transmit = FALSE;
                 s->at_state.dte_is_waiting = TRUE;
@@ -1503,6 +1506,7 @@ static void hdlc_rx_status(void *user_data, int status)
                 s->modem = FAX_MODEM_SILENCE_TX;
                 t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
                 s->rx_frame_received = FALSE;
+                s->audio.modems.rx_frame_received = FALSE;
                 at_put_response_code(&s->at_state, AT_RESPONSE_CODE_FCERROR);
             }
         }
@@ -1515,6 +1519,7 @@ static void hdlc_rx_status(void *user_data, int status)
                     /* Report CONNECT as soon as possible to avoid a timeout. */
                     at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
                     s->rx_frame_received = TRUE;
+                    s->audio.modems.rx_frame_received = TRUE;
                 }
                 else
                 {
@@ -1553,6 +1558,7 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
             /* Report CONNECT as soon as possible to avoid a timeout. */
             at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
             s->rx_frame_received = TRUE;
+            s->audio.modems.rx_frame_received = TRUE;
         }
         else
         {
@@ -1589,6 +1595,7 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
                 at_put_response_code(&s->at_state, (ok)  ?  AT_RESPONSE_CODE_OK  :  AT_RESPONSE_CODE_ERROR);
                 s->at_state.dte_is_waiting = FALSE;
                 s->rx_frame_received = FALSE;
+                s->audio.modems.rx_frame_received = FALSE;
             }
         }
         else
@@ -1632,8 +1639,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
     s->tx.final = FALSE;
     s->at_state.rx_signal_present = FALSE;
     s->at_state.rx_trained = FALSE;
+    s->audio.modems.rx_trained = FALSE;
     s->rx_frame_received = FALSE;
-    set_rx_handler(s, (span_rx_handler_t) &span_dummy_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
+    s->audio.modems.rx_frame_received = FALSE;
+    fax_modems_set_rx_handler(t, (span_rx_handler_t) &span_dummy_rx, NULL, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
     use_hdlc = FALSE;
     switch (s->modem)
     {
@@ -1652,10 +1661,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
             /* Do V.21/HDLC receive in parallel. The other end may send its
                first message at any time. The CNG tone will continue until
                we get a valid preamble. */
-            set_rx_handler(s, (span_rx_handler_t) &cng_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
             t31_v21_rx(s);
-            set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            fax_modems_set_rx_handler(t, (span_rx_handler_t) &cng_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
+            fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
+            fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
         s->at_state.transmit = TRUE;
         break;
@@ -1665,10 +1674,10 @@ static int restart_modem(t31_state_t *s, int new_modem)
         }
         else
         {
-            set_rx_handler(s, (span_rx_handler_t) &cng_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
             t31_v21_rx(s);
+            fax_modems_set_rx_handler(t, (span_rx_handler_t) &cng_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
             silence_gen_set(&t->silence_gen, 0);
-            set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+            fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
         }
         s->at_state.transmit = FALSE;
         break;
@@ -1682,8 +1691,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
         else
         {
             modem_connect_tones_tx_init(&t->connect_tx, MODEM_CONNECT_TONES_FAX_CED);
-            set_tx_handler(s, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            fax_modems_set_tx_handler(t, (span_tx_handler_t) &modem_connect_tones_tx, &t->connect_tx);
+            fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
         s->at_state.transmit = TRUE;
         break;
@@ -1702,8 +1711,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
             /* 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);
-            set_tx_handler(s, (span_tx_handler_t) &fsk_tx, &t->v21_tx);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            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);
         }
         s->hdlc_tx.final = FALSE;
         s->hdlc_tx.len = 0;
@@ -1716,8 +1725,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
         }
         else
         {
-            set_rx_handler(s, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
             t31_v21_rx(s);
+            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 FAX_MODEM_V17_TX:
@@ -1748,8 +1757,8 @@ 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);
-            set_tx_handler(s, (span_tx_handler_t) &v17_tx, &t->fast_modems.v17_tx);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            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);
         }
         s->tx.out_bytes = 0;
         s->tx.data_started = FALSE;
@@ -1758,7 +1767,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
     case FAX_MODEM_V17_RX:
         if (!s->t38_mode)
         {
-            set_rx_handler(s, (span_rx_handler_t) &v17_v21_rx, (span_rx_fillin_handler_t) &v17_v21_rx_fillin, s);
+            fax_modems_set_rx_handler(t, (span_rx_handler_t) &v17_v21_rx, s, (span_rx_fillin_handler_t) &v17_v21_rx_fillin, s);
             v17_rx_restart(&t->fast_modems.v17_rx, s->bit_rate, s->short_train);
             /* Allow for +FCERROR/+FRH:3 */
             t31_v21_rx(s);
@@ -1785,8 +1794,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
         else
         {
             v27ter_tx_restart(&t->fast_modems.v27ter_tx, s->bit_rate, FALSE);
-            set_tx_handler(s, (span_tx_handler_t) &v27ter_tx, &t->fast_modems.v27ter_tx);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            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);
         }
         s->tx.out_bytes = 0;
         s->tx.data_started = FALSE;
@@ -1795,7 +1804,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
     case FAX_MODEM_V27TER_RX:
         if (!s->t38_mode)
         {
-            set_rx_handler(s, (span_rx_handler_t) &v27ter_v21_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, s);
+            fax_modems_set_rx_handler(t, (span_rx_handler_t) &v27ter_v21_rx, s, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, s);
             v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->bit_rate, FALSE);
             /* Allow for +FCERROR/+FRH:3 */
             t31_v21_rx(s);
@@ -1822,8 +1831,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
         else
         {
             v29_tx_restart(&t->fast_modems.v29_tx, s->bit_rate, FALSE);
-            set_tx_handler(s, (span_tx_handler_t) &v29_tx, &t->fast_modems.v29_tx);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            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);
         }
         s->tx.out_bytes = 0;
         s->tx.data_started = FALSE;
@@ -1832,7 +1841,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
     case FAX_MODEM_V29_RX:
         if (!s->t38_mode)
         {
-            set_rx_handler(s, (span_rx_handler_t) &v29_v21_rx, (span_rx_fillin_handler_t) &v29_v21_rx_fillin, s);
+            fax_modems_set_rx_handler(t, (span_rx_handler_t) &v29_v21_rx, s, (span_rx_fillin_handler_t) &v29_v21_rx_fillin, s);
             v29_rx_restart(&t->fast_modems.v29_rx, s->bit_rate, FALSE);
             /* Allow for +FCERROR/+FRH:3 */
             t31_v21_rx(s);
@@ -1853,18 +1862,18 @@ static int restart_modem(t31_state_t *s, int new_modem)
         else
         {
             silence_gen_set(&t->silence_gen, 0);
-            set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+            fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
         s->at_state.transmit = FALSE;
         break;
     case FAX_MODEM_SILENCE_RX:
         if (!s->t38_mode)
         {
-            set_rx_handler(s, (span_rx_handler_t) &silence_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, s);
+            fax_modems_set_rx_handler(t, (span_rx_handler_t) &silence_rx, s, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
             silence_gen_set(&t->silence_gen, 0);
-            set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+            fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
         }
         s->at_state.transmit = FALSE;
         break;
@@ -1881,8 +1890,8 @@ static int restart_modem(t31_state_t *s, int new_modem)
         {
             s->modem = FAX_MODEM_SILENCE_TX;
             silence_gen_alter(&t->silence_gen, ms_to_samples(200));
-            set_tx_handler(s, (span_tx_handler_t) &silence_gen, &t->silence_gen);
-            set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+            fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
+            fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
             s->at_state.transmit = TRUE;
         }
         break;
@@ -2055,6 +2064,7 @@ static int process_class1_cmd(at_state_t *t, void *user_data, int direction, int
             /* Send straight away, if there is something queued. */
             t31_set_at_rx_mode(s, AT_MODE_DELIVERY);
             s->rx_frame_received = FALSE;
+            s->audio.modems.rx_frame_received = FALSE;
             do
             {
                 if (!queue_empty(s->rx_queue))
@@ -2225,7 +2235,7 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
             s->at_state.rx_data_bytes = 0;
             s->at_state.transmit = FALSE;
             s->modem = FAX_MODEM_SILENCE_TX;
-            set_rx_handler(s, (span_rx_handler_t) &span_dummy_rx, (span_rx_fillin_handler_t) &span_dummy_rx_fillin, NULL);
+            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);
             t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
             at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK);
         }
@@ -2251,31 +2261,6 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
 }
 /*- End of function --------------------------------------------------------*/
 
-static void set_rx_handler(t31_state_t *s,
-                           span_rx_handler_t rx_handler,
-                           span_rx_fillin_handler_t fillin_handler,
-                           void *user_data)
-{
-    s->audio.modems.rx_handler = rx_handler;
-    s->audio.modems.rx_fillin_handler = fillin_handler;
-    s->audio.modems.rx_user_data = user_data;
-}
-/*- End of function --------------------------------------------------------*/
-
-static void set_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data)
-{
-    s->audio.modems.tx_handler = handler;
-    s->audio.modems.tx_user_data = user_data;
-}
-/*- End of function --------------------------------------------------------*/
-
-static void set_next_tx_handler(t31_state_t *s, span_tx_handler_t handler, void *user_data)
-{
-    s->audio.modems.next_tx_handler = handler;
-    s->audio.modems.next_tx_user_data = user_data;
-}
-/*- End of function --------------------------------------------------------*/
-
 static int silence_rx(void *user_data, const int16_t amp[], int len)
 {
     t31_state_t *s;
@@ -2326,8 +2311,8 @@ 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(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
+        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
     {
@@ -2336,8 +2321,8 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
         {
             /* We have received something, and the fast modem has not trained. We must
                be receiving valid V.21 */
-            span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
+            span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
+            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;
@@ -2369,8 +2354,8 @@ 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(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_rx_fillin, &s->fast_modems.v27ter_rx);
+        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
     {
@@ -2379,8 +2364,8 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
         {
             /* We have received something, and the fast modem has not trained. We must
                be receiving valid V.21 */
-            span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
+            span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
+            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;
@@ -2413,7 +2398,7 @@ 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(t, (span_rx_handler_t) &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
     {
@@ -2422,8 +2407,8 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
         {
             /* We have received something, and the fast modem has not trained. We must
                be receiving valid V.21 */
-            span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
+            span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
+            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;
@@ -2535,14 +2520,14 @@ static int set_next_tx_type(t31_state_t *s)
 {
     if (s->audio.next_tx_handler)
     {
-        set_tx_handler(s, s->audio.next_tx_handler, s->audio.next_tx_user_data);
-        set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+        fax_modems_set_tx_handler(&s->audio.modems, s->audio.next_tx_handler, s->audio.next_tx_user_data);
+        fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
         return 0;
     }
     /* There is nothing else to change to, so use zero length silence */
     silence_gen_alter(&s->audio.modems.silence_gen, 0);
-    set_tx_handler(s, (span_tx_handler_t) &silence_gen, &s->audio.modems.silence_gen);
-    set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+    fax_modems_set_tx_handler(&s->audio.modems, (span_tx_handler_t) &silence_gen, &s->audio.modems.silence_gen);
+    fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
     return -1;
 }
 /*- End of function --------------------------------------------------------*/
@@ -2671,9 +2656,7 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
                                      t38_tx_packet_handler_t tx_t38_packet_handler,
                                      void *tx_t38_packet_user_data)
 {
-#if 0
     v8_parms_t v8_parms;
-#endif
     int alloced;
 
     if (at_tx_handler == NULL  ||  modem_control_handler == NULL)
@@ -2700,7 +2683,6 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
                     non_ecm_get_bit,
                     tone_detected,
                     (void *) s);
-#if 0
     v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
     v8_parms.call_function = V8_CALL_T30_RX;
     v8_parms.modulations = V8_MOD_V21
@@ -2717,12 +2699,12 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
     v8_parms.t66 = -1;
     v8_init(&s->audio.v8, FALSE, &v8_parms, v8_handler, s);
 
-#endif
     power_meter_init(&s->audio.rx_power, 4);
     s->audio.last_sample = 0;
     s->audio.silence_threshold_power = power_meter_level_dbm0(-36);
     s->at_state.rx_signal_present = FALSE;
     s->at_state.rx_trained = FALSE;
+    s->audio.modems.rx_trained = FALSE;
 
     s->at_state.do_hangup = FALSE;
     s->at_state.line_ptr = 0;
index 11b653face5908f08d8ce7dc5c7816258738849b..570cbdc6257cd17c4c3a8be8a526149d200056e2 100644 (file)
@@ -196,7 +196,11 @@ static void non_ecm_remove_fill_and_put_bit(void *user_data, int bit);
 static void non_ecm_push_residue(t38_gateway_state_t *s);
 static void tone_detected(void *user_data, int tone, int level, int delay);
 
-static void set_rx_handler(t38_gateway_state_t *s, span_rx_handler_t handler, span_rx_fillin_handler_t fillin_handler, void *user_data)
+static void set_rx_handler(t38_gateway_state_t *s,
+                           span_rx_handler_t handler,
+                           void *user_data,
+                           span_rx_fillin_handler_t fillin_handler,
+                           void *rx_fillin_user_data)
 {
     if (s->audio.modems.rx_handler != span_dummy_rx)
     {
@@ -207,6 +211,7 @@ static void set_rx_handler(t38_gateway_state_t *s, span_rx_handler_t handler, sp
     s->audio.base_rx_handler = handler;
     s->audio.base_rx_fillin_handler = fillin_handler;
     s->audio.modems.rx_user_data = user_data;
+    s->audio.modems.rx_fillin_user_data = rx_fillin_user_data;
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -257,7 +262,7 @@ 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(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->fast_modems.v17_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
+        set_rx_handler(t, (span_rx_handler_t) &v17_rx, &s->fast_modems.v17_rx, (span_rx_fillin_handler_t) &v17_rx_fillin, &s->fast_modems.v17_rx);
     }
     else
     {
@@ -265,7 +270,7 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
         if (s->rx_signal_present)
         {
             span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
+            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
         }
         /*endif*/
     }
@@ -300,7 +305,7 @@ 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(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->fast_modems.v27ter_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, &s->fast_modems.v27ter_rx);
+        set_rx_handler(t, (span_rx_handler_t) &v27ter_rx, &s->fast_modems.v27ter_rx, (span_rx_fillin_handler_t) &v27ter_v21_rx_fillin, &s->fast_modems.v27ter_rx);
     }
     else
     {
@@ -308,7 +313,7 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
         if (s->rx_signal_present)
         {
             span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
+            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
         }
         /*endif*/
     }
@@ -343,7 +348,7 @@ 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(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->fast_modems.v29_rx));
-        set_rx_handler(t, (span_rx_handler_t) &v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
+        set_rx_handler(t, (span_rx_handler_t) &v29_rx, &s->fast_modems.v29_rx, (span_rx_fillin_handler_t) &v29_rx_fillin, &s->fast_modems.v29_rx);
     }
     else
     {
@@ -351,7 +356,7 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
         if (s->rx_signal_present)
         {
             span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
-            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
+            set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx);
         }
         /*endif*/
     }
@@ -422,6 +427,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
     int short_train;
     fax_modems_state_t *t;
     t38_gateway_hdlc_state_t *u;
+    int bit_rate;
 
     t = &s->audio.modems;
     t38_non_ecm_buffer_report_output_status(&s->core.non_ecm_to_modem, &s->logging);
@@ -511,16 +517,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
         break;
     case T38_IND_V27TER_2400_TRAINING:
     case T38_IND_V27TER_4800_TRAINING:
-        switch (indicator)
-        {
-        case T38_IND_V27TER_2400_TRAINING:
-            t->tx_bit_rate = 2400;
-            break;
-        case T38_IND_V27TER_4800_TRAINING:
-            t->tx_bit_rate = 4800;
-            break;
-        }
-        /*endswitch*/
+        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, get_bit_func, get_bit_user_data);
@@ -530,16 +528,8 @@ static int set_next_tx_type(t38_gateway_state_t *s)
         break;
     case T38_IND_V29_7200_TRAINING:
     case T38_IND_V29_9600_TRAINING:
-        switch (indicator)
-        {
-        case T38_IND_V29_7200_TRAINING:
-            t->tx_bit_rate = 7200;
-            break;
-        case T38_IND_V29_9600_TRAINING:
-            t->tx_bit_rate = 9600;
-            break;
-        }
-        /*endswitch*/
+        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, get_bit_func, get_bit_user_data);
@@ -560,34 +550,35 @@ static int set_next_tx_type(t38_gateway_state_t *s)
         {
         case T38_IND_V17_7200_SHORT_TRAINING:
             short_train = TRUE;
-            t->tx_bit_rate = 7200;
+            bit_rate = 7200;
             break;
         case T38_IND_V17_7200_LONG_TRAINING:
-            t->tx_bit_rate = 7200;
+            bit_rate = 7200;
             break;
         case T38_IND_V17_9600_SHORT_TRAINING:
             short_train = TRUE;
-            t->tx_bit_rate = 9600;
+            bit_rate = 9600;
             break;
         case T38_IND_V17_9600_LONG_TRAINING:
-            t->tx_bit_rate = 9600;
+            bit_rate = 9600;
             break;
         case T38_IND_V17_12000_SHORT_TRAINING:
             short_train = TRUE;
-            t->tx_bit_rate = 12000;
+            bit_rate = 12000;
             break;
         case T38_IND_V17_12000_LONG_TRAINING:
-            t->tx_bit_rate = 12000;
+            bit_rate = 12000;
             break;
         case T38_IND_V17_14400_SHORT_TRAINING:
             short_train = TRUE;
-            t->tx_bit_rate = 14400;
+            bit_rate = 14400;
             break;
         case T38_IND_V17_14400_LONG_TRAINING:
-            t->tx_bit_rate = 14400;
+            bit_rate = 14400;
             break;
         }
         /*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, get_bit_func, get_bit_user_data);
@@ -1087,7 +1078,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
         span_log(&s->logging,
                  SPAN_LOG_FLOW,
                  "Changing - (%d) %s -> %s\n",
-                 silence_gen_remainder(&(s->audio.modems.silence_gen)),
+                 silence_gen_remainder(&s->audio.modems.silence_gen),
                  t38_indicator_to_str(t->current_rx_indicator),
                  t38_indicator_to_str(indicator));
         switch (s->t38x.current_rx_field_class)
@@ -1107,7 +1098,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
         span_log(&s->logging,
                  SPAN_LOG_FLOW,
                  "Queued change - (%d) %s -> %s\n",
-                 silence_gen_remainder(&(s->audio.modems.silence_gen)),
+                 silence_gen_remainder(&s->audio.modems.silence_gen),
                  t38_indicator_to_str(t->current_rx_indicator),
                  t38_indicator_to_str(indicator));
     }
@@ -2159,23 +2150,23 @@ static int restart_rx_modem(t38_gateway_state_t *s)
     case FAX_MODEM_V27TER_RX:
         v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->core.fast_bit_rate, FALSE);
         v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data);
-        set_rx_handler(s, &v27ter_v21_rx, &v27ter_v21_rx_fillin, s);
+        set_rx_handler(s, &v27ter_v21_rx, s, &v27ter_v21_rx_fillin, s);
         s->core.fast_rx_active = FAX_MODEM_V27TER_RX;
         break;
     case FAX_MODEM_V29_RX:
         v29_rx_restart(&t->fast_modems.v29_rx, s->core.fast_bit_rate, FALSE);
         v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data);
-        set_rx_handler(s, &v29_v21_rx, &v29_v21_rx_fillin, s);
+        set_rx_handler(s, &v29_v21_rx, s, &v29_v21_rx_fillin, s);
         s->core.fast_rx_active = FAX_MODEM_V29_RX;
         break;
     case FAX_MODEM_V17_RX:
         v17_rx_restart(&t->fast_modems.v17_rx, s->core.fast_bit_rate, s->core.short_train);
         v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data);
-        set_rx_handler(s, &v17_v21_rx, &v17_v21_rx_fillin, s);
+        set_rx_handler(s, &v17_v21_rx, s, &v17_v21_rx_fillin, s);
         s->core.fast_rx_active = FAX_MODEM_V17_RX;
         break;
     default:
-        set_rx_handler(s, (span_rx_handler_t) &fsk_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
+        set_rx_handler(s, (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;
     }
@@ -2233,7 +2224,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], i
 #endif
     update_rx_timing(s, len);
     for (i = 0;  i < len;  i++)
-        amp[i] = dc_restore(&(s->audio.modems.dc_restore), amp[i]);
+        amp[i] = dc_restore(&s->audio.modems.dc_restore, amp[i]);
     /*endfor*/
     s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
     return 0;
@@ -2263,7 +2254,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len)
 #endif
     update_rx_timing(s, len);
     /* TODO: handle the modems properly */
-    s->audio.modems.rx_fillin_handler(s->audio.modems.rx_user_data, len);
+    s->audio.modems.rx_fillin_handler(s->audio.modems.rx_fillin_user_data, len);
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -2284,7 +2275,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], i
             len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp + len, max_len - len);
             if (len < max_len)
             {
-                silence_gen_set(&(s->audio.modems.silence_gen), 0);
+                silence_gen_set(&s->audio.modems.silence_gen, 0);
                 set_next_tx_type(s);
             }
             /*endif*/