]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
More tweaks for spandsp.
authorSteve Underwood <steveu@i7.coppice.org>
Wed, 4 Jul 2012 15:57:30 +0000 (23:57 +0800)
committerSteve Underwood <steveu@i7.coppice.org>
Wed, 4 Jul 2012 15:57:30 +0000 (23:57 +0800)
17 files changed:
libs/spandsp/src/dtmf.c
libs/spandsp/src/hdlc.c
libs/spandsp/src/make_modem_filter.c
libs/spandsp/src/modem_connect_tones.c
libs/spandsp/src/spandsp/modem_connect_tones.h
libs/spandsp/src/spandsp/private/super_tone_rx.h
libs/spandsp/src/spandsp/private/v22bis.h
libs/spandsp/src/spandsp/v8.h
libs/spandsp/src/super_tone_rx.c
libs/spandsp/src/t38_gateway.c
libs/spandsp/src/v18.c
libs/spandsp/src/v22bis_rx.c
libs/spandsp/src/v22bis_tx.c
libs/spandsp/src/v8.c
libs/spandsp/src/vector_float.c
libs/spandsp/tests/fax_tester.h
libs/spandsp/tests/udptl.h

index 35dc6c9dd1ce240ae747bf9902a0eccb19c8d966..ac1656360eb5f857c8be2641b03477f27a9798ac 100644 (file)
@@ -258,45 +258,42 @@ SPAN_DECLARE(int) dtmf_rx(dtmf_rx_state_t *s, const int16_t amp[], int samples)
                   Note this is only relevant to VoIP using A-law, u-law or similar.
                   Low bit rate codecs scramble DTMF too much for it to be recognised,
                   and often slip in units larger than a sample. */
-        if (hit != s->in_digit)
+        if (hit != s->in_digit  &&  s->last_hit != s->in_digit)
         {
-            if (s->last_hit != s->in_digit)
+            /* We have two successive indications that something has changed. */
+            /* To declare digit on, the hits must agree. Otherwise we declare tone off. */
+            hit = (hit  &&  hit == s->last_hit)  ?  hit   :  0;
+            if (s->realtime_callback)
             {
-                /* We have two successive indications that something has changed. */
-                /* To declare digit on, the hits must agree. Otherwise we declare tone off. */
-                hit = (hit  &&  hit == s->last_hit)  ?  hit   :  0;
-                if (s->realtime_callback)
+                /* Avoid reporting multiple no digit conditions on flaky hits */
+                if (s->in_digit  ||  hit)
                 {
-                    /* Avoid reporting multiple no digit conditions on flaky hits */
-                    if (s->in_digit  ||  hit)
-                    {
-                        i = (s->in_digit  &&  !hit)  ?  -99  :  lfastrintf(log10f(s->energy)*10.0f - DTMF_POWER_OFFSET + DBM0_MAX_POWER);
-                        s->realtime_callback(s->realtime_callback_data, hit, i, s->duration);
-                        s->duration = 0;
-                    }
+                    i = (s->in_digit  &&  !hit)  ?  -99  :  lfastrintf(log10f(s->energy)*10.0f - DTMF_POWER_OFFSET + DBM0_MAX_POWER);
+                    s->realtime_callback(s->realtime_callback_data, hit, i, s->duration);
+                    s->duration = 0;
                 }
-                else
+            }
+            else
+            {
+                if (hit)
                 {
-                    if (hit)
+                    if (s->current_digits < MAX_DTMF_DIGITS)
                     {
-                        if (s->current_digits < MAX_DTMF_DIGITS)
+                        s->digits[s->current_digits++] = (char) hit;
+                        s->digits[s->current_digits] = '\0';
+                        if (s->digits_callback)
                         {
-                            s->digits[s->current_digits++] = (char) hit;
-                            s->digits[s->current_digits] = '\0';
-                            if (s->digits_callback)
-                            {
-                                s->digits_callback(s->digits_callback_data, s->digits, s->current_digits);
-                                s->current_digits = 0;
-                            }
-                        }
-                        else
-                        {
-                            s->lost_digits++;
+                            s->digits_callback(s->digits_callback_data, s->digits, s->current_digits);
+                            s->current_digits = 0;
                         }
                     }
+                    else
+                    {
+                        s->lost_digits++;
+                    }
                 }
-                s->in_digit = hit;
             }
+            s->in_digit = hit;
         }
         s->last_hit = hit;
 #if defined(SPANDSP_USE_FIXED_POINT)
@@ -333,7 +330,7 @@ SPAN_DECLARE(int) dtmf_rx_fillin(dtmf_rx_state_t *s, int samples)
 #endif
     s->current_sample = 0;
     /* Don't update the hit detection. Pretend it never happened. */
-    /* TODO: Surely we can be cleverer than this. */
+    /* TODO: Surely we can be cleverer than this. */
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -359,7 +356,7 @@ SPAN_DECLARE(size_t) dtmf_rx_get(dtmf_rx_state_t *s, char *buf, int max)
         s->current_digits -= max;
     }
     buf[max] = '\0';
-    return  max;
+    return max;
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -417,7 +414,7 @@ SPAN_DECLARE(dtmf_rx_state_t *) dtmf_rx_init(dtmf_rx_state_t *s,
     if (s == NULL)
     {
         if ((s = (dtmf_rx_state_t *) malloc(sizeof (*s))) == NULL)
-            return  NULL;
+            return NULL;
     }
     memset(s, 0, sizeof(*s));
     span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
@@ -570,7 +567,7 @@ SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s)
     if (s == NULL)
     {
         if ((s = (dtmf_tx_state_t *) malloc(sizeof (*s))) == NULL)
-            return  NULL;
+            return NULL;
     }
     memset(s, 0, sizeof(*s));
     if (!dtmf_tx_inited)
index fc401fb5d13eeea3dc20ad6e8a2491a9e3812934..d08ab1a05e4644ca95df7b59056b17e0493371d8 100644 (file)
@@ -154,7 +154,8 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
                         s->rx_frames++;
                         s->rx_bytes += s->len - s->crc_bytes;
                         s->len -= s->crc_bytes;
-                        s->frame_handler(s->frame_user_data, s->buffer, s->len, TRUE);
+                        if (s->frame_handler)
+                            s->frame_handler(s->frame_user_data, s->buffer, s->len, TRUE);
                     }
                     else
                     {
@@ -162,7 +163,8 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
                         if (s->report_bad_frames)
                         {
                             s->len -= s->crc_bytes;
-                            s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
+                            if (s->frame_handler)
+                                s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
                         }
                     }
                 }
@@ -177,7 +179,8 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
                             s->len -= s->crc_bytes;
                         else
                             s->len = 0;
-                        s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
+                        if (s->frame_handler)
+                            s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
                     }
                     s->rx_length_errors++;
                 }
index aa58ac301b2384a80803edf8c3debb2c4d9279e6..9bf49eb0aa64675db620a054c8e65d9db535b34c 100644 (file)
@@ -450,6 +450,151 @@ int main(int argc, char **argv)
         rx_tag = "";
         tx_tag = "";
     }
+    else if (strcmp(modem, "V.34_2400") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 10;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1600.0;
+        baud_rate = 2400.0;
+        rx_tag = "_2400_low_carrier";
+        tx_tag = "_2400";
+    }
+    else if (strcmp(modem, "V.34_2400_high") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 10;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1800.0;
+        baud_rate = 2400.0;
+        rx_tag = "_2400_high_carrier";
+        tx_tag = "_2400";
+    }
+    else if (strcmp(modem, "V.34_2743") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 35;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1646.0;
+        baud_rate = 2400.0*8.0/7.0;
+        rx_tag = "_2743_low_carrier";
+        tx_tag = "_2743";
+    }
+    else if (strcmp(modem, "V.34_2743_high") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 35;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1829.0;
+        baud_rate = 2400.0*8.0/7.0;
+        rx_tag = "_2743_high_carrier";
+        tx_tag = "_2743";
+    }
+    else if (strcmp(modem, "V.34_2800") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 20;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1680.0;
+        baud_rate = 2400.0*7.0/6.0;
+        rx_tag = "_2800_low_carrier";
+        tx_tag = "_2800";
+    }
+    else if (strcmp(modem, "V.34_2800_high") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 20;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1867.0;
+        baud_rate = 2400.0*7.0/6.0;
+        rx_tag = "_2800_high_carrier";
+        tx_tag = "_2800";
+    }
+    else if (strcmp(modem, "V.34_3000") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 8;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1800.0;
+        baud_rate = 2400.0*5.0/4.0;
+        rx_tag = "_3000_low_carrier";
+        tx_tag = "_3000";
+    }
+    else if (strcmp(modem, "V.34_3000_high") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 8;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 2000.0;
+        baud_rate = 2400.0*5.0/4.0;
+        rx_tag = "_3000_high_carrier";
+        tx_tag = "_3000";
+    }
+    else if (strcmp(modem, "V.34_3200") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 5;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1829.0;
+        baud_rate = 2400.0*4.0/3.0;
+        rx_tag = "_3200_low_carrier";
+        tx_tag = "_3200";
+    }
+    else if (strcmp(modem, "V.34_3200_high") == 0)
+    {
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 5;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        carrier = 1920.0;
+        baud_rate = 2400.0*4.0/3.0;
+        rx_tag = "_3200_high_carrier";
+        tx_tag = "_3200";
+    }
+    else if (strcmp(modem, "V.34_3429") == 0)
+    {
+        /* There is only one carrier frequency defined for this baud rate */
+        rx_coeff_sets = 192;
+        rx_coeffs_per_filter = 27;
+        rx_excess_bandwidth = 0.25;
+        tx_coeff_sets = 7;
+        tx_coeffs_per_filter = 9;
+        tx_excess_bandwidth = 0.12;
+        //carrier = 1959.0;
+        carrier = 1959.0;
+        baud_rate = 2400.0*10.0/7.0;
+        rx_tag = "_3429";
+        tx_tag = "_3429";
+    }
     else
     {
         usage();
index 25e96b04d2555570fd74af9b0fc97bb7fd439bdc..4162286db8d55b4dc5bb1ed7c08cb03dbb62735d 100644 (file)
 /* CNG is 0.5s+-15% of 1100+-38Hz, 3s+-15% off, repeating.
 
    CED is 0.2s silence, 3.3+-0.7s of 2100+-15Hz, and 75+-20ms of silence.
-   
+
+   Calling tone is 0.5s-0.7s of 1300Hz+-15Hz, 1.5s-2.0s off, repeating.
+
    ANS is 3.3+-0.7s of 2100+-15Hz.
-   
+
    ANS/ is 3.3+-0.7s of 2100+-15Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms.
 
    ANSam/ is 2100+-1Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms, and AM with a sinewave of 15+-0.1Hz. 
@@ -92,6 +94,8 @@ SPAN_DECLARE(const char *) modem_connect_tone_to_str(int tone)
         return "FAX preamble";
     case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE:
         return "FAX CED or preamble";
+    case MODEM_CONNECT_TONES_CALLING_TONE:
+        return "Calling tone";
     }
     return "???";
 }
@@ -202,6 +206,29 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *
         }
         s->duration_timer -= len;
         break;
+    case MODEM_CONNECT_TONES_CALLING_TONE:
+        for (  ;  i < len;  i++)
+        {
+            if (s->duration_timer > ms_to_samples(2000))
+            {
+                if ((xlen = i + s->duration_timer - ms_to_samples(2000)) > len)
+                    xlen = len;
+                s->duration_timer -= (xlen - i);
+                for (  ;  i < xlen;  i++)
+                    amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
+            }
+            if (s->duration_timer > 0)
+            {
+                if ((xlen = i + s->duration_timer) > len)
+                    xlen = len;
+                s->duration_timer -= (xlen - i);
+                memset(amp + i, 0, sizeof(int16_t)*(xlen - i));
+                i = xlen;
+            }
+            if (s->duration_timer == 0)
+                s->duration_timer = ms_to_samples(600 + 2000);
+        }
+        break;
     }
     return len;
 }
@@ -274,6 +301,17 @@ SPAN_DECLARE(modem_connect_tones_tx_state_t *) modem_connect_tones_tx_init(modem
         s->mod_phase = 0;
         s->hop_timer = ms_to_samples(450);
         break;
+    case MODEM_CONNECT_TONES_CALLING_TONE:
+        /* 0.6s of 1300Hz+-15Hz + 2.0s of silence repeating. */
+        s->tone_phase_rate = dds_phase_rate(1300.0);
+        s->level = dds_scaling_dbm0(-11);
+        s->duration_timer = ms_to_samples(600 + 2000);
+        s->mod_phase_rate = 0;
+        s->tone_phase = 0;
+        s->mod_phase = 0;
+        s->mod_level = 0;
+        s->hop_timer = 0;
+        break;
     default:
         if (alloced)
             free(s);
@@ -402,6 +440,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
             famp = amp[i];
             /* A Cauer notch at 1100Hz, spread just wide enough to meet our detection bandwidth
                criteria. */
+            /* Poles 0.736618498*exp(+-1047/4000 * PI * j)
+               Zeroes exp(+-1099.5 * PI * j) */
             v1 = 0.792928f*famp + 1.0018744927985f*s->znotch_1 - 0.54196833412465f*s->znotch_2;
             famp = v1 - 1.2994747954630f*s->znotch_1 + s->znotch_2;
             s->znotch_2 = s->znotch_1;
@@ -446,6 +486,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
         {
             famp = amp[i];
             /* A Cauer bandpass at 15Hz, with which we demodulate the AM signal. */
+            /* Poles 0.9983989*exp(+-15/4000 * PI * j)
+               Zeroes exp(0 * PI * j) */
             v1 = fabs(famp) + 1.996667f*s->z15hz_1 - 0.9968004f*s->z15hz_2;
             filtered = 0.001599787f*(v1 - s->z15hz_2);
             s->z15hz_2 = s->z15hz_1;
@@ -454,8 +496,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
             //printf("%9.1f %10.4f %9d %9d\n", famp, filtered, s->am_level, s->channel_level);
             /* A Cauer notch at 2100Hz, spread just wide enough to meet our detection bandwidth
                criteria. */
-            /* This is actually centred at 2095Hz, but gets the balance we want, due
-               to the asymmetric walls of the notch */
+            /* Poles 0.7144255*exp(+-2105.612/4000 * PI * j)
+               Zeroes exp(+-2099.9 * PI * j) */
             v1 = 0.76000f*famp - 0.1183852f*s->znotch_1 - 0.5104039f*s->znotch_2;
             famp = v1 + 0.1567596f*s->znotch_1 + s->znotch_2;
             s->znotch_2 = s->znotch_1;
@@ -543,6 +585,44 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
             }
         }
         break;
+    case MODEM_CONNECT_TONES_CALLING_TONE:
+        for (i = 0;  i < len;  i++)
+        {
+            famp = amp[i];
+            /* A Cauer notch at 1300Hz, spread just wide enough to meet our detection bandwidth
+               criteria. */
+            /* Poles 0.736618498*exp(+-1247/4000 * PI * j)
+               Zeroes exp(+-1299.5 * PI * j) */
+            v1 = 0.755582f*famp + 0.820887174515f*s->znotch_1 - 0.541968324778f*s->znotch_2;
+            famp = v1 - 1.0456667108f*s->znotch_1 + s->znotch_2;
+            s->znotch_2 = s->znotch_1;
+            s->znotch_1 = v1;
+            notched = (int16_t) lfastrintf(famp);
+
+            /* Estimate the overall energy in the channel, and the energy in
+               the notch (i.e. overall channel energy - tone energy => noise).
+               Use abs instead of multiply for speed (is it really faster?). */
+            s->channel_level += ((abs(amp[i]) - s->channel_level) >> 5);
+            s->notch_level += ((abs(notched) - s->notch_level) >> 5);
+            if (s->channel_level > 70  &&  s->notch_level*6 < s->channel_level)
+            {
+                /* There is adequate energy in the channel, and it is mostly at 1300Hz. */
+                if (s->tone_present != MODEM_CONNECT_TONES_CALLING_TONE)
+                {
+                    if (++s->tone_cycle_duration >= ms_to_samples(415))
+                        report_tone_state(s, MODEM_CONNECT_TONES_CALLING_TONE, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
+                }
+            }
+            else
+            {
+                /* If the signal looks wrong, even for a moment, we consider this the
+                   end of the tone. */
+                if (s->tone_present == MODEM_CONNECT_TONES_CALLING_TONE)
+                    report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
+                s->tone_cycle_duration = 0;
+            }
+        }
+        break;
     }
     return 0;
 }
index db3831bf28ee6f8360c4928cd1796d8db95fd3d4..f0c0aaeb2ec6445db924d3d158f4eb7587d410c3 100644 (file)
@@ -75,7 +75,10 @@ enum
     /*! \brief CED tone is the same as ANS tone. FAX preamble in a string of V.21 HDLC flag octets.
                This is only valid as a tone type to receive. It is never reported as a detected tone
                type. The report will either be for FAX preamble or CED/ANS tone. */
-    MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE = 7
+    MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE = 7,
+    /*! \brief Calling tone is a pure 1300Hz tone, in 0.6s bursts, with 2s silences in between. The
+               bursts repeat for as long as is required. */
+    MODEM_CONNECT_TONES_CALLING_TONE = 8
 };
 
 /*! \brief FAX CED tone is the same as ANS tone. */
index 1f0fd985645b5da88efdac2337a014cb4c8fc172..e62d455d4773f26f464d679958e0c4a48ddfc695 100644 (file)
@@ -26,7 +26,7 @@
 #if !defined(_SPANDSP_PRIVATE_SUPER_TONE_RX_H_)
 #define _SPANDSP_PRIVATE_SUPER_TONE_RX_H_
 
-#define BINS            128
+#define SUPER_TONE_BINS             128
 
 struct super_tone_rx_segment_s
 {
@@ -41,7 +41,7 @@ struct super_tone_rx_descriptor_s
 {
     int used_frequencies;
     int monitored_frequencies;
-    int pitches[BINS/2][2];
+    int pitches[SUPER_TONE_BINS/2][2];
     int tones;
     super_tone_rx_segment_t **tone_list;
     int *tone_segs;
@@ -55,7 +55,7 @@ struct super_tone_rx_state_s
     int detected_tone;
     int rotation;
     tone_report_func_t tone_callback;
-    void (*segment_callback)(void *data, int f1, int f2, int duration);
+    tone_segment_func_t segment_callback;
     void *callback_data;
     super_tone_rx_segment_t segments[11];
     goertzel_state_t state[];
index d5016430e9c47f38be5facf669249c58f3d65179..dca574df77710939335e6aee530d74b13ca4bd22 100644 (file)
@@ -209,7 +209,7 @@ struct v22bis_state_s
         uint32_t guard_phase;
         /*! \brief The update rate for the phase of the guard tone (i.e. the DDS increment). */
         int32_t guard_phase_rate;
-        float guard_level;
+        float guard_tone_gain;
         /*! \brief The current fractional phase of the baud timing. */
         int baud_phase;
         /*! \brief The code number for the current position in the constellation. */
index 152c478fad28e5648649bc282e7ba63c6e2b1964..fa9df4a0c56ea16ad2f35854a07db6da5784ce34 100644 (file)
@@ -118,6 +118,8 @@ struct v8_parms_s
 {
     int status;
     int modem_connect_tone;
+    int send_ci;
+    int v92;
     int call_function;
     unsigned int modulations;
     int protocol;
index 87934669ab008d229ad8e3f3be9a5fc9053bb1d4..97b9655ea769ca9a5b10544dc00579347f7cef61 100644 (file)
 #include "spandsp/private/super_tone_rx.h"
 
 #if defined(SPANDSP_USE_FIXED_POINT)
-#define DETECTION_THRESHOLD         16439           /* -42dBm0 [((BINS*BINS*32768.0/(1.4142*128.0))*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
+#define DETECTION_THRESHOLD         16439           /* -42dBm0 [((SUPER_TONE_BINS*SUPER_TONE_BINS*32768.0/(1.4142*128.0))*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
 #define TONE_TWIST                  4               /* 6dB */
 #define TONE_TO_TOTAL_ENERGY        64              /* -3dB */
 #else
-#define DETECTION_THRESHOLD         2104205.6f      /* -42dBm0 [((BINS*BINS*32768.0/1.4142)*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
+#define DETECTION_THRESHOLD         2104205.6f      /* -42dBm0 [((SUPER_TONE_BINS*SUPER_TONE_BINS*32768.0/1.4142)*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
 #define TONE_TWIST                  3.981f          /* 6dB */
 #define TONE_TO_TOTAL_ENERGY        1.995f          /* 3dB */
 #endif
@@ -86,7 +86,7 @@ static int add_super_tone_freq(super_tone_rx_descriptor_t *desc, int freq)
             /* Merge these two */
             desc->pitches[desc->used_frequencies][0] = freq;
             desc->pitches[desc->used_frequencies][1] = i;
-            make_goertzel_descriptor(&desc->desc[desc->pitches[i][1]], (float) (freq + desc->pitches[i][0])/2, BINS);
+            make_goertzel_descriptor(&desc->desc[desc->pitches[i][1]], (float) (freq + desc->pitches[i][0])/2, SUPER_TONE_BINS);
             desc->used_frequencies++;
             return desc->pitches[i][1];
         }
@@ -97,7 +97,7 @@ static int add_super_tone_freq(super_tone_rx_descriptor_t *desc, int freq)
     {
         desc->desc = (goertzel_descriptor_t *) realloc(desc->desc, (desc->monitored_frequencies + 5)*sizeof(goertzel_descriptor_t));
     }
-    make_goertzel_descriptor(&desc->desc[desc->monitored_frequencies++], (float) freq, BINS);
+    make_goertzel_descriptor(&desc->desc[desc->monitored_frequencies++], (float) freq, SUPER_TONE_BINS);
     desc->used_frequencies++;
     return desc->pitches[i][1];
 }
@@ -162,9 +162,9 @@ static int test_cadence(super_tone_rx_segment_t *pattern,
             j = (rotation + steps - 2)%steps;
             if (pattern[j].f1 != test[8].f1  ||  pattern[j].f2 != test[8].f2)
                 return  0;
-            if (pattern[j].min_duration > test[8].min_duration*BINS
+            if (pattern[j].min_duration > test[8].min_duration*SUPER_TONE_BINS
                 ||
-                pattern[j].max_duration < test[8].min_duration*BINS)
+                pattern[j].max_duration < test[8].min_duration*SUPER_TONE_BINS)
             {
                 return  0;
             }
@@ -172,7 +172,7 @@ static int test_cadence(super_tone_rx_segment_t *pattern,
         j = (rotation + steps - 1)%steps;
         if (pattern[j].f1 != test[9].f1  ||  pattern[j].f2 != test[9].f2)
             return  0;
-        if (pattern[j].max_duration < test[9].min_duration*BINS)
+        if (pattern[j].max_duration < test[9].min_duration*SUPER_TONE_BINS)
             return  0;
     }
     else
@@ -183,9 +183,9 @@ static int test_cadence(super_tone_rx_segment_t *pattern,
             j = i + 10 - steps;
             if (pattern[i].f1 != test[j].f1  ||  pattern[i].f2 != test[j].f2)
                 return  0;
-            if (pattern[i].min_duration > test[j].min_duration*BINS
+            if (pattern[i].min_duration > test[j].min_duration*SUPER_TONE_BINS
                 ||
-                pattern[i].max_duration < test[j].min_duration*BINS)
+                pattern[i].max_duration < test[j].min_duration*SUPER_TONE_BINS)
             {
                 return  0;
             }
@@ -313,9 +313,9 @@ static void super_tone_chunk(super_tone_rx_state_t *s)
     int k1;
     int k2;
 #if defined(SPANDSP_USE_FIXED_POINT)
-    int32_t res[BINS/2];
+    int32_t res[SUPER_TONE_BINS/2];
 #else
-    float res[BINS/2];
+    float res[SUPER_TONE_BINS/2];
 #endif
 
     for (i = 0;  i < s->desc->monitored_frequencies;  i++)
@@ -397,7 +397,7 @@ static void super_tone_chunk(super_tone_rx_state_t *s)
                 s->segment_callback(s->callback_data,
                                     s->segments[9].f1,
                                     s->segments[9].f2,
-                                    s->segments[9].min_duration*BINS/8);
+                                    s->segments[9].min_duration*SUPER_TONE_BINS/8);
             }
             memcpy (&s->segments[0], &s->segments[1], 9*sizeof(s->segments[0]));
             s->segments[9].f1 = k1;
@@ -467,7 +467,7 @@ SPAN_DECLARE(int) super_tone_rx(super_tone_rx_state_t *s, const int16_t amp[], i
             s->energy += xamp*xamp;
 #endif
         }
-        if (s->state[0].current_sample >= BINS)
+        if (s->state[0].current_sample >= SUPER_TONE_BINS)
         {
             /* We have finished a Goertzel block. */
             super_tone_chunk(s);
index 4c0c5a59da50c5e58537e52df8ecf274018c8afb..1cf859b99738e92f622d7aa8c077238bdc7c7f03 100644 (file)
@@ -440,9 +440,9 @@ static int set_next_tx_type(t38_gateway_state_t *s)
         /* There is a handler queued, so that is the next one. */
         set_tx_handler(s, t->next_tx_handler, t->next_tx_user_data);
         set_next_tx_handler(s, NULL, NULL);
-        if (t->tx_handler == (span_tx_handler_t) &(silence_gen)
+        if (t->tx_handler == (span_tx_handler_t) &silence_gen
             ||
-            t->tx_handler == (span_tx_handler_t) &(tone_gen))
+            t->tx_handler == (span_tx_handler_t) &tone_gen)
         {
             set_rx_active(s, TRUE);
         }
index b35d5fa4e9ea767714b8e9549cb4dd9ff570490f..ee939b5cfd47c999ed3e0091318b6f800667fa72 100644 (file)
@@ -111,7 +111,7 @@ static const struct dtmf_to_ascii_s dtmf_to_ascii[] =
     {"##8", 'W'},
     {"##9", 'Z'},
     {"##0", ' '},
-#if defined(WIN32)  ||  ( defined(__SVR4) && defined (__sun))
+#if defined(WIN32)  ||  (defined(__SVR4)  &&  defined (__sun))
     {"#*1", 'X'},   // (Note 1) 111 1011
     {"#*2", 'X'},   // (Note 1) 111 1100
     {"#*3", 'X'},   // (Note 1) 111 1101
index 55c540d53ef527b2e23303fe6b8a58b86380f458..85c0b9e10c9d2e3bce5800af10aef4782a33c809 100644 (file)
@@ -52,6 +52,9 @@
 
 #include "spandsp/telephony.h"
 #include "spandsp/logging.h"
+#include "spandsp/fast_convert.h"
+#include "spandsp/math_fixed.h"
+#include "spandsp/saturated.h"
 #include "spandsp/complex.h"
 #include "spandsp/vector_float.h"
 #include "spandsp/complex_vector_float.h"
 #include "v22bis_rx_2400_floating_rrc.h"
 #endif
 
-#define ms_to_symbols(t)        (((t)*600)/1000)
+#define ms_to_symbols(t)                (((t)*600)/1000)
 
 /*! The adaption rate coefficient for the equalizer */
-#define EQUALIZER_DELTA         0.25f
+#define EQUALIZER_DELTA                 0.25f
 /*! The number of phase shifted coefficient set for the pulse shaping/bandpass filter */
-#define PULSESHAPER_COEFF_SETS  12
+#define PULSESHAPER_COEFF_SETS          12
 
 /*
 The basic method used by the V.22bis receiver is:
index 39ad4dd24099b8699b464512dc4c1e6339c40556..41c7ed2f385eb52760f0fd13cfb4f0330762ce17 100644 (file)
@@ -310,8 +310,8 @@ static __inline__ int get_scrambled_bit(v22bis_state_t *s)
 
 static complexf_t training_get(v22bis_state_t *s)
 {
-    complexf_t z;
     int bits;
+    static const complexf_t zero = {0.0f, 0.0f};
 
     /* V.22bis training sequence */
     switch (s->tx.training)
@@ -329,20 +329,17 @@ static complexf_t training_get(v22bis_state_t *s)
     case V22BIS_TX_TRAINING_STAGE_INITIAL_SILENCE:
         /* Silence */
         s->tx.constellation_state = 0;
-        z = complex_setf(0.0f, 0.0f);
-        break;
+        return zero;
     case V22BIS_TX_TRAINING_STAGE_U11:
         /* Send continuous unscrambled ones at 1200bps (i.e. 270 degree phase steps). */
         /* Only the answering modem sends unscrambled ones. It is the first thing exchanged between the modems. */
         s->tx.constellation_state = (s->tx.constellation_state + phase_steps[3]) & 3;
-        z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
-        break;
+        return v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
     case V22BIS_TX_TRAINING_STAGE_U0011:
         /* Continuous unscrambled double dibit 00 11 at 1200bps. This is termed the S1 segment in
            the V.22bis spec. It is only sent to request or accept 2400bps mode, and lasts 100+-3ms. After this
            timed burst, we unconditionally change to sending scrambled ones at 1200bps. */
         s->tx.constellation_state = (s->tx.constellation_state + phase_steps[3*(s->tx.training_count & 1)]) & 3;
-        z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
         if (++s->tx.training_count >= ms_to_symbols(100))
         {
             span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting S11 after U0011\n");
@@ -357,7 +354,7 @@ static complexf_t training_get(v22bis_state_t *s)
                 s->tx.training = V22BIS_TX_TRAINING_STAGE_TIMED_S11;
             }
         }
-        break;
+        return v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
     case V22BIS_TX_TRAINING_STAGE_TIMED_S11:
         /* A timed period of scrambled ones at 1200bps. */
         if (++s->tx.training_count >= ms_to_symbols(756))
@@ -383,8 +380,7 @@ static complexf_t training_get(v22bis_state_t *s)
         bits = scramble(s, 1);
         bits = (bits << 1) | scramble(s, 1);
         s->tx.constellation_state = (s->tx.constellation_state + phase_steps[bits]) & 3;
-        z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
-        break;
+        return v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
     case V22BIS_TX_TRAINING_STAGE_S1111:
         /* Scrambled ones at 2400bps. We send a timed 200ms burst, and switch to normal operation at 2400bps */
         bits = scramble(s, 1);
@@ -392,7 +388,6 @@ static complexf_t training_get(v22bis_state_t *s)
         s->tx.constellation_state = (s->tx.constellation_state + phase_steps[bits]) & 3;
         bits = scramble(s, 1);
         bits = (bits << 1) | scramble(s, 1);
-        z = v22bis_constellation[(s->tx.constellation_state << 2) | bits];
         if (++s->tx.training_count >= ms_to_symbols(200))
         {
             /* We have completed training. Now handle some real work. */
@@ -402,13 +397,9 @@ static complexf_t training_get(v22bis_state_t *s)
             v22bis_report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED);
             s->tx.current_get_bit = s->get_bit;
         }
-        break;
-    case V22BIS_TX_TRAINING_STAGE_PARKED:
-    default:
-        z = complex_setf(0.0f, 0.0f);
-        break;
+        return v22bis_constellation[(s->tx.constellation_state << 2) | bits];
     }
-    return z;
+    return zero;
 }
 /*- End of function --------------------------------------------------------*/
 
@@ -476,12 +467,12 @@ SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
             x.im += tx_pulseshaper[39 - s->tx.baud_phase][i]*s->tx.rrc_filter[i + s->tx.rrc_filter_step].im;
         }
         /* Now create and modulate the carrier */
-        z = dds_complexf(&(s->tx.carrier_phase), s->tx.carrier_phase_rate);
+        z = dds_complexf(&s->tx.carrier_phase, s->tx.carrier_phase_rate);
         famp = (x.re*z.re - x.im*z.im)*s->tx.gain;
         if (s->tx.guard_phase_rate  &&  (s->tx.rrc_filter[s->tx.rrc_filter_step].re != 0.0f  ||  s->tx.rrc_filter[s->tx.rrc_filter_step].im != 0.0f))
         {
             /* Add the guard tone */
-            famp += dds_modf(&(s->tx.guard_phase), s->tx.guard_phase_rate, s->tx.guard_level, 0);
+            famp += dds_modf(&s->tx.guard_phase, s->tx.guard_phase_rate, s->tx.guard_tone_gain, 0);
         }
         /* Don't bother saturating. We should never clip. */
         amp[sample] = (int16_t) lfastrintf(famp);
@@ -499,20 +490,20 @@ SPAN_DECLARE(void) v22bis_tx_power(v22bis_state_t *s, float power)
         l = 1.6f*powf(10.0f, (power - 1.0f - DBM0_MAX_POWER)/20.0f);
         s->tx.gain = l*32768.0f/(TX_PULSESHAPER_GAIN*3.0f);
         l = powf(10.0f, (power - 1.0f - 3.0f - DBM0_MAX_POWER)/20.0f);
-        s->tx.guard_level = l*32768.0f;
+        s->tx.guard_tone_gain = l*32768.0f;
     }
     else if(s->tx.guard_phase_rate == dds_phase_ratef(1800.0f))
     {
         l = 1.6f*powf(10.0f, (power - 1.0f - 1.0f - DBM0_MAX_POWER)/20.0f);
         s->tx.gain = l*32768.0f/(TX_PULSESHAPER_GAIN*3.0f);
         l = powf(10.0f, (power - 1.0f - 6.0f - DBM0_MAX_POWER)/20.0f);
-        s->tx.guard_level = l*32768.0f;
+        s->tx.guard_tone_gain = l*32768.0f;
     }
     else
     {
         l = 1.6f*powf(10.0f, (power - DBM0_MAX_POWER)/20.0f);
         s->tx.gain = l*32768.0f/(TX_PULSESHAPER_GAIN*3.0f);
-        s->tx.guard_level = 0;
+        s->tx.guard_tone_gain = 0;
     }
 }
 /*- End of function --------------------------------------------------------*/
