mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 16:15:04 +00:00
Tweaks, and a fix for FAX polling.
This commit is contained in:
parent
3a00260dc6
commit
6f439d3741
@ -504,7 +504,7 @@ SPAN_DECLARE(int) decode_msg(ademco_contactid_report_t *report, const char buf[]
|
|||||||
int x;
|
int x;
|
||||||
char buf2[20];
|
char buf2[20];
|
||||||
|
|
||||||
/* We need to remap normal DTMF (0-0, *, #, A-D) to Ademco's pseudo-hex (0-0, B-F, nothing for A)
|
/* We need to remap normal DTMF (0-9, *, #, A-D) to Ademco's pseudo-hex (0-9, B-F, nothing for A)
|
||||||
and calculate the checksum */
|
and calculate the checksum */
|
||||||
for (sum = 0, s = buf, t = buf2; *s; s++, t++)
|
for (sum = 0, s = buf, t = buf2; *s; s++, t++)
|
||||||
{
|
{
|
||||||
|
@ -85,6 +85,7 @@ SPAN_DECLARE(const char *) signal_status_to_str(int status)
|
|||||||
case SIG_STATUS_LINK_IDLE:
|
case SIG_STATUS_LINK_IDLE:
|
||||||
return "Link idle";
|
return "Link idle";
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
@ -293,15 +293,15 @@ SPAN_DECLARE(int) bell_mf_tx(bell_mf_tx_state_t *s, int16_t amp[], int max_sampl
|
|||||||
if (s->tones.current_section >= 0)
|
if (s->tones.current_section >= 0)
|
||||||
{
|
{
|
||||||
/* Deal with the fragment left over from last time */
|
/* Deal with the fragment left over from last time */
|
||||||
len = tone_gen(&(s->tones), amp, max_samples);
|
len = tone_gen(&s->tones, amp, max_samples);
|
||||||
}
|
}
|
||||||
while (len < max_samples && (digit = queue_read_byte(&s->queue.queue)) >= 0)
|
while (len < max_samples && (digit = queue_read_byte(&s->queue.queue)) >= 0)
|
||||||
{
|
{
|
||||||
/* Step to the next digit */
|
/* Step to the next digit */
|
||||||
if ((cp = strchr(bell_mf_tone_codes, digit)) == NULL)
|
if ((cp = strchr(bell_mf_tone_codes, digit)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
tone_gen_init(&(s->tones), &bell_mf_digit_tones[cp - bell_mf_tone_codes]);
|
tone_gen_init(&s->tones, &bell_mf_digit_tones[cp - bell_mf_tone_codes]);
|
||||||
len += tone_gen(&(s->tones), amp + len, max_samples - len);
|
len += tone_gen(&s->tones, amp + len, max_samples - len);
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -338,7 +338,7 @@ SPAN_DECLARE(bell_mf_tx_state_t *) bell_mf_tx_init(bell_mf_tx_state_t *s)
|
|||||||
|
|
||||||
if (!bell_mf_gen_inited)
|
if (!bell_mf_gen_inited)
|
||||||
bell_mf_gen_init();
|
bell_mf_gen_init();
|
||||||
tone_gen_init(&(s->tones), &bell_mf_digit_tones[0]);
|
tone_gen_init(&s->tones, &bell_mf_digit_tones[0]);
|
||||||
s->current_sample = 0;
|
s->current_sample = 0;
|
||||||
queue_init(&s->queue.queue, MAX_BELL_MF_DIGITS, QUEUE_READ_ATOMIC | QUEUE_WRITE_ATOMIC);
|
queue_init(&s->queue.queue, MAX_BELL_MF_DIGITS, QUEUE_READ_ATOMIC | QUEUE_WRITE_ATOMIC);
|
||||||
s->tones.current_section = -1;
|
s->tones.current_section = -1;
|
||||||
|
@ -161,8 +161,10 @@ SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_accept(void *user_data, const uint8_t
|
|||||||
say the current signal source is valid. */
|
say the current signal source is valid. */
|
||||||
if (len >= 0 && ok)
|
if (len >= 0 && ok)
|
||||||
s->rx_frame_received = true;
|
s->rx_frame_received = true;
|
||||||
|
/*endif*/
|
||||||
if (s->hdlc_accept)
|
if (s->hdlc_accept)
|
||||||
s->hdlc_accept(s->hdlc_accept_user_data, msg, len, ok);
|
s->hdlc_accept(s->hdlc_accept_user_data, msg, len, ok);
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -176,6 +178,7 @@ SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_
|
|||||||
hdlc_tx_restart(&s->hdlc_tx);
|
hdlc_tx_restart(&s->hdlc_tx);
|
||||||
else
|
else
|
||||||
hdlc_tx_frame(&s->hdlc_tx, msg, len);
|
hdlc_tx_frame(&s->hdlc_tx, msg, len);
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -579,6 +582,7 @@ SPAN_DECLARE(int) fax_modems_set_next_tx_type(fax_modems_state_t *s)
|
|||||||
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
|
fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* There is nothing else to change to, so use zero length silence */
|
/* There is nothing else to change to, so use zero length silence */
|
||||||
silence_gen_alter(&s->silence_gen, 0);
|
silence_gen_alter(&s->silence_gen, 0);
|
||||||
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &s->silence_gen);
|
fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &s->silence_gen);
|
||||||
@ -619,6 +623,7 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
|
|||||||
{
|
{
|
||||||
if ((s = (fax_modems_state_t *) span_alloc(sizeof(*s))) == NULL)
|
if ((s = (fax_modems_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
memset(s, 0, sizeof(*s));
|
memset(s, 0, sizeof(*s));
|
||||||
|
@ -53,7 +53,7 @@ static __inline__ int16_t gsm_add(int16_t a, int16_t b)
|
|||||||
int32_t sum;
|
int32_t sum;
|
||||||
|
|
||||||
sum = (int32_t) a + (int32_t) b;
|
sum = (int32_t) a + (int32_t) b;
|
||||||
return saturate16(sum);
|
return saturate16(sum);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -78,17 +78,17 @@ static __inline__ int32_t gsm_l_add(int32_t a, int32_t b)
|
|||||||
if (a < 0)
|
if (a < 0)
|
||||||
{
|
{
|
||||||
if (b >= 0)
|
if (b >= 0)
|
||||||
return a + b;
|
return a + b;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1);
|
A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1);
|
||||||
return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2;
|
return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2;
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
if (b <= 0)
|
if (b <= 0)
|
||||||
return a + b;
|
return a + b;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
A = (uint32_t) a + (uint32_t) b;
|
A = (uint32_t) a + (uint32_t) b;
|
||||||
return (A > INT32_MAX) ? INT32_MAX : A;
|
return (A > INT32_MAX) ? INT32_MAX : A;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -98,23 +98,23 @@ static __inline__ int16_t gsm_sub(int16_t a, int16_t b)
|
|||||||
int32_t diff;
|
int32_t diff;
|
||||||
|
|
||||||
diff = (int32_t) a - (int32_t) b;
|
diff = (int32_t) a - (int32_t) b;
|
||||||
return saturate16(diff);
|
return saturate16(diff);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int16_t gsm_mult(int16_t a, int16_t b)
|
static __inline__ int16_t gsm_mult(int16_t a, int16_t b)
|
||||||
{
|
{
|
||||||
if (a == INT16_MIN && b == INT16_MIN)
|
if (a == INT16_MIN && b == INT16_MIN)
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
return (int16_t) (((int32_t) a * (int32_t) b) >> 15);
|
return (int16_t) (((int32_t) a * (int32_t) b) >> 15);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int32_t gsm_l_mult(int16_t a, int16_t b)
|
static __inline__ int32_t gsm_l_mult(int16_t a, int16_t b)
|
||||||
{
|
{
|
||||||
assert (a != INT16_MIN || b != INT16_MIN);
|
assert (a != INT16_MIN || b != INT16_MIN);
|
||||||
return ((int32_t) a * (int32_t) b) << 1;
|
return ((int32_t) a * (int32_t) b) << 1;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -123,47 +123,47 @@ static __inline__ int16_t gsm_mult_r(int16_t a, int16_t b)
|
|||||||
int32_t prod;
|
int32_t prod;
|
||||||
|
|
||||||
if (b == INT16_MIN && a == INT16_MIN)
|
if (b == INT16_MIN && a == INT16_MIN)
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
prod = (int32_t) a * (int32_t) b + 16384;
|
prod = (int32_t) a * (int32_t) b + 16384;
|
||||||
prod >>= 15;
|
prod >>= 15;
|
||||||
return (int16_t) (prod & 0xFFFF);
|
return (int16_t) (prod & 0xFFFF);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int16_t gsm_abs(int16_t a)
|
static __inline__ int16_t gsm_abs(int16_t a)
|
||||||
{
|
{
|
||||||
return (a == INT16_MIN) ? INT16_MAX : (int16_t) abs(a);
|
return (a == INT16_MIN) ? INT16_MAX : (int16_t) abs(a);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int16_t gsm_asr(int16_t a, int n)
|
static __inline__ int16_t gsm_asr(int16_t a, int n)
|
||||||
{
|
{
|
||||||
if (n >= 16)
|
if (n >= 16)
|
||||||
return (int16_t) (-(a < 0));
|
return (int16_t) (-(a < 0));
|
||||||
/*endif*/
|
/*endif*/
|
||||||
if (n <= -16)
|
if (n <= -16)
|
||||||
return 0;
|
return 0;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return (int16_t) (a << -n);
|
return (int16_t) (a << -n);
|
||||||
/*endif*/
|
/*endif*/
|
||||||
return (int16_t) (a >> n);
|
return (int16_t) (a >> n);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int16_t gsm_asl(int16_t a, int n)
|
static __inline__ int16_t gsm_asl(int16_t a, int n)
|
||||||
{
|
{
|
||||||
if (n >= 16)
|
if (n >= 16)
|
||||||
return 0;
|
return 0;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
if (n <= -16)
|
if (n <= -16)
|
||||||
return (int16_t) (-(a < 0));
|
return (int16_t) (-(a < 0));
|
||||||
/*endif*/
|
/*endif*/
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return gsm_asr(a, -n);
|
return gsm_asr(a, -n);
|
||||||
/*endif*/
|
/*endif*/
|
||||||
return (int16_t) (a << n);
|
return (int16_t) (a << n);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
static void weighting_filter(int16_t x[40],
|
static void weighting_filter(int16_t x[40],
|
||||||
const int16_t *e) // signal [-5..0.39.44] IN)
|
const int16_t *e) // signal [-5..0.39.44] IN)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__) && defined(SPANDSP_USE_MMX) && defined(__x86_64__) && !(defined(__APPLE_CC__) && __APPLE_CC__ >= 5448) && !defined(__OpenBSD__)
|
#if defined(__GNUC__) && defined(SPANDSP_USE_MMX) && defined(__x86_64__)
|
||||||
/* Table 4.4 Coefficients of the weighting filter */
|
/* Table 4.4 Coefficients of the weighting filter */
|
||||||
/* This must be padded to a multiple of 4 for MMX to work */
|
/* This must be padded to a multiple of 4 for MMX to work */
|
||||||
static const union
|
static const union
|
||||||
|
@ -302,7 +302,7 @@ SPAN_DECLARE(int) sig_tone_tx(sig_tone_tx_state_t *s, int16_t amp[], int len)
|
|||||||
{
|
{
|
||||||
for (j = i; j < i + n; j++)
|
for (j = i; j < i + n; j++)
|
||||||
{
|
{
|
||||||
tone = dds_mod(&(s->phase_acc[k]), s->phase_rate[k], s->tone_scaling[k][high_low], 0);
|
tone = dds_mod(&s->phase_acc[k], s->phase_rate[k], s->tone_scaling[k][high_low], 0);
|
||||||
amp[j] = sat_add16(amp[j], tone);
|
amp[j] = sat_add16(amp[j], tone);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
|
@ -322,12 +322,12 @@ extern "C"
|
|||||||
#if (_MSC_VER < 1800)
|
#if (_MSC_VER < 1800)
|
||||||
__inline long int lrint(double x)
|
__inline long int lrint(double x)
|
||||||
{
|
{
|
||||||
return (long int)_mm_cvtsd_si64x( _mm_loadu_pd ((const double*)&x) );
|
return (long int)_mm_cvtsd_si64x(_mm_loadu_pd((const double *) &x));
|
||||||
}
|
}
|
||||||
|
|
||||||
__inline long int lrintf(float x)
|
__inline long int lrintf(float x)
|
||||||
{
|
{
|
||||||
return _mm_cvt_ss2si( _mm_load_ss((const float*)&x) );
|
return _mm_cvt_ss2si(_mm_load_ss((const float *) &x));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -88,10 +88,10 @@ static __inline__ const int16_t *fir16_create(fir16_state_t *fir,
|
|||||||
fir->curr_pos = taps - 1;
|
fir->curr_pos = taps - 1;
|
||||||
fir->coeffs = coeffs;
|
fir->coeffs = coeffs;
|
||||||
#if defined(USE_MMX) || defined(USE_SSE2)
|
#if defined(USE_MMX) || defined(USE_SSE2)
|
||||||
if ((fir->history = malloc(2*taps*sizeof(int16_t))))
|
if ((fir->history = span_alloc(2*taps*sizeof(int16_t))))
|
||||||
memset(fir->history, 0, 2*taps*sizeof(int16_t));
|
memset(fir->history, 0, 2*taps*sizeof(int16_t));
|
||||||
#else
|
#else
|
||||||
if ((fir->history = (int16_t *) malloc(taps*sizeof(int16_t))))
|
if ((fir->history = (int16_t *) span_alloc(taps*sizeof(int16_t))))
|
||||||
memset(fir->history, 0, taps*sizeof(int16_t));
|
memset(fir->history, 0, taps*sizeof(int16_t));
|
||||||
#endif
|
#endif
|
||||||
return fir->history;
|
return fir->history;
|
||||||
@ -110,7 +110,7 @@ static __inline__ void fir16_flush(fir16_state_t *fir)
|
|||||||
|
|
||||||
static __inline__ void fir16_free(fir16_state_t *fir)
|
static __inline__ void fir16_free(fir16_state_t *fir)
|
||||||
{
|
{
|
||||||
free(fir->history);
|
span_free(fir->history);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ static __inline__ const int16_t *fir32_create(fir32_state_t *fir,
|
|||||||
fir->taps = taps;
|
fir->taps = taps;
|
||||||
fir->curr_pos = taps - 1;
|
fir->curr_pos = taps - 1;
|
||||||
fir->coeffs = coeffs;
|
fir->coeffs = coeffs;
|
||||||
fir->history = (int16_t *) malloc(taps*sizeof(int16_t));
|
fir->history = (int16_t *) span_alloc(taps*sizeof(int16_t));
|
||||||
if (fir->history)
|
if (fir->history)
|
||||||
memset(fir->history, '\0', taps*sizeof(int16_t));
|
memset(fir->history, '\0', taps*sizeof(int16_t));
|
||||||
return fir->history;
|
return fir->history;
|
||||||
@ -225,7 +225,7 @@ static __inline__ void fir32_flush(fir32_state_t *fir)
|
|||||||
|
|
||||||
static __inline__ void fir32_free(fir32_state_t *fir)
|
static __inline__ void fir32_free(fir32_state_t *fir)
|
||||||
{
|
{
|
||||||
free(fir->history);
|
span_free(fir->history);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ static __inline__ const float *fir_float_create(fir_float_state_t *fir,
|
|||||||
fir->taps = taps;
|
fir->taps = taps;
|
||||||
fir->curr_pos = taps - 1;
|
fir->curr_pos = taps - 1;
|
||||||
fir->coeffs = coeffs;
|
fir->coeffs = coeffs;
|
||||||
fir->history = (float *) malloc(taps*sizeof(float));
|
fir->history = (float *) span_alloc(taps*sizeof(float));
|
||||||
if (fir->history)
|
if (fir->history)
|
||||||
memset(fir->history, '\0', taps*sizeof(float));
|
memset(fir->history, '\0', taps*sizeof(float));
|
||||||
return fir->history;
|
return fir->history;
|
||||||
@ -267,7 +267,7 @@ static __inline__ const float *fir_float_create(fir_float_state_t *fir,
|
|||||||
|
|
||||||
static __inline__ void fir_float_free(fir_float_state_t *fir)
|
static __inline__ void fir_float_free(fir_float_state_t *fir)
|
||||||
{
|
{
|
||||||
free(fir->history);
|
span_free(fir->history);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -81,7 +81,8 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \brief Initialise an HDLC receiver context.
|
/*! Initialise an HDLC receiver context.
|
||||||
|
\brief Initialise an HDLC receiver context.
|
||||||
\param s A pointer to an HDLC receiver context.
|
\param s A pointer to an HDLC receiver context.
|
||||||
\param crc32 True to use ITU CRC32. False to use ITU CRC16.
|
\param crc32 True to use ITU CRC32. False to use ITU CRC16.
|
||||||
\param report_bad_frames True to request the reporting of bad frames.
|
\param report_bad_frames True to request the reporting of bad frames.
|
||||||
|
@ -106,9 +106,9 @@ struct at_state_s
|
|||||||
int command_dial;
|
int command_dial;
|
||||||
int ok_is_pending;
|
int ok_is_pending;
|
||||||
int dte_is_waiting;
|
int dte_is_waiting;
|
||||||
/*! \brief True if a carrier is presnt. Otherwise false. */
|
/*! \brief True if a carrier is present. */
|
||||||
bool rx_signal_present;
|
bool rx_signal_present;
|
||||||
/*! \brief True if a modem has trained, Otherwise false. */
|
/*! \brief True if a modem has trained, */
|
||||||
bool rx_trained;
|
bool rx_trained;
|
||||||
int transmit;
|
int transmit;
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ struct r2_mf_rx_state_s
|
|||||||
tone_report_func_t callback;
|
tone_report_func_t callback;
|
||||||
/*! An opaque pointer passed to the callback function. */
|
/*! An opaque pointer passed to the callback function. */
|
||||||
void *callback_data;
|
void *callback_data;
|
||||||
/*! Tue is we are detecting forward tones. False if we are detecting backward tones */
|
/*! True if we are detecting forward tones. False if we are detecting backward tones */
|
||||||
bool fwd;
|
bool fwd;
|
||||||
/*! Tone detector working states */
|
/*! Tone detector working states */
|
||||||
goertzel_state_t out[6];
|
goertzel_state_t out[6];
|
||||||
|
@ -48,7 +48,7 @@ typedef struct
|
|||||||
struct g722_encode_state_s
|
struct g722_encode_state_s
|
||||||
{
|
{
|
||||||
/*! True if operating in the special ITU test mode, with the band split filters
|
/*! True if operating in the special ITU test mode, with the band split filters
|
||||||
disabled. */
|
disabled. */
|
||||||
bool itu_test_mode;
|
bool itu_test_mode;
|
||||||
/*! True if the G.722 data is packed */
|
/*! True if the G.722 data is packed */
|
||||||
bool packed;
|
bool packed;
|
||||||
@ -74,7 +74,7 @@ struct g722_encode_state_s
|
|||||||
struct g722_decode_state_s
|
struct g722_decode_state_s
|
||||||
{
|
{
|
||||||
/*! True if operating in the special ITU test mode, with the band split filters
|
/*! True if operating in the special ITU test mode, with the band split filters
|
||||||
disabled. */
|
disabled. */
|
||||||
bool itu_test_mode;
|
bool itu_test_mode;
|
||||||
/*! True if the G.722 data is packed */
|
/*! True if the G.722 data is packed */
|
||||||
bool packed;
|
bool packed;
|
||||||
|
@ -133,7 +133,7 @@ struct v42_state_s
|
|||||||
{
|
{
|
||||||
/*! True if we are the calling party, otherwise false. */
|
/*! True if we are the calling party, otherwise false. */
|
||||||
bool calling_party;
|
bool calling_party;
|
||||||
/*! True if we should detect whether the far end is V.42 capable. false if we go
|
/*! True if we should detect whether the far end is V.42 capable. False if we go
|
||||||
directly to protocol establishment. */
|
directly to protocol establishment. */
|
||||||
bool detect;
|
bool detect;
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
\section t30_page_sec_1 What does it do?
|
\section t30_page_sec_1 What does it do?
|
||||||
The T.30 protocol is the core protocol used for FAX transmission. This module
|
The T.30 protocol is the core protocol used for FAX transmission. This module
|
||||||
implements most of its key features. It does not interface to the outside work.
|
implements most of its key features. It does not interface to the outside world.
|
||||||
Seperate modules do that for T.38, analogue line, and other forms of FAX
|
Seperate modules do that for T.38, analogue line, and other forms of FAX
|
||||||
communication.
|
communication.
|
||||||
|
|
||||||
|
@ -45,16 +45,14 @@ to maximum the tolerance of jitter and packet loss on the IP network.
|
|||||||
typedef struct t38_gateway_state_s t38_gateway_state_t;
|
typedef struct t38_gateway_state_s t38_gateway_state_t;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
T.30 real time frame handler.
|
T.38 gateway real time frame handler.
|
||||||
\brief T.30 real time frame handler.
|
\brief T.38 gateway real time frame handler.
|
||||||
\param s The T.30 context.
|
|
||||||
\param user_data An opaque pointer.
|
\param user_data An opaque pointer.
|
||||||
\param incoming True for incoming, false for outgoing.
|
\param incoming True for incoming, false for outgoing.
|
||||||
\param msg The HDLC message.
|
\param msg The HDLC message.
|
||||||
\param len The length of the message.
|
\param len The length of the message.
|
||||||
*/
|
*/
|
||||||
typedef void (*t38_gateway_real_time_frame_handler_t)(t38_gateway_state_t *s,
|
typedef void (*t38_gateway_real_time_frame_handler_t)(void *user_data,
|
||||||
void *user_data,
|
|
||||||
bool incoming,
|
bool incoming,
|
||||||
const uint8_t *msg,
|
const uint8_t *msg,
|
||||||
int len);
|
int len);
|
||||||
|
@ -78,7 +78,7 @@ SPAN_DECLARE(void) make_goertzel_descriptor(goertzel_descriptor_t *t,
|
|||||||
int samples);
|
int samples);
|
||||||
|
|
||||||
/*! \brief Initialise the state of a Goertzel transform.
|
/*! \brief Initialise the state of a Goertzel transform.
|
||||||
\param s The Goertzel context. If NULL, a context is allocated with malloc.
|
\param s The Goertzel context. If NULL, a context is allocated.
|
||||||
\param t The Goertzel descriptor.
|
\param t The Goertzel descriptor.
|
||||||
\return A pointer to the Goertzel state. */
|
\return A pointer to the Goertzel state. */
|
||||||
SPAN_DECLARE(goertzel_state_t *) goertzel_init(goertzel_state_t *s,
|
SPAN_DECLARE(goertzel_state_t *) goertzel_init(goertzel_state_t *s,
|
||||||
|
@ -2657,7 +2657,6 @@ static int start_receiving_document(t30_state_t *s)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Start receiving document\n");
|
span_log(&s->logging, SPAN_LOG_FLOW, "Start receiving document\n");
|
||||||
queue_phase(s, T30_PHASE_B_TX);
|
|
||||||
s->ecm_block = 0;
|
s->ecm_block = 0;
|
||||||
send_dis_or_dtc_sequence(s, true);
|
send_dis_or_dtc_sequence(s, true);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2745,7 +2744,7 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
|
|||||||
send_dcs_sequence(s, true);
|
send_dcs_sequence(s, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s nothing to send\n", t30_frametype(msg[2]));
|
span_log(&s->logging, SPAN_LOG_FLOW, "%s - nothing to send\n", t30_frametype(msg[2]));
|
||||||
/* ... then try to receive something */
|
/* ... then try to receive something */
|
||||||
if (s->rx_file[0])
|
if (s->rx_file[0])
|
||||||
{
|
{
|
||||||
@ -2772,7 +2771,7 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
|
|||||||
send_dis_or_dtc_sequence(s, true);
|
send_dis_or_dtc_sequence(s, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s nothing to receive\n", t30_frametype(msg[2]));
|
span_log(&s->logging, SPAN_LOG_FLOW, "%s - nothing to receive\n", t30_frametype(msg[2]));
|
||||||
/* There is nothing to do, or nothing we are able to do. */
|
/* There is nothing to do, or nothing we are able to do. */
|
||||||
send_dcn(s);
|
send_dcn(s);
|
||||||
return -1;
|
return -1;
|
||||||
@ -5105,6 +5104,7 @@ static void queue_phase(t30_state_t *s, int phase)
|
|||||||
s->send_hdlc_handler(s->send_hdlc_user_data, NULL, -1);
|
s->send_hdlc_handler(s->send_hdlc_user_data, NULL, -1);
|
||||||
}
|
}
|
||||||
s->next_phase = phase;
|
s->next_phase = phase;
|
||||||
|
span_log(&s->logging, SPAN_LOG_FLOW, "Queuing phase %s\n", phase_names[s->next_phase]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5116,7 +5116,7 @@ static void queue_phase(t30_state_t *s, int phase)
|
|||||||
|
|
||||||
static void set_phase(t30_state_t *s, int phase)
|
static void set_phase(t30_state_t *s, int phase)
|
||||||
{
|
{
|
||||||
if (phase != s->next_phase && s->next_phase != T30_PHASE_IDLE)
|
if (s->next_phase != phase && s->next_phase != T30_PHASE_IDLE)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Flushing queued phase %s\n", phase_names[s->next_phase]);
|
span_log(&s->logging, SPAN_LOG_FLOW, "Flushing queued phase %s\n", phase_names[s->next_phase]);
|
||||||
/* Ensure nothing has been left in the queue that was scheduled to go out in the previous next
|
/* Ensure nothing has been left in the queue that was scheduled to go out in the previous next
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
#include "spandsp/async.h"
|
#include "spandsp/async.h"
|
||||||
#include "spandsp/crc.h"
|
#include "spandsp/crc.h"
|
||||||
#include "spandsp/hdlc.h"
|
#include "spandsp/hdlc.h"
|
||||||
|
#include "spandsp/vector_int.h"
|
||||||
#include "spandsp/silence_gen.h"
|
#include "spandsp/silence_gen.h"
|
||||||
#include "spandsp/super_tone_rx.h"
|
#include "spandsp/super_tone_rx.h"
|
||||||
#include "spandsp/fsk.h"
|
#include "spandsp/fsk.h"
|
||||||
@ -929,7 +930,7 @@ static int stream_non_ecm(t31_state_t *s)
|
|||||||
help for all implentations. It is usually ignored, which is probably
|
help for all implentations. It is usually ignored, which is probably
|
||||||
the right thing to do after receiving a message saying the signal has
|
the right thing to do after receiving a message saying the signal has
|
||||||
ended. */
|
ended. */
|
||||||
memset(buf + len, 0, fe->octets_per_data_packet - len);
|
memset(&buf[len], 0, fe->octets_per_data_packet - len);
|
||||||
fe->non_ecm_trailer_bytes = 3*fe->octets_per_data_packet + len;
|
fe->non_ecm_trailer_bytes = 3*fe->octets_per_data_packet + len;
|
||||||
len = fe->octets_per_data_packet;
|
len = fe->octets_per_data_packet;
|
||||||
fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_4;
|
fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_4;
|
||||||
@ -2868,7 +2869,7 @@ SPAN_DECLARE_NONSTD(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len)
|
|||||||
if (s->audio.modems.transmit_on_idle)
|
if (s->audio.modems.transmit_on_idle)
|
||||||
{
|
{
|
||||||
/* Pad to the requested length with silence */
|
/* Pad to the requested length with silence */
|
||||||
memset(&[len], 0, (max_len - len)*sizeof(int16_t));
|
vec_zeroi16(&[len], max_len - len);
|
||||||
len = max_len;
|
len = max_len;
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
|
@ -500,7 +500,7 @@ static const nsf_data_t vendor_b5[] =
|
|||||||
{"\x00\x6E", 2, "Microsoft", false, NULL},
|
{"\x00\x6E", 2, "Microsoft", false, NULL},
|
||||||
{"\x00\x72", 2, "Speaking Devices", false, NULL},
|
{"\x00\x72", 2, "Speaking Devices", false, NULL},
|
||||||
{"\x00\x74", 2, "Compaq", false, NULL},
|
{"\x00\x74", 2, "Compaq", false, NULL},
|
||||||
{"\x00\x76", 2, "Microsoft", false, NULL}, /* uses LSB for country but MSB for manufacturer */
|
{"\x00\x76", 2, "Microsoft", false, NULL}, /* Uses LSB for country but MSB for manufacturer */
|
||||||
{"\x00\x78", 2, "Cylink", false, NULL},
|
{"\x00\x78", 2, "Cylink", false, NULL},
|
||||||
{"\x00\x7A", 2, "Pitney Bowes", false, NULL},
|
{"\x00\x7A", 2, "Pitney Bowes", false, NULL},
|
||||||
{"\x00\x7C", 2, "Digiboard", false, NULL},
|
{"\x00\x7C", 2, "Digiboard", false, NULL},
|
||||||
@ -724,7 +724,7 @@ static const country_code_t t35_country_codes[255] =
|
|||||||
{"Vanuatu", NULL},
|
{"Vanuatu", NULL},
|
||||||
{"Vatican City State", NULL},
|
{"Vatican City State", NULL},
|
||||||
{"Venezuela", NULL},
|
{"Venezuela", NULL},
|
||||||
{"Viet Nam", vendor_bc},
|
{"Vietnam", vendor_bc},
|
||||||
{"Wallis and Futuna", NULL},
|
{"Wallis and Futuna", NULL},
|
||||||
{"Western Samoa", NULL},
|
{"Western Samoa", NULL},
|
||||||
{"Yemen (Republic of)", NULL},
|
{"Yemen (Republic of)", NULL},
|
||||||
|
@ -147,6 +147,7 @@ SPAN_DECLARE(const char *) t38_indicator_to_str(int indicator)
|
|||||||
case T38_IND_V33_14400_TRAINING:
|
case T38_IND_V33_14400_TRAINING:
|
||||||
return "v33-14400-training";
|
return "v33-14400-training";
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -186,6 +187,7 @@ SPAN_DECLARE(const char *) t38_data_type_to_str(int data_type)
|
|||||||
case T38_DATA_V33_14400:
|
case T38_DATA_V33_14400:
|
||||||
return "v33-14400";
|
return "v33-14400";
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -219,6 +221,7 @@ SPAN_DECLARE(const char *) t38_field_type_to_str(int field_type)
|
|||||||
case T38_FIELD_V34RATE:
|
case T38_FIELD_V34RATE:
|
||||||
return "v34rate";
|
return "v34rate";
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -240,6 +243,7 @@ SPAN_DECLARE(const char *) t38_cm_profile_to_str(int profile)
|
|||||||
case '6':
|
case '6':
|
||||||
return "V.34 HDX-only FAX receiving terminal";
|
return "V.34 HDX-only FAX receiving terminal";
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -248,6 +252,7 @@ SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len)
|
|||||||
{
|
{
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
return "???";
|
return "???";
|
||||||
|
/*endif*/
|
||||||
switch (data[0])
|
switch (data[0])
|
||||||
{
|
{
|
||||||
case 'A':
|
case 'A':
|
||||||
@ -256,6 +261,7 @@ SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len)
|
|||||||
case '0':
|
case '0':
|
||||||
return "ACK";
|
return "ACK";
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
switch (data[1])
|
switch (data[1])
|
||||||
@ -269,8 +275,10 @@ SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len)
|
|||||||
/* Response for profiles 5 and 6 */
|
/* Response for profiles 5 and 6 */
|
||||||
return "NACK: V.34 only FAX.";
|
return "NACK: V.34 only FAX.";
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -282,12 +290,15 @@ SPAN_DECLARE(int) t38_v34rate_to_bps(const uint8_t *data, int len)
|
|||||||
|
|
||||||
if (len < 3)
|
if (len < 3)
|
||||||
return -1;
|
return -1;
|
||||||
|
/*endif*/
|
||||||
for (i = 0, rate = 0; i < 3; i++)
|
for (i = 0, rate = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
if (data[i] < '0' || data[i] > '9')
|
if (data[i] < '0' || data[i] > '9')
|
||||||
return -1;
|
return -1;
|
||||||
|
/*endif*/
|
||||||
rate = rate*10 + data[i] - '0';
|
rate = rate*10 + data[i] - '0';
|
||||||
}
|
}
|
||||||
|
/*endfor*/
|
||||||
return rate*100;
|
return rate*100;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -307,11 +318,13 @@ static __inline__ int classify_seq_no_offset(int expected, int actual)
|
|||||||
/* In the near future */
|
/* In the near future */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (expected < actual + ACCEPTABLE_SEQ_NO_OFFSET)
|
if (expected < actual + ACCEPTABLE_SEQ_NO_OFFSET)
|
||||||
{
|
{
|
||||||
/* In the recent past */
|
/* In the recent past */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -320,12 +333,15 @@ static __inline__ int classify_seq_no_offset(int expected, int actual)
|
|||||||
/* In the near future */
|
/* In the near future */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (expected + 0x10000 - ACCEPTABLE_SEQ_NO_OFFSET < actual)
|
if (expected + 0x10000 - ACCEPTABLE_SEQ_NO_OFFSET < actual)
|
||||||
{
|
{
|
||||||
/* In the recent past */
|
/* In the recent past */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* There has been a huge step in the sequence */
|
/* There has been a huge step in the sequence */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -355,6 +371,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
sprintf(tag, "Rx %5d: IFP", log_seq_no);
|
sprintf(tag, "Rx %5d: IFP", log_seq_no);
|
||||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
|
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
ptr = 0;
|
ptr = 0;
|
||||||
pkt_len = len;
|
pkt_len = len;
|
||||||
switch (s->data_transport_protocol)
|
switch (s->data_transport_protocol)
|
||||||
@ -369,15 +386,19 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
/* Version */
|
/* Version */
|
||||||
if (buf[0] != 3)
|
if (buf[0] != 3)
|
||||||
return -1;
|
return -1;
|
||||||
|
/*endif*/
|
||||||
/* Reserved */
|
/* Reserved */
|
||||||
if (buf[1] != 0)
|
if (buf[1] != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
/*endif*/
|
||||||
/* Packet length - this includes the length of the header itself */
|
/* Packet length - this includes the length of the header itself */
|
||||||
pkt_len = (buf[2] << 8) | buf[3];
|
pkt_len = (buf[2] << 8) | buf[3];
|
||||||
if (len < pkt_len)
|
if (len < pkt_len)
|
||||||
return 0;
|
return 0;
|
||||||
|
/*endif*/
|
||||||
ptr = 4;
|
ptr = 4;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -385,8 +406,10 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
if ((ptr + 1) > pkt_len)
|
if ((ptr + 1) > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
data_field_present = buf[ptr] & 0x80;
|
data_field_present = buf[ptr] & 0x80;
|
||||||
type = (buf[ptr] >> 6) & 1;
|
type = (buf[ptr] >> 6) & 1;
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -398,6 +421,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Data field with indicator\n", log_seq_no);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Data field with indicator\n", log_seq_no);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* Any received indicator should mean we no longer have a valid concept of "last received data/field type". */
|
/* Any received indicator should mean we no longer have a valid concept of "last received data/field type". */
|
||||||
s->current_rx_data_type = -1;
|
s->current_rx_data_type = -1;
|
||||||
s->current_rx_field_type = -1;
|
s->current_rx_field_type = -1;
|
||||||
@ -406,12 +430,14 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
/* Extension */
|
/* Extension */
|
||||||
if ((ptr + 2) > pkt_len)
|
if ((ptr + 2) > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
t30_indicator = T38_IND_V8_ANSAM + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
t30_indicator = T38_IND_V8_ANSAM + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
||||||
if (t30_indicator > T38_IND_V33_14400_TRAINING)
|
if (t30_indicator > T38_IND_V33_14400_TRAINING)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown indicator - %d\n", log_seq_no, t30_indicator);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown indicator - %d\n", log_seq_no, t30_indicator);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -419,6 +445,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
t30_indicator = (buf[ptr] >> 1) & 0xF;
|
t30_indicator = (buf[ptr] >> 1) & 0xF;
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: indicator %s\n", log_seq_no, t38_indicator_to_str(t30_indicator));
|
span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: indicator %s\n", log_seq_no, t38_indicator_to_str(t30_indicator));
|
||||||
s->rx_indicator_handler(s, s->rx_user_data, t30_indicator);
|
s->rx_indicator_handler(s, s->rx_user_data, t30_indicator);
|
||||||
/* This must come after the indicator handler, so the handler routine sees the existing state of the
|
/* This must come after the indicator handler, so the handler routine sees the existing state of the
|
||||||
@ -431,12 +458,14 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
/* Extension */
|
/* Extension */
|
||||||
if ((ptr + 2) > pkt_len)
|
if ((ptr + 2) > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
t30_data = T38_DATA_V8 + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
t30_data = T38_DATA_V8 + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
||||||
if (t30_data > T38_DATA_V33_14400)
|
if (t30_data > T38_DATA_V33_14400)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown data type - %d\n", log_seq_no, t30_data);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown data type - %d\n", log_seq_no, t30_data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -447,16 +476,20 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown data type - %d\n", log_seq_no, t30_data);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown data type - %d\n", log_seq_no, t30_data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (!data_field_present)
|
if (!data_field_present)
|
||||||
{
|
{
|
||||||
/* This is kinda weird, but I guess if the length checks out we accept it. */
|
/* This is kinda weird, but I guess if the length checks out we accept it. */
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Data type with no data field\n", log_seq_no);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Data type with no data field\n", log_seq_no);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (ptr >= pkt_len)
|
if (ptr >= pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
count = buf[ptr++];
|
count = buf[ptr++];
|
||||||
//printf("Count is %d\n", count);
|
//printf("Count is %d\n", count);
|
||||||
/* Do a dummy run through the fields to check we have a complete and uncorrupted packet. */
|
/* Do a dummy run through the fields to check we have a complete and uncorrupted packet. */
|
||||||
@ -466,6 +499,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
{
|
{
|
||||||
if (ptr >= pkt_len)
|
if (ptr >= pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
if (s->t38_version == 0)
|
if (s->t38_version == 0)
|
||||||
{
|
{
|
||||||
/* The original version of T.38 with a typo in the ASN.1 spec. */
|
/* The original version of T.38 with a typo in the ASN.1 spec. */
|
||||||
@ -488,12 +522,15 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
ptr++;
|
ptr++;
|
||||||
else
|
else
|
||||||
other_half = true;
|
other_half = true;
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (t30_field_type > T38_FIELD_T4_NON_ECM_SIG_END)
|
if (t30_field_type > T38_FIELD_T4_NON_ECM_SIG_END)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown field type - %d\n", log_seq_no, t30_field_type);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown field type - %d\n", log_seq_no, t30_field_type);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -503,35 +540,45 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
{
|
{
|
||||||
if ((ptr + 2) > pkt_len)
|
if ((ptr + 2) > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
t30_field_type = T38_FIELD_CM_MESSAGE + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
t30_field_type = T38_FIELD_CM_MESSAGE + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
||||||
if (t30_field_type > T38_FIELD_V34RATE)
|
if (t30_field_type > T38_FIELD_V34RATE)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown field type - %d\n", log_seq_no, t30_field_type);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown field type - %d\n", log_seq_no, t30_field_type);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* Decode field_data */
|
/* Decode field_data */
|
||||||
if (field_data_present)
|
if (field_data_present)
|
||||||
{
|
{
|
||||||
if ((ptr + 2) > pkt_len)
|
if ((ptr + 2) > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
numocts = ((buf[ptr] << 8) | buf[ptr + 1]) + 1;
|
numocts = ((buf[ptr] << 8) | buf[ptr + 1]) + 1;
|
||||||
ptr += numocts + 2;
|
ptr += numocts + 2;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (ptr > pkt_len)
|
if (ptr > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endfor*/
|
||||||
/* Check if we finished mid byte in a version 0 packet. */
|
/* Check if we finished mid byte in a version 0 packet. */
|
||||||
if (other_half)
|
if (other_half)
|
||||||
ptr++;
|
ptr++;
|
||||||
|
/*endif*/
|
||||||
if (ptr > pkt_len)
|
if (ptr > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
|
|
||||||
/* Things look alright in the data, so lets run through the fields again, actually processing them.
|
/* Things look alright in the data, so lets run through the fields again, actually processing them.
|
||||||
There is no need to do all the error checking along the way on this pass. */
|
There is no need to do all the error checking along the way on this pass. */
|
||||||
@ -561,7 +608,9 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
ptr++;
|
ptr++;
|
||||||
else
|
else
|
||||||
other_half = true;
|
other_half = true;
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -576,7 +625,9 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
{
|
{
|
||||||
t30_field_type = (buf[ptr++] >> 3) & 0x7;
|
t30_field_type = (buf[ptr++] >> 3) & 0x7;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* Decode field_data */
|
/* Decode field_data */
|
||||||
if (field_data_present)
|
if (field_data_present)
|
||||||
{
|
{
|
||||||
@ -589,6 +640,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
numocts = 0;
|
numocts = 0;
|
||||||
msg = NULL;
|
msg = NULL;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
span_log(&s->logging,
|
span_log(&s->logging,
|
||||||
SPAN_LOG_FLOW,
|
SPAN_LOG_FLOW,
|
||||||
"Rx %5d: (%d) data %s/%s + %d byte(s)\n",
|
"Rx %5d: (%d) data %s/%s + %d byte(s)\n",
|
||||||
@ -601,13 +653,17 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
|||||||
s->current_rx_data_type = t30_data;
|
s->current_rx_data_type = t30_data;
|
||||||
s->current_rx_field_type = t30_field_type;
|
s->current_rx_field_type = t30_field_type;
|
||||||
}
|
}
|
||||||
|
/*endfor*/
|
||||||
/* Check if we finished mid byte in a version 0 packet. */
|
/* Check if we finished mid byte in a version 0 packet. */
|
||||||
if (other_half)
|
if (other_half)
|
||||||
ptr++;
|
ptr++;
|
||||||
|
/*endif*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
if (ptr > pkt_len)
|
if (ptr > pkt_len)
|
||||||
return ret;
|
return ret;
|
||||||
|
/*endif*/
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -645,6 +701,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8
|
|||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: Repeat packet number\n", log_seq_no);
|
span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: Repeat packet number\n", log_seq_no);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* Distinguish between a little bit out of sequence, and a huge hop. */
|
/* Distinguish between a little bit out of sequence, and a huge hop. */
|
||||||
switch (classify_seq_no_offset(s->rx_expected_seq_no, seq_no))
|
switch (classify_seq_no_offset(s->rx_expected_seq_no, seq_no))
|
||||||
{
|
{
|
||||||
@ -665,15 +722,20 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8
|
|||||||
s->missing_packets++;
|
s->missing_packets++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*endswitch*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
s->rx_expected_seq_no = seq_no;
|
s->rx_expected_seq_no = seq_no;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (len < 1)
|
if (len < 1)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Bad packet length - %d\n", log_seq_no, len);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Bad packet length - %d\n", log_seq_no, len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* The sequence numbering is defined as rolling from 0xFFFF to 0x0000. Some implementations
|
/* The sequence numbering is defined as rolling from 0xFFFF to 0x0000. Some implementations
|
||||||
of T.38 roll from 0xFFFF to 0x0001. Isn't standardisation a wonderful thing? The T.38
|
of T.38 roll from 0xFFFF to 0x0001. Isn't standardisation a wonderful thing? The T.38
|
||||||
document specifies only a small fraction of what it should, yet then they actually nail
|
document specifies only a small fraction of what it should, yet then they actually nail
|
||||||
@ -690,8 +752,10 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8
|
|||||||
{
|
{
|
||||||
if (ptr >= 0)
|
if (ptr >= 0)
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for packet - %d %d\n", log_seq_no, ptr, len);
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for packet - %d %d\n", log_seq_no, ptr, len);
|
||||||
|
/*endif*/
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -704,6 +768,7 @@ static int t38_encode_indicator(t38_core_state_t *s, uint8_t buf[], int indicato
|
|||||||
len = 0;
|
len = 0;
|
||||||
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
||||||
len = 4;
|
len = 4;
|
||||||
|
/*endif*/
|
||||||
|
|
||||||
/* Data field not present */
|
/* Data field not present */
|
||||||
/* Indicator packet */
|
/* Indicator packet */
|
||||||
@ -721,9 +786,10 @@ static int t38_encode_indicator(t38_core_state_t *s, uint8_t buf[], int indicato
|
|||||||
{
|
{
|
||||||
len = -1;
|
len = -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
||||||
{
|
{
|
||||||
/* Fill in the TPKT header (se RFC1006) */
|
/* Fill in the TPKT header (see RFC1006) */
|
||||||
/* Version */
|
/* Version */
|
||||||
buf[0] = 3;
|
buf[0] = 3;
|
||||||
/* Reserved */
|
/* Reserved */
|
||||||
@ -732,6 +798,7 @@ static int t38_encode_indicator(t38_core_state_t *s, uint8_t buf[], int indicato
|
|||||||
buf[2] = (len >> 8) & 0xFF;
|
buf[2] = (len >> 8) & 0xFF;
|
||||||
buf[3] = len & 0xFF;
|
buf[3] = len & 0xFF;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -755,6 +822,7 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
|||||||
len = 0;
|
len = 0;
|
||||||
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
||||||
len = 4;
|
len = 4;
|
||||||
|
/*endif*/
|
||||||
|
|
||||||
/* There seems no valid reason why a packet would ever be generated without a data field present */
|
/* There seems no valid reason why a packet would ever be generated without a data field present */
|
||||||
data_field_present = (fields > 0) ? 0x80 : 0x00;
|
data_field_present = (fields > 0) ? 0x80 : 0x00;
|
||||||
@ -775,6 +843,7 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
|
|
||||||
if (data_field_present)
|
if (data_field_present)
|
||||||
{
|
{
|
||||||
@ -803,6 +872,7 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
|||||||
buf[len++] = (uint8_t) (0xC0 | multiplier);
|
buf[len++] = (uint8_t) (0xC0 | multiplier);
|
||||||
enclen = 0x4000*multiplier;
|
enclen = 0x4000*multiplier;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
|
|
||||||
fragment_len = enclen;
|
fragment_len = enclen;
|
||||||
encoded_len += fragment_len;
|
encoded_len += fragment_len;
|
||||||
@ -817,6 +887,7 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
|||||||
/* Original version of T.38 with a typo */
|
/* Original version of T.38 with a typo */
|
||||||
if (q->field_type > T38_FIELD_T4_NON_ECM_SIG_END)
|
if (q->field_type > T38_FIELD_T4_NON_ECM_SIG_END)
|
||||||
return -1;
|
return -1;
|
||||||
|
/*endif*/
|
||||||
buf[len++] = (uint8_t) ((field_data_present << 7) | (q->field_type << 4));
|
buf[len++] = (uint8_t) ((field_data_present << 7) | (q->field_type << 4));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -834,22 +905,28 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
/* Encode field_data */
|
/* Encode field_data */
|
||||||
if (field_data_present)
|
if (field_data_present)
|
||||||
{
|
{
|
||||||
if (q->field_len < 1 || q->field_len > 65535)
|
if (q->field_len < 1 || q->field_len > 65535)
|
||||||
return -1;
|
return -1;
|
||||||
|
/*endif*/
|
||||||
buf[len++] = (uint8_t) (((q->field_len - 1) >> 8) & 0xFF);
|
buf[len++] = (uint8_t) (((q->field_len - 1) >> 8) & 0xFF);
|
||||||
buf[len++] = (uint8_t) ((q->field_len - 1) & 0xFF);
|
buf[len++] = (uint8_t) ((q->field_len - 1) & 0xFF);
|
||||||
memcpy(&buf[len], q->field, q->field_len);
|
memcpy(&buf[len], q->field, q->field_len);
|
||||||
len += q->field_len;
|
len += q->field_len;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
data_field_no++;
|
data_field_no++;
|
||||||
}
|
}
|
||||||
|
/*endfor*/
|
||||||
}
|
}
|
||||||
while ((int) encoded_len != fields || fragment_len >= 16384);
|
while ((int) encoded_len != fields || fragment_len >= 16384);
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
|
|
||||||
for (data_field_no = 0; data_field_no < fields; data_field_no++)
|
for (data_field_no = 0; data_field_no < fields; data_field_no++)
|
||||||
{
|
{
|
||||||
@ -862,6 +939,7 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
|||||||
t38_field_type_to_str(field[data_field_no].field_type),
|
t38_field_type_to_str(field[data_field_no].field_type),
|
||||||
field[data_field_no].field_len);
|
field[data_field_no].field_len);
|
||||||
}
|
}
|
||||||
|
/*endfor*/
|
||||||
|
|
||||||
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
||||||
{
|
{
|
||||||
@ -874,12 +952,14 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
|||||||
buf[2] = (len >> 8) & 0xFF;
|
buf[2] = (len >> 8) & 0xFF;
|
||||||
buf[3] = len & 0xFF;
|
buf[3] = len & 0xFF;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
|
|
||||||
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
|
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
|
||||||
{
|
{
|
||||||
sprintf(tag, "Tx %5d: IFP", s->tx_seq_no);
|
sprintf(tag, "Tx %5d: IFP", s->tx_seq_no);
|
||||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
|
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -907,22 +987,28 @@ SPAN_DECLARE(int) t38_core_send_indicator(t38_core_state_t *s, int indicator)
|
|||||||
span_log(&s->logging, SPAN_LOG_FLOW, "T.38 indicator len is %d\n", len);
|
span_log(&s->logging, SPAN_LOG_FLOW, "T.38 indicator len is %d\n", len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Tx %5d: indicator %s\n", s->tx_seq_no, t38_indicator_to_str(indicator));
|
span_log(&s->logging, SPAN_LOG_FLOW, "Tx %5d: indicator %s\n", s->tx_seq_no, t38_indicator_to_str(indicator));
|
||||||
if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, transmissions) < 0)
|
if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, transmissions) < 0)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx packet handler failure\n");
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx packet handler failure\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
||||||
if (s->pace_transmission)
|
if (s->pace_transmission)
|
||||||
{
|
{
|
||||||
delay = modem_startup_time[indicator].training;
|
delay = modem_startup_time[indicator].training;
|
||||||
if (s->allow_for_tep)
|
if (s->allow_for_tep)
|
||||||
delay += modem_startup_time[indicator].tep;
|
delay += modem_startup_time[indicator].tep;
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
s->current_tx_indicator = indicator;
|
s->current_tx_indicator = indicator;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
return delay;
|
return delay;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -931,6 +1017,7 @@ SPAN_DECLARE(int) t38_core_send_flags_delay(t38_core_state_t *s, int indicator)
|
|||||||
{
|
{
|
||||||
if (s->pace_transmission)
|
if (s->pace_transmission)
|
||||||
return modem_startup_time[indicator].flags;
|
return modem_startup_time[indicator].flags;
|
||||||
|
/*endif*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -939,6 +1026,7 @@ SPAN_DECLARE(int) t38_core_send_training_delay(t38_core_state_t *s, int indicato
|
|||||||
{
|
{
|
||||||
if (s->pace_transmission)
|
if (s->pace_transmission)
|
||||||
return modem_startup_time[indicator].training;
|
return modem_startup_time[indicator].training;
|
||||||
|
/*endif*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -957,11 +1045,13 @@ SPAN_DECLARE(int) t38_core_send_data(t38_core_state_t *s, int data_type, int fie
|
|||||||
span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len);
|
span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]) < 0)
|
if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]) < 0)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx packet handler failure\n");
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx packet handler failure\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -977,11 +1067,13 @@ SPAN_DECLARE(int) t38_core_send_data_multi_field(t38_core_state_t *s, int data_t
|
|||||||
span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len);
|
span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]) < 0)
|
if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]) < 0)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx packet handler failure\n");
|
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx packet handler failure\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1109,7 +1201,9 @@ SPAN_DECLARE(t38_core_state_t *) t38_core_init(t38_core_state_t *s,
|
|||||||
{
|
{
|
||||||
if ((s = (t38_core_state_t *) span_alloc(sizeof(*s))) == NULL)
|
if ((s = (t38_core_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
memset(s, 0, sizeof(*s));
|
memset(s, 0, sizeof(*s));
|
||||||
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
||||||
span_log_set_protocol(&s->logging, "T.38");
|
span_log_set_protocol(&s->logging, "T.38");
|
||||||
|
@ -1105,7 +1105,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
|||||||
{
|
{
|
||||||
monitor_control_messages(s, false, hdlc_buf->buf, hdlc_buf->len);
|
monitor_control_messages(s, false, hdlc_buf->buf, hdlc_buf->len);
|
||||||
if (s->core.real_time_frame_handler)
|
if (s->core.real_time_frame_handler)
|
||||||
s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, false, hdlc_buf->buf, hdlc_buf->len);
|
s->core.real_time_frame_handler(s->core.real_time_frame_user_data, false, hdlc_buf->buf, hdlc_buf->len);
|
||||||
/*endif*/
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
@ -1193,7 +1193,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
|||||||
{
|
{
|
||||||
monitor_control_messages(s, false, hdlc_buf->buf, hdlc_buf->len);
|
monitor_control_messages(s, false, hdlc_buf->buf, hdlc_buf->len);
|
||||||
if (s->core.real_time_frame_handler)
|
if (s->core.real_time_frame_handler)
|
||||||
s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, false, hdlc_buf->buf, hdlc_buf->len);
|
s->core.real_time_frame_handler(s->core.real_time_frame_user_data, false, hdlc_buf->buf, hdlc_buf->len);
|
||||||
/*endif*/
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
@ -1830,7 +1830,7 @@ static void rx_flag_or_abort(hdlc_rx_state_t *t)
|
|||||||
{
|
{
|
||||||
monitor_control_messages(s, true, t->buffer, t->len - 2);
|
monitor_control_messages(s, true, t->buffer, t->len - 2);
|
||||||
if (s->core.real_time_frame_handler)
|
if (s->core.real_time_frame_handler)
|
||||||
s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, true, t->buffer, t->len - 2);
|
s->core.real_time_frame_handler(s->core.real_time_frame_user_data, true, t->buffer, t->len - 2);
|
||||||
/*endif*/
|
/*endif*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1937,13 +1937,13 @@ static void t38_hdlc_rx_put_bit(hdlc_rx_state_t *t, int new_bit)
|
|||||||
if (t->len == 1)
|
if (t->len == 1)
|
||||||
{
|
{
|
||||||
/* All valid HDLC frames in FAX communication begin 0xFF 0x03 or 0xFF 0x13.
|
/* All valid HDLC frames in FAX communication begin 0xFF 0x03 or 0xFF 0x13.
|
||||||
Anything else is bogus, */
|
Anything else is bogus. */
|
||||||
if (t->buffer[0] != 0xFF || (t->buffer[1] & 0xEF) != 0x03)
|
if (t->buffer[0] != 0xFF || (t->buffer[1] & 0xEF) != 0x03)
|
||||||
{
|
{
|
||||||
/* Abandon the frame, and wait for the next flag octet. */
|
/* Abandon the frame, and wait for the next flag octet. */
|
||||||
/* If this is a real frame, where one of these first two octets has a bit
|
/* If this is a real frame, where one of these first two octets has a bit
|
||||||
error, we will fail to forward the frame with a CRC error, as we do for
|
error, we will fail to forward the frame with a CRC error, as we do for
|
||||||
other bad framess. This will affect the timing of what goes forward.
|
other bad frames. This will affect the timing of what goes forward.
|
||||||
Hopefully such timing changes will have less frequent bad effects than
|
Hopefully such timing changes will have less frequent bad effects than
|
||||||
the consequences of a bad bit stream simulating an HDLC frame start. */
|
the consequences of a bad bit stream simulating an HDLC frame start. */
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad HDLC frame header. Abandoning frame.\n");
|
span_log(&s->logging, SPAN_LOG_FLOW, "Bad HDLC frame header. Abandoning frame.\n");
|
||||||
|
@ -330,6 +330,7 @@ static void process_hdlc_data(t38_terminal_front_end_state_t *fe, const uint8_t
|
|||||||
{
|
{
|
||||||
fe->rx_data_missing = true;
|
fe->rx_data_missing = true;
|
||||||
}
|
}
|
||||||
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -95,14 +95,14 @@ int has_MMX(void)
|
|||||||
/*endif*/
|
/*endif*/
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" push %%ebx;\n"
|
" push %%ebx;\n"
|
||||||
" mov $1,%%eax;\n"
|
" mov $1,%%eax;\n"
|
||||||
" cpuid;\n"
|
" cpuid;\n"
|
||||||
" xor %%eax,%%eax;\n"
|
" xor %%eax,%%eax;\n"
|
||||||
" test $0x800000,%%edx;\n"
|
" test $0x800000,%%edx;\n"
|
||||||
" jz 1f;\n" /* no MMX support */
|
" jz 1f;\n" /* no MMX support */
|
||||||
" inc %%eax;\n" /* MMX support */
|
" inc %%eax;\n" /* MMX support */
|
||||||
"1:\n"
|
"1:\n"
|
||||||
" pop %%ebx;\n"
|
" pop %%ebx;\n"
|
||||||
: "=a" (result)
|
: "=a" (result)
|
||||||
:
|
:
|
||||||
: "ecx", "edx");
|
: "ecx", "edx");
|
||||||
@ -119,14 +119,14 @@ int has_SIMD(void)
|
|||||||
/*endif*/
|
/*endif*/
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" push %%ebx;\n"
|
" push %%ebx;\n"
|
||||||
" mov $1,%%eax;\n"
|
" mov $1,%%eax;\n"
|
||||||
" cpuid;\n"
|
" cpuid;\n"
|
||||||
" xor %%eax,%%eax;\n"
|
" xor %%eax,%%eax;\n"
|
||||||
" test $0x02000000,%%edx;\n"
|
" test $0x02000000,%%edx;\n"
|
||||||
" jz 1f;\n" /* no SIMD support */
|
" jz 1f;\n" /* no SIMD support */
|
||||||
" inc %%eax;\n" /* SIMD support */
|
" inc %%eax;\n" /* SIMD support */
|
||||||
"1:\n"
|
"1:\n"
|
||||||
" pop %%ebx;\n"
|
" pop %%ebx;\n"
|
||||||
: "=a" (result)
|
: "=a" (result)
|
||||||
:
|
:
|
||||||
: "ecx", "edx");
|
: "ecx", "edx");
|
||||||
@ -143,14 +143,14 @@ int has_SIMD2(void)
|
|||||||
/*endif*/
|
/*endif*/
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" push %%ebx;\n"
|
" push %%ebx;\n"
|
||||||
" mov $1,%%eax;\n"
|
" mov $1,%%eax;\n"
|
||||||
" cpuid;\n"
|
" cpuid;\n"
|
||||||
" xor %%eax,%%eax;\n"
|
" xor %%eax,%%eax;\n"
|
||||||
" test $0x04000000,%%edx;\n"
|
" test $0x04000000,%%edx;\n"
|
||||||
" jz 1f;\n" /* no SIMD2 support */
|
" jz 1f;\n" /* no SIMD2 support */
|
||||||
" inc %%eax;\n" /* SIMD2 support */
|
" inc %%eax;\n" /* SIMD2 support */
|
||||||
"1:\n"
|
"1:\n"
|
||||||
" pop %%ebx;\n"
|
" pop %%ebx;\n"
|
||||||
: "=a" (result)
|
: "=a" (result)
|
||||||
:
|
:
|
||||||
: "ecx", "edx");
|
: "ecx", "edx");
|
||||||
@ -167,19 +167,19 @@ int has_3DNow(void)
|
|||||||
/*endif*/
|
/*endif*/
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" push %%ebx;\n"
|
" push %%ebx;\n"
|
||||||
" mov $0x80000000,%%eax;\n"
|
" mov $0x80000000,%%eax;\n"
|
||||||
" cpuid;\n"
|
" cpuid;\n"
|
||||||
" xor %%ecx,%%ecx;\n"
|
" xor %%ecx,%%ecx;\n"
|
||||||
" cmp $0x80000000,%%eax;\n"
|
" cmp $0x80000000,%%eax;\n"
|
||||||
" jbe 1f;\n" /* no extended MSR(1), so no 3DNow! */
|
" jbe 1f;\n" /* no extended MSR(1), so no 3DNow! */
|
||||||
" mov $0x80000001,%%eax;\n"
|
" mov $0x80000001,%%eax;\n"
|
||||||
" cpuid;\n"
|
" cpuid;\n"
|
||||||
" xor %%ecx,%%ecx;\n"
|
" xor %%ecx,%%ecx;\n"
|
||||||
" test $0x80000000,%%edx;\n"
|
" test $0x80000000,%%edx;\n"
|
||||||
" jz 1f;\n" /* no 3DNow! support */
|
" jz 1f;\n" /* no 3DNow! support */
|
||||||
" inc %%ecx;\n" /* 3DNow! support */
|
" inc %%ecx;\n" /* 3DNow! support */
|
||||||
"1:\n"
|
"1:\n"
|
||||||
" pop %%ebx;\n"
|
" pop %%ebx;\n"
|
||||||
: "=c" (result)
|
: "=c" (result)
|
||||||
:
|
:
|
||||||
: "eax", "edx");
|
: "eax", "edx");
|
||||||
|
@ -258,7 +258,7 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||||||
if (s->playout_rate < 1.0f)
|
if (s->playout_rate < 1.0f)
|
||||||
{
|
{
|
||||||
/* Speed up - drop a chunk of data */
|
/* Speed up - drop a chunk of data */
|
||||||
overlap_add(s->buf, s->buf + pitch, pitch);
|
overlap_add(s->buf, &s->buf[pitch], pitch);
|
||||||
memcpy(&s->buf[pitch], &s->buf[2*pitch], sizeof(int16_t)*(s->buf_len - 2*pitch));
|
memcpy(&s->buf[pitch], &s->buf[2*pitch], sizeof(int16_t)*(s->buf_len - 2*pitch));
|
||||||
if (len - in_len < pitch)
|
if (len - in_len < pitch)
|
||||||
{
|
{
|
||||||
@ -275,7 +275,7 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||||||
/* Slow down - insert a chunk of data */
|
/* Slow down - insert a chunk of data */
|
||||||
memcpy(&out[out_len], s->buf, sizeof(int16_t)*pitch);
|
memcpy(&out[out_len], s->buf, sizeof(int16_t)*pitch);
|
||||||
out_len += pitch;
|
out_len += pitch;
|
||||||
overlap_add(s->buf + pitch, s->buf, pitch);
|
overlap_add(&s->buf[pitch], s->buf, pitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1144,7 @@ SPAN_DECLARE(int) v8_free(v8_state_t *s)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = queue_free(s->tx_queue);
|
ret = v8_release(s);
|
||||||
span_free(s);
|
span_free(s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,17 @@ typedef void (*faxtester_front_end_step_complete_handler_t)(faxtester_state_t *s
|
|||||||
*/
|
*/
|
||||||
struct faxtester_state_s
|
struct faxtester_state_s
|
||||||
{
|
{
|
||||||
|
/*! \brief The far end FAX context */
|
||||||
|
fax_state_t *far_fax;
|
||||||
|
|
||||||
|
/*! \brief The far end T.38 terminal context */
|
||||||
|
t38_terminal_state_t *far_t38_fax;
|
||||||
|
|
||||||
|
/*! \brief Path for the FAX image test files. */
|
||||||
|
char image_path[1024];
|
||||||
|
|
||||||
|
/*! \brief Pointer to the XML document. */
|
||||||
|
xmlDocPtr doc;
|
||||||
/*! \brief Pointer to our current step in the test. */
|
/*! \brief Pointer to our current step in the test. */
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
|
|
||||||
@ -113,6 +124,19 @@ struct faxtester_state_s
|
|||||||
int64_t timer;
|
int64_t timer;
|
||||||
int64_t timeout;
|
int64_t timeout;
|
||||||
|
|
||||||
|
bool test_for_call_clear;
|
||||||
|
int call_clear_timer;
|
||||||
|
|
||||||
|
bool far_end_cleared_call;
|
||||||
|
|
||||||
|
int timein_x;
|
||||||
|
int timeout_x;
|
||||||
|
|
||||||
|
uint8_t awaited[1000];
|
||||||
|
int awaited_len;
|
||||||
|
|
||||||
|
char next_tx_file[1000];
|
||||||
|
|
||||||
/*! \brief Error and flow logging control */
|
/*! \brief Error and flow logging control */
|
||||||
logging_state_t logging;
|
logging_state_t logging;
|
||||||
};
|
};
|
||||||
|
@ -1420,7 +1420,6 @@ static int parse_test_group(faxtester_state_t *s, xmlDocPtr doc, xmlNsPtr ns, xm
|
|||||||
static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test)
|
static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test)
|
||||||
{
|
{
|
||||||
xmlParserCtxtPtr ctxt;
|
xmlParserCtxtPtr ctxt;
|
||||||
xmlDocPtr doc;
|
|
||||||
xmlNsPtr ns;
|
xmlNsPtr ns;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
|
|
||||||
@ -1435,7 +1434,7 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/* parse the file, activating the DTD validation option */
|
/* parse the file, activating the DTD validation option */
|
||||||
if ((doc = xmlCtxtReadFile(ctxt, test_file, NULL, XML_PARSE_XINCLUDE | XML_PARSE_DTDVALID)) == NULL)
|
if ((s->doc = xmlCtxtReadFile(ctxt, test_file, NULL, XML_PARSE_XINCLUDE | XML_PARSE_DTDVALID)) == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to read the XML document\n");
|
fprintf(stderr, "Failed to read the XML document\n");
|
||||||
printf("Test failed\n");
|
printf("Test failed\n");
|
||||||
@ -1444,7 +1443,7 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
|||||||
if (ctxt->valid == 0)
|
if (ctxt->valid == 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to validate the XML document\n");
|
fprintf(stderr, "Failed to validate the XML document\n");
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(s->doc);
|
||||||
xmlFreeParserCtxt(ctxt);
|
xmlFreeParserCtxt(ctxt);
|
||||||
printf("Test failed\n");
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
@ -1452,9 +1451,9 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
|||||||
xmlFreeParserCtxt(ctxt);
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
|
||||||
/* Check the document is of the right kind */
|
/* Check the document is of the right kind */
|
||||||
if ((cur = xmlDocGetRootElement(doc)) == NULL)
|
if ((cur = xmlDocGetRootElement(s->doc)) == NULL)
|
||||||
{
|
{
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(s->doc);
|
||||||
fprintf(stderr, "Empty document\n");
|
fprintf(stderr, "Empty document\n");
|
||||||
printf("Test failed\n");
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
@ -1462,7 +1461,7 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
|||||||
/*endif*/
|
/*endif*/
|
||||||
if (xmlStrcmp(cur->name, (const xmlChar *) "fax-tests"))
|
if (xmlStrcmp(cur->name, (const xmlChar *) "fax-tests"))
|
||||||
{
|
{
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(s->doc);
|
||||||
fprintf(stderr, "Document of the wrong type, root node != fax-tests");
|
fprintf(stderr, "Document of the wrong type, root node != fax-tests");
|
||||||
printf("Test failed\n");
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
@ -1482,12 +1481,12 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
|||||||
{
|
{
|
||||||
if (xmlStrcmp(cur->name, (const xmlChar *) "config") == 0)
|
if (xmlStrcmp(cur->name, (const xmlChar *) "config") == 0)
|
||||||
{
|
{
|
||||||
parse_config(s, doc, ns, cur->xmlChildrenNode);
|
parse_config(s, s->doc, ns, cur->xmlChildrenNode);
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
if (xmlStrcmp(cur->name, (const xmlChar *) "test-group") == 0)
|
if (xmlStrcmp(cur->name, (const xmlChar *) "test-group") == 0)
|
||||||
{
|
{
|
||||||
if (parse_test_group(s, doc, ns, cur->xmlChildrenNode, test) == 0)
|
if (parse_test_group(s, s->doc, ns, cur->xmlChildrenNode, test) == 0)
|
||||||
{
|
{
|
||||||
/* We found the test we want, so run it. */
|
/* We found the test we want, so run it. */
|
||||||
exchange(s);
|
exchange(s);
|
||||||
@ -1499,7 +1498,7 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
|||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
/*endwhile*/
|
/*endwhile*/
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(s->doc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user