]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Fixed updating of the modem type after a FAX ECM CTC.
authorSteve Underwood <steveu@coppice.org>
Sat, 28 Jun 2014 08:43:05 +0000 (16:43 +0800)
committerSteve Underwood <steveu@coppice.org>
Sat, 28 Jun 2014 08:43:05 +0000 (16:43 +0800)
libs/spandsp/src/spandsp/private/t38_gateway.h
libs/spandsp/src/spandsp/t38_gateway.h
libs/spandsp/src/t38_gateway.c

index 23c6dd59bf1b4a7f43242a2cece24e064476a2ad..5d3a3eb23bdfe6f30621efd0f59dd4e201893ca7 100644 (file)
@@ -46,6 +46,10 @@ typedef struct
     /*! \brief If NSF, NSC, and NSS are to be suppressed by altering their contents to
                something the far end will not recognise, this is the amount to overwrite. */
     int suppress_nsx_len[2];
+    /*! \brief If NSF, NSC, and NSS are to be suppressed by altering their contents to
+               something the far end will not recognise, this is the string to use for overwriting. */
+    uint8_t suppress_nsx_string[2][MAX_NSX_SUPPRESSION];
+
     /*! \brief True if we need to corrupt the HDLC frame in progress, so the receiver cannot
                interpret it. The two values are for the two directions. */
     bool corrupt_current_frame[2];
index 89bd9b116df5f9f16ab8ea341a48cd1d42489c5e..4c68b7ff4aeecf3b87b7ec9fcf4a602f8a92c2ce 100644 (file)
@@ -38,6 +38,10 @@ to maximum the tolerance of jitter and packet loss on the IP network.
 \section t38_gateway_page_sec_2 How does it work?
 */
 
+/*! The maximum number of bytes to be zapped, in order to corrupt NSF,
+    NSS and NSC messages, so the receiver does not recognise them. */
+#define MAX_NSX_SUPPRESSION             10
+
 typedef struct t38_gateway_state_s t38_gateway_state_t;
 
 /*!
index 8535f2d59c00779c34272203d3ea636766ae561d..646c3fee9a8ada56ffd550ea981a37ad05a9db40 100644 (file)
 /*! The number of transmissions of terminating data IFP packets */
 #define DATA_END_TX_COUNT                       3
 
+/*! The number of consecutive flags to declare HDLC framing is OK. */
+#define HDLC_FRAMING_OK_THRESHOLD       5
+
 enum
 {
     DISBIT1 = 0x01,
@@ -184,19 +187,6 @@ enum
     TIMED_MODE_TCF_PREDICTABLE_MODEM_START_BEGIN,
 };
 
-/*! The maximum number of bytes to be zapped, in order to corrupt NSF,
-    NSS and NSC messages, so the receiver does not recognise them. */
-#define MAX_NSX_SUPPRESSION             10
-
-/*! The number of consecutive flags to declare HDLC framing is OK. */
-#define HDLC_FRAMING_OK_THRESHOLD       5
-
-static uint8_t nsx_overwrite[2][MAX_NSX_SUPPRESSION] =
-{
-    {0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-};
-
 static int restart_rx_modem(t38_gateway_state_t *s);
 static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indicator);
 static void hdlc_underflow_handler(void *user_data);
@@ -485,18 +475,18 @@ static void finalise_hdlc_frame(t38_gateway_state_t *s, int good_fcs)
 }
 /*- End of function --------------------------------------------------------*/
 