index 8ac13d3dd8bf08309455a162cfce0b6126e0cbdd..37ef368a44bd8e68b18ebc14a12344aac49c0ec9 100644 (file)
@@ -63,7 +63,8 @@
 
 enum
 {
-    V8_WAIT_1S,
+    V8_WAIT_1S,         /* Start point when sending CI */
+    V8_AWAIT_ANSAM,     /* Start point when sending initial silence */
     V8_CI_ON,
     V8_CI_OFF,
     V8_HEARD_ANSAM,
@@ -100,7 +101,8 @@ enum
 enum
 {
     V8_CI_SYNC_OCTET = 0x00,
-    V8_CM_JM_SYNC_OCTET = 0xE0
+    V8_CM_JM_SYNC_OCTET = 0xE0,
+    V8_V92_SYNC_OCTET = 0x55
 };
 
 SPAN_DECLARE(const char *) v8_call_function_to_str(int call_function)
@@ -755,7 +757,24 @@ SPAN_DECLARE_NONSTD(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len)
 }
 /*- End of function --------------------------------------------------------*/
 
-static void v8_send_ci(v8_state_t *s)
+static void send_v92(v8_state_t *s)
+{
+    int i;
+
+    if (s->result.v92 >= 0)
+    {
+        /* Send 2 V.92 packets */
+        for (i = 0;  i < 2;  i++)
+        {
+            v8_put_preamble(s);
+            v8_put_byte(s, V8_V92_SYNC_OCTET);
+            v8_put_byte(s, s->result.v92);
+        }
+    }
+}
+/*- End of function --------------------------------------------------------*/
+
+static void send_ci(v8_state_t *s)
 {
     int i;
 
@@ -810,7 +829,7 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
         if ((s->negotiation_timer -= len) > 0)
             break;
         fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
-        v8_send_ci(s);
+        send_ci(s);
         s->state = V8_CI_ON;
         s->fsk_tx_on = TRUE;
         break;
@@ -851,12 +870,18 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
             {
                 /* Try again */
                 fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
-                v8_send_ci(s);
+                send_ci(s);
                 s->state = V8_CI_ON;
                 s->fsk_tx_on = TRUE;
             }
         }
         break;
+    case V8_AWAIT_ANSAM:
+        residual_samples = modem_connect_tones_rx(&s->ansam_rx, amp, len);
+        /* Check if an ANSam or ANSam/ tone has been detected */
+        if ((tone = modem_connect_tones_rx_get(&s->ansam_rx)) != MODEM_CONNECT_TONES_NONE)
+            handle_modem_connect_tone(s, tone);
+        break;
     case V8_HEARD_ANSAM:
         /* We have heard the ANSam or ANSam/ signal, but we still need to wait for the
            end of the Te timeout period to comply with the spec. */
@@ -865,6 +890,7 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
             v8_decode_init(s);
             s->negotiation_timer = ms_to_samples(5000);
             fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
+            send_v92(s);
             send_cm_jm(s);
             s->state = V8_CM_ON;
             s->fsk_tx_on = TRUE;
@@ -1015,9 +1041,16 @@ SPAN_DECLARE(int) v8_restart(v8_state_t *s, int calling_party, v8_parms_t *parms
     s->calling_party = calling_party;
     if (s->calling_party)
     {
-        s->state = V8_WAIT_1S;
-        s->negotiation_timer = ms_to_samples(1000);
-        s->ci_count = 0;
+        if (s->result.send_ci)
+        {
+            s->state = V8_WAIT_1S;
+            s->negotiation_timer = ms_to_samples(1000);
+            s->ci_count = 0;
+        }
+        else
+        {
+            s->state = V8_AWAIT_ANSAM;
+        }
         modem_connect_tones_rx_init(&s->ansam_rx, MODEM_CONNECT_TONES_ANS_PR, NULL, NULL);
         fsk_tx_init(&s->v21tx, &preset_fsk_specs[FSK_V21CH1], get_bit, s);
     }
index 7b5a7efa691d95645a33e03f5963b8bcf07203c6..dd09e449e15ba850ce574f1659275c2ef0214370 100644 (file)
@@ -107,8 +107,8 @@ SPAN_DECLARE(void) vec_copyl(long double z[], const long double x[], int n)
 SPAN_DECLARE(void) vec_negatef(float z[], const float x[], int n)
 {
     int i;
-       static const uint32_t mask = 0x80000000;
-       static const float *fmask = (float *) &mask;
+    static const uint32_t mask = 0x80000000;
+    static const float *fmask = (float *) &mask;
     __m128 n1;
     __m128 n2;
  
@@ -118,7 +118,7 @@ SPAN_DECLARE(void) vec_negatef(float z[], const float x[], int n)
         for (i -= 4;  i >= 0;  i -= 4)
         {
             n1 = _mm_loadu_ps(x + i);
-                   n1 = _mm_xor_ps(n1, n2);
+            n1 = _mm_xor_ps(n1, n2);
             _mm_storeu_ps(z + i, n1);
         }
     }
index 9735e0f2a5df8d1c777b496b40e8d719fd13af21..3d64e2e6b7e939c91b0baf32866ccd050b9fe057 100644 (file)
@@ -37,7 +37,7 @@
 
 typedef struct faxtester_state_s faxtester_state_t;
 
-typedef void (faxtester_flush_handler_t)(faxtester_state_t *s, void *user_data, int which);
+typedef void (*faxtester_flush_handler_t)(faxtester_state_t *s, void *user_data, int which);
 
 /*!
     FAX tester real time frame handler.
@@ -48,13 +48,13 @@ typedef void (faxtester_flush_handler_t)(faxtester_state_t *s, void *user_data,
     \param msg The HDLC message.
     \param len The length of the message.
 */
-typedef void (faxtester_real_time_frame_handler_t)(faxtester_state_t *s,
-                                                   void *user_data,
-                                                   int direction,
-                                                   const uint8_t *msg,
-                                                   int len);
+typedef void (*faxtester_real_time_frame_handler_t)(faxtester_state_t *s,
+                                                    void *user_data,
+                                                    int direction,
+                                                    const uint8_t *msg,
+                                                    int len);
 
-typedef void (faxtester_front_end_step_complete_handler_t)(faxtester_state_t *s, void *user_data);
+typedef void (*faxtester_front_end_step_complete_handler_t)(faxtester_state_t *s, void *user_data);
 
 /*!
     FAX tester descriptor.
@@ -64,19 +64,19 @@ struct faxtester_state_s
     /*! \brief Pointer to our current step in the test. */
     xmlNodePtr cur;
 
-    faxtester_flush_handler_t *flush_handler;
+    faxtester_flush_handler_t flush_handler;
     void *flush_user_data;
 
     /*! \brief A pointer to a callback routine to be called when frames are
         exchanged. */
-    faxtester_real_time_frame_handler_t *real_time_frame_handler;
+    faxtester_real_time_frame_handler_t real_time_frame_handler;
     /*! \brief An opaque pointer supplied in real time frame callbacks. */
     void *real_time_frame_user_data;
 
-    faxtester_front_end_step_complete_handler_t *front_end_step_complete_handler;
+    faxtester_front_end_step_complete_handler_t front_end_step_complete_handler;
     void *front_end_step_complete_user_data;
 
-    faxtester_front_end_step_complete_handler_t *front_end_step_timeout_handler;
+    faxtester_front_end_step_complete_handler_t front_end_step_timeout_handler;
     void *front_end_step_timeout_user_data;
 
     const uint8_t *image_buffer;
@@ -149,7 +149,7 @@ void faxtester_send_hdlc_flags(faxtester_state_t *s, int flags);
 
 void faxtester_send_hdlc_msg(faxtester_state_t *s, const uint8_t *msg, int len, int crc_ok);
 
-void faxtester_set_flush_handler(faxtester_state_t *s, faxtester_flush_handler_t *handler, void *user_data);
+void faxtester_set_flush_handler(faxtester_state_t *s, faxtester_flush_handler_t handler, void *user_data);
 
 /*! Select whether silent audio will be sent when FAX transmit is idle.
     \brief Select whether silent audio will be sent when FAX transmit is idle.
@@ -167,11 +167,11 @@ void faxtester_set_transmit_on_idle(faxtester_state_t *s, int transmit_on_idle);
 */
 void faxtester_set_tep_mode(faxtester_state_t *s, int use_tep);
 
-void faxtester_set_real_time_frame_handler(faxtester_state_t *s, faxtester_real_time_frame_handler_t *handler, void *user_data);
+void faxtester_set_real_time_frame_handler(faxtester_state_t *s, faxtester_real_time_frame_handler_t handler, void *user_data);
 
-void faxtester_set_front_end_step_complete_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t *handler, void *user_data);
+void faxtester_set_front_end_step_complete_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data);
 
-void faxtester_set_front_end_step_timeout_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t *handler, void *user_data);
+void faxtester_set_front_end_step_timeout_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data);
 
 void faxtester_set_timeout(faxtester_state_t *s, int timeout);
 
index 23563ad484c18d00032924d1e750d5d7f94fcfde..ae555cd500f7150869b9c3b3eb70b89f41972a1c 100644 (file)
@@ -31,7 +31,7 @@
 
 #define UDPTL_BUF_MASK              15
 
-typedef int (udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
+typedef int (*udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
 
 typedef struct
 {
@@ -51,7 +51,7 @@ typedef struct
 
 struct udptl_state_s
 {
-    udptl_rx_packet_handler_t *rx_packet_handler;
+    udptl_rx_packet_handler_t rx_packet_handler;
     void *user_data;
 
     /*! This option indicates the error correction scheme used in transmitted UDPTL