-static void edit_control_messages(t38_gateway_state_t *s, int from_modem, uint8_t *buf, int len)
+static void edit_control_messages(t38_gateway_state_t *s, bool from_modem, uint8_t *buf, int len)
 {
     /* Frames need to be fed to this routine byte by byte as they arrive. It basically just
        edits the last byte received, based on the frame up to that point. */
-    if (s->t38x.corrupt_current_frame[from_modem])
+    if (s->t38x.corrupt_current_frame[(from_modem)  ?  1  :  0])
     {
         /* We simply need to overwrite a section of the message, so it is not recognisable at
            the receiver. This is used for the NSF, NSC, and NSS messages. Several strategies are
            possible for the replacement data. If you have a manufacturer code of your own, the
            sane thing is to overwrite the original data with that. */
-        if (len <= s->t38x.suppress_nsx_len[from_modem])
-            buf[len - 1] = nsx_overwrite[from_modem][len - 4];
+        if (len <= s->t38x.suppress_nsx_len[(from_modem)  ?  1  :  0])
+            buf[len - 1] = s->t38x.suppress_nsx_string[(from_modem)  ?  1  :  0][len - 1 - 3];
         /*endif*/
         return;
     }
@@ -510,13 +500,13 @@ static void edit_control_messages(t38_gateway_state_t *s, int from_modem, uint8_
         case T30_NSF:
         case T30_NSC:
         case T30_NSS:
-            if (s->t38x.suppress_nsx_len[from_modem])
+            if (s->t38x.suppress_nsx_len[(from_modem)  ?  1  :  0])
             {
                 /* Corrupt the message, so it will be ignored by the far end. If it were
                    processed, 2 machines which recognise each other might do special things
                    we cannot handle as a middle man. */
                 span_log(&s->logging, SPAN_LOG_FLOW, "Corrupting %s message to prevent recognition\n", t30_frametype(buf[2]));
-                s->t38x.corrupt_current_frame[from_modem] = true;
+                s->t38x.corrupt_current_frame[(from_modem)  ?  1  :  0] = true;
             }
             /*endif*/
             break;
@@ -603,7 +593,7 @@ static void edit_control_messages(t38_gateway_state_t *s, int from_modem, uint8_
 /*- End of function --------------------------------------------------------*/
 
 static void monitor_control_messages(t38_gateway_state_t *s,
-                                     int from_modem,
+                                     bool from_modem,
                                      const uint8_t *buf,
                                      int len)
 {
@@ -664,6 +654,27 @@ static void monitor_control_messages(t38_gateway_state_t *s,
         s->core.image_data_mode = false;
         s->core.short_train = false;
         break;
+    case T30_CTC:
+        if (len >= 5)
+        {
+            /* The table is short, and not searched often, so a brain-dead linear scan seems OK */
+            dcs_code = buf[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3);
+            for (i = 0;  modem_codes[i].bit_rate;  i++)
+            {
+                if (modem_codes[i].dcs_code == dcs_code)
+                    break;
+                /*endif*/
+            }
+            /*endfor*/
+            /* If we are processing a message from the modem side, the contents determine the fast receive modem.
+               we are to use. If it comes from the T.38 side the contents do not. */
+            s->core.fast_bit_rate = modem_codes[i].bit_rate;
+            if (from_modem)
+                s->core.fast_rx_modem = modem_codes[i].modem_type;
+            /*endif*/
+        }
+        /*endif*/
+        break;
     case T30_CTR:
         /* T.30 says the first image data after this does full training, yet does not
            return to TCF. This seems to be the sole case of long training for image
@@ -1981,13 +1992,13 @@ static int restart_rx_modem(t38_gateway_state_t *s)
              s->core.ecm_mode);
 
     t = &s->audio.modems;
-    hdlc_rx_init(&t->hdlc_rx, false, true, HDLC_FRAMING_OK_THRESHOLD, NULL, s);
     t->rx_signal_present = false;
     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);
+    hdlc_rx_init(&t->hdlc_rx, false, true, HDLC_FRAMING_OK_THRESHOLD, NULL, s);
 #if 0
     fsk_rx_signal_cutoff(&t->v21_rx, -39.09f);
 #endif
@@ -2209,8 +2220,14 @@ SPAN_DECLARE(void) t38_gateway_set_nsx_suppression(t38_gateway_state_t *s,
                                                    const uint8_t *from_modem,
                                                    int from_modem_len)
 {
-    s->t38x.suppress_nsx_len[0] = (from_t38_len < 0  ||  from_t38_len < MAX_NSX_SUPPRESSION)  ?  (from_t38_len + 3)  :  0;
-    s->t38x.suppress_nsx_len[1] = (from_modem_len < 0  ||  from_modem_len < MAX_NSX_SUPPRESSION)  ?  (from_modem_len + 3)  :  0;
+    if (from_t38_len >= 0)
+        s->t38x.suppress_nsx_len[0] = ((from_t38_len < MAX_NSX_SUPPRESSION)  ?  from_t38_len  :  MAX_NSX_SUPPRESSION) + 3;
+    if (from_t38)
+        memcpy(s->t38x.suppress_nsx_string[0], from_t38, s->t38x.suppress_nsx_len[0]);
+    if (from_modem_len >= 0)
+        s->t38x.suppress_nsx_len[1] = ((from_modem_len < MAX_NSX_SUPPRESSION)  ?  from_modem_len  :  MAX_NSX_SUPPRESSION) + 3;
+    if (from_modem)
+        memcpy(s->t38x.suppress_nsx_string[1], from_modem, s->t38x.suppress_nsx_len[1]);
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -2302,7 +2319,7 @@ SPAN_DECLARE(t38_gateway_state_t *) t38_gateway_init(t38_gateway_state_t *s,
 
     fax_modems_set_rx_active(&s->audio.modems, true);
     t38_gateway_set_supported_modems(s, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
-    t38_gateway_set_nsx_suppression(s, (const uint8_t *) "\x00\x00\x00", 3, (const uint8_t *) "\x00\x00\x00", 3);
+    t38_gateway_set_nsx_suppression(s, (const uint8_t *) "\xFF\x00\x00", 3, (const uint8_t *) "\xFF\x00\x00", 3);
 
     s->core.to_t38.octets_per_data_packet = 1;
     s->core.ecm_allowed = true;