mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-12 23:40: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;
|
||||
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 */
|
||||
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:
|
||||
return "Link idle";
|
||||
}
|
||||
/*endswitch*/
|
||||
return "???";
|
||||
}
|
||||
/*- 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)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
/* Step to the next digit */
|
||||
if ((cp = strchr(bell_mf_tone_codes, digit)) == NULL)
|
||||
continue;
|
||||
tone_gen_init(&(s->tones), &bell_mf_digit_tones[cp - bell_mf_tone_codes]);
|
||||
len += tone_gen(&(s->tones), amp + len, max_samples - len);
|
||||
tone_gen_init(&s->tones, &bell_mf_digit_tones[cp - bell_mf_tone_codes]);
|
||||
len += tone_gen(&s->tones, amp + len, max_samples - 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)
|
||||
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;
|
||||
queue_init(&s->queue.queue, MAX_BELL_MF_DIGITS, QUEUE_READ_ATOMIC | QUEUE_WRITE_ATOMIC);
|
||||
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. */
|
||||
if (len >= 0 && ok)
|
||||
s->rx_frame_received = true;
|
||||
/*endif*/
|
||||
if (s->hdlc_accept)
|
||||
s->hdlc_accept(s->hdlc_accept_user_data, msg, len, ok);
|
||||
/*endif*/
|
||||
}
|
||||
/*- 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);
|
||||
else
|
||||
hdlc_tx_frame(&s->hdlc_tx, msg, len);
|
||||
/*endif*/
|
||||
}
|
||||
/*- 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);
|
||||
return 0;
|
||||
}
|
||||
/*endif*/
|
||||
/* There is nothing else to change to, so use zero length silence */
|
||||
silence_gen_alter(&s->silence_gen, 0);
|
||||
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)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
@ -53,7 +53,7 @@ static __inline__ int16_t gsm_add(int16_t a, int16_t b)
|
||||
int32_t sum;
|
||||
|
||||
sum = (int32_t) a + (int32_t) b;
|
||||
return saturate16(sum);
|
||||
return saturate16(sum);
|
||||
#endif
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -78,17 +78,17 @@ static __inline__ int32_t gsm_l_add(int32_t a, int32_t b)
|
||||
if (a < 0)
|
||||
{
|
||||
if (b >= 0)
|
||||
return a + b;
|
||||
return a + b;
|
||||
/*endif*/
|
||||
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*/
|
||||
if (b <= 0)
|
||||
return a + b;
|
||||
return a + b;
|
||||
/*endif*/
|
||||
A = (uint32_t) a + (uint32_t) b;
|
||||
return (A > INT32_MAX) ? INT32_MAX : A;
|
||||
return (A > INT32_MAX) ? INT32_MAX : A;
|
||||
#endif
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -98,23 +98,23 @@ static __inline__ int16_t gsm_sub(int16_t a, int16_t b)
|
||||
int32_t diff;
|
||||
|
||||
diff = (int32_t) a - (int32_t) b;
|
||||
return saturate16(diff);
|
||||
return saturate16(diff);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int16_t gsm_mult(int16_t a, int16_t b)
|
||||
{
|
||||
if (a == INT16_MIN && b == INT16_MIN)
|
||||
return INT16_MAX;
|
||||
return INT16_MAX;
|
||||
/*endif*/
|
||||
return (int16_t) (((int32_t) a * (int32_t) b) >> 15);
|
||||
return (int16_t) (((int32_t) a * (int32_t) b) >> 15);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int32_t gsm_l_mult(int16_t a, int16_t b)
|
||||
{
|
||||
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 --------------------------------------------------------*/
|
||||
|
||||
@ -123,47 +123,47 @@ static __inline__ int16_t gsm_mult_r(int16_t a, int16_t b)
|
||||
int32_t prod;
|
||||
|
||||
if (b == INT16_MIN && a == INT16_MIN)
|
||||
return INT16_MAX;
|
||||
return INT16_MAX;
|
||||
/*endif*/
|
||||
prod = (int32_t) a * (int32_t) b + 16384;
|
||||
prod >>= 15;
|
||||
return (int16_t) (prod & 0xFFFF);
|
||||
return (int16_t) (prod & 0xFFFF);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
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 --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int16_t gsm_asr(int16_t a, int n)
|
||||
{
|
||||
if (n >= 16)
|
||||
return (int16_t) (-(a < 0));
|
||||
return (int16_t) (-(a < 0));
|
||||
/*endif*/
|
||||
if (n <= -16)
|
||||
return 0;
|
||||
return 0;
|
||||
/*endif*/
|
||||
if (n < 0)
|
||||
return (int16_t) (a << -n);
|
||||
/*endif*/
|
||||
return (int16_t) (a >> n);
|
||||
return (int16_t) (a >> n);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int16_t gsm_asl(int16_t a, int n)
|
||||
{
|
||||
if (n >= 16)
|
||||
return 0;
|
||||
return 0;
|
||||
/*endif*/
|
||||
if (n <= -16)
|
||||
return (int16_t) (-(a < 0));
|
||||
return (int16_t) (-(a < 0));
|
||||
/*endif*/
|
||||
if (n < 0)
|
||||
return gsm_asr(a, -n);
|
||||
return gsm_asr(a, -n);
|
||||
/*endif*/
|
||||
return (int16_t) (a << n);
|
||||
return (int16_t) (a << n);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
static void weighting_filter(int16_t x[40],
|
||||
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 */
|
||||
/* This must be padded to a multiple of 4 for MMX to work */
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
/*endfor*/
|
||||
|
@ -322,12 +322,12 @@ extern "C"
|
||||
#if (_MSC_VER < 1800)
|
||||
__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)
|
||||
{
|
||||
return _mm_cvt_ss2si( _mm_load_ss((const float*)&x) );
|
||||
return _mm_cvt_ss2si(_mm_load_ss((const float *) &x));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -88,10 +88,10 @@ static __inline__ const int16_t *fir16_create(fir16_state_t *fir,
|
||||
fir->curr_pos = taps - 1;
|
||||
fir->coeffs = coeffs;
|
||||
#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));
|
||||
#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));
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
free(fir->history);
|
||||
span_free(fir->history);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@ -210,7 +210,7 @@ static __inline__ const int16_t *fir32_create(fir32_state_t *fir,
|
||||
fir->taps = taps;
|
||||
fir->curr_pos = taps - 1;
|
||||
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)
|
||||
memset(fir->history, '\0', taps*sizeof(int16_t));
|
||||
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)
|
||||
{
|
||||
free(fir->history);
|
||||
span_free(fir->history);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@ -258,7 +258,7 @@ static __inline__ const float *fir_float_create(fir_float_state_t *fir,
|
||||
fir->taps = taps;
|
||||
fir->curr_pos = taps - 1;
|
||||
fir->coeffs = coeffs;
|
||||
fir->history = (float *) malloc(taps*sizeof(float));
|
||||
fir->history = (float *) span_alloc(taps*sizeof(float));
|
||||
if (fir->history)
|
||||
memset(fir->history, '\0', taps*sizeof(float));
|
||||
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)
|
||||
{
|
||||
free(fir->history);
|
||||
span_free(fir->history);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -81,7 +81,8 @@ extern "C"
|
||||
{
|
||||
#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 crc32 True to use ITU CRC32. False to use ITU CRC16.
|
||||
\param report_bad_frames True to request the reporting of bad frames.
|
||||
|
@ -106,9 +106,9 @@ struct at_state_s
|
||||
int command_dial;
|
||||
int ok_is_pending;
|
||||
int dte_is_waiting;
|
||||
/*! \brief True if a carrier is presnt. Otherwise false. */
|
||||
/*! \brief True if a carrier is present. */
|
||||
bool rx_signal_present;
|
||||
/*! \brief True if a modem has trained, Otherwise false. */
|
||||
/*! \brief True if a modem has trained, */
|
||||
bool rx_trained;
|
||||
int transmit;
|
||||
|
||||
|
@ -88,7 +88,7 @@ struct r2_mf_rx_state_s
|
||||
tone_report_func_t callback;
|
||||
/*! An opaque pointer passed to the callback function. */
|
||||
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;
|
||||
/*! Tone detector working states */
|
||||
goertzel_state_t out[6];
|
||||
|
@ -48,7 +48,7 @@ typedef struct
|
||||
struct g722_encode_state_s
|
||||
{
|
||||
/*! True if operating in the special ITU test mode, with the band split filters
|
||||
disabled. */
|
||||
disabled. */
|
||||
bool itu_test_mode;
|
||||
/*! True if the G.722 data is packed */
|
||||
bool packed;
|
||||
@ -74,7 +74,7 @@ struct g722_encode_state_s
|
||||
struct g722_decode_state_s
|
||||
{
|
||||
/*! True if operating in the special ITU test mode, with the band split filters
|
||||
disabled. */
|
||||
disabled. */
|
||||
bool itu_test_mode;
|
||||
/*! True if the G.722 data is packed */
|
||||
bool packed;
|
||||
|
@ -133,7 +133,7 @@ struct v42_state_s
|
||||
{
|
||||
/*! True if we are the calling party, otherwise false. */
|
||||
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. */
|
||||
bool detect;
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
\section t30_page_sec_1 What does it do?
|
||||
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
|
||||
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;
|
||||
|
||||
/*!
|
||||
T.30 real time frame handler.
|
||||
\brief T.30 real time frame handler.
|
||||
\param s The T.30 context.
|
||||
T.38 gateway real time frame handler.
|
||||
\brief T.38 gateway real time frame handler.
|
||||
\param user_data An opaque pointer.
|
||||
\param incoming True for incoming, false for outgoing.
|
||||
\param msg The HDLC message.
|
||||
\param len The length of the message.
|
||||
*/
|
||||
typedef void (*t38_gateway_real_time_frame_handler_t)(t38_gateway_state_t *s,
|
||||
void *user_data,
|
||||
typedef void (*t38_gateway_real_time_frame_handler_t)(void *user_data,
|
||||
bool incoming,
|
||||
const uint8_t *msg,
|
||||
int len);
|
||||
|
@ -78,7 +78,7 @@ SPAN_DECLARE(void) make_goertzel_descriptor(goertzel_descriptor_t *t,
|
||||
int samples);
|
||||
|
||||
/*! \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.
|
||||
\return A pointer to the Goertzel state. */
|
||||
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;
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Start receiving document\n");
|
||||
queue_phase(s, T30_PHASE_B_TX);
|
||||
s->ecm_block = 0;
|
||||
send_dis_or_dtc_sequence(s, true);
|
||||
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);
|
||||
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 */
|
||||
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);
|
||||
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. */
|
||||
send_dcn(s);
|
||||
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->next_phase = phase;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Queuing phase %s\n", phase_names[s->next_phase]);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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]);
|
||||
/* 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/crc.h"
|
||||
#include "spandsp/hdlc.h"
|
||||
#include "spandsp/vector_int.h"
|
||||
#include "spandsp/silence_gen.h"
|
||||
#include "spandsp/super_tone_rx.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
|
||||
the right thing to do after receiving a message saying the signal has
|
||||
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;
|
||||
len = fe->octets_per_data_packet;
|
||||
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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
/*endif*/
|
||||
|
@ -500,7 +500,7 @@ static const nsf_data_t vendor_b5[] =
|
||||
{"\x00\x6E", 2, "Microsoft", false, NULL},
|
||||
{"\x00\x72", 2, "Speaking Devices", 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\x7A", 2, "Pitney Bowes", false, NULL},
|
||||
{"\x00\x7C", 2, "Digiboard", false, NULL},
|
||||
@ -724,7 +724,7 @@ static const country_code_t t35_country_codes[255] =
|
||||
{"Vanuatu", NULL},
|
||||
{"Vatican City State", NULL},
|
||||
{"Venezuela", NULL},
|
||||
{"Viet Nam", vendor_bc},
|
||||
{"Vietnam", vendor_bc},
|
||||
{"Wallis and Futuna", NULL},
|
||||
{"Western Samoa", 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:
|
||||
return "v33-14400-training";
|
||||
}
|
||||
/*endswitch*/
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -186,6 +187,7 @@ SPAN_DECLARE(const char *) t38_data_type_to_str(int data_type)
|
||||
case T38_DATA_V33_14400:
|
||||
return "v33-14400";
|
||||
}
|
||||
/*endswitch*/
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -219,6 +221,7 @@ SPAN_DECLARE(const char *) t38_field_type_to_str(int field_type)
|
||||
case T38_FIELD_V34RATE:
|
||||
return "v34rate";
|
||||
}
|
||||
/*endswitch*/
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -240,6 +243,7 @@ SPAN_DECLARE(const char *) t38_cm_profile_to_str(int profile)
|
||||
case '6':
|
||||
return "V.34 HDX-only FAX receiving terminal";
|
||||
}
|
||||
/*endswitch*/
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -248,6 +252,7 @@ SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len)
|
||||
{
|
||||
if (len < 2)
|
||||
return "???";
|
||||
/*endif*/
|
||||
switch (data[0])
|
||||
{
|
||||
case 'A':
|
||||
@ -256,6 +261,7 @@ SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len)
|
||||
case '0':
|
||||
return "ACK";
|
||||
}
|
||||
/*endswitch*/
|
||||
break;
|
||||
case 'N':
|
||||
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 */
|
||||
return "NACK: V.34 only FAX.";
|
||||
}
|
||||
/*endswitch*/
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -282,12 +290,15 @@ SPAN_DECLARE(int) t38_v34rate_to_bps(const uint8_t *data, int len)
|
||||
|
||||
if (len < 3)
|
||||
return -1;
|
||||
/*endif*/
|
||||
for (i = 0, rate = 0; i < 3; i++)
|
||||
{
|
||||
if (data[i] < '0' || data[i] > '9')
|
||||
return -1;
|
||||
/*endif*/
|
||||
rate = rate*10 + data[i] - '0';
|
||||
}
|
||||
/*endfor*/
|
||||
return rate*100;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -307,11 +318,13 @@ static __inline__ int classify_seq_no_offset(int expected, int actual)
|
||||
/* In the near future */
|
||||
return 1;
|
||||
}
|
||||
/*endif*/
|
||||
if (expected < actual + ACCEPTABLE_SEQ_NO_OFFSET)
|
||||
{
|
||||
/* In the recent past */
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -320,12 +333,15 @@ static __inline__ int classify_seq_no_offset(int expected, int actual)
|
||||
/* In the near future */
|
||||
return 1;
|
||||
}
|
||||
/*endif*/
|
||||
if (expected + 0x10000 - ACCEPTABLE_SEQ_NO_OFFSET < actual)
|
||||
{
|
||||
/* In the recent past */
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
/* There has been a huge step in the sequence */
|
||||
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);
|
||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
|
||||
}
|
||||
/*endif*/
|
||||
ptr = 0;
|
||||
pkt_len = len;
|
||||
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 */
|
||||
if (buf[0] != 3)
|
||||
return -1;
|
||||
/*endif*/
|
||||
/* Reserved */
|
||||
if (buf[1] != 0)
|
||||
return -1;
|
||||
/*endif*/
|
||||
/* Packet length - this includes the length of the header itself */
|
||||
pkt_len = (buf[2] << 8) | buf[3];
|
||||
if (len < pkt_len)
|
||||
return 0;
|
||||
/*endif*/
|
||||
ptr = 4;
|
||||
}
|
||||
/*endif*/
|
||||
ret = -1;
|
||||
break;
|
||||
default:
|
||||
@ -385,8 +406,10 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
if ((ptr + 1) > pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
data_field_present = buf[ptr] & 0x80;
|
||||
type = (buf[ptr] >> 6) & 1;
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
/* 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_field_type = -1;
|
||||
@ -406,12 +430,14 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
||||
/* Extension */
|
||||
if ((ptr + 2) > pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
t30_indicator = T38_IND_V8_ANSAM + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
ptr += 2;
|
||||
}
|
||||
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;
|
||||
ptr += 1;
|
||||
}
|
||||
/*endif*/
|
||||
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);
|
||||
/* 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 */
|
||||
if ((ptr + 2) > pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
t30_data = T38_DATA_V8 + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
ptr += 2;
|
||||
}
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
ptr += 1;
|
||||
}
|
||||
/*endif*/
|
||||
if (!data_field_present)
|
||||
{
|
||||
/* 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);
|
||||
break;
|
||||
}
|
||||
/*endif*/
|
||||
if (ptr >= pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
count = buf[ptr++];
|
||||
//printf("Count is %d\n", count);
|
||||
/* 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)
|
||||
return ret;
|
||||
/*endif*/
|
||||
if (s->t38_version == 0)
|
||||
{
|
||||
/* 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++;
|
||||
else
|
||||
other_half = true;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
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)
|
||||
return ret;
|
||||
/*endif*/
|
||||
t30_field_type = T38_FIELD_CM_MESSAGE + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
ptr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
/* Decode field_data */
|
||||
if (field_data_present)
|
||||
{
|
||||
if ((ptr + 2) > pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
numocts = ((buf[ptr] << 8) | buf[ptr + 1]) + 1;
|
||||
ptr += numocts + 2;
|
||||
}
|
||||
/*endif*/
|
||||
if (ptr > pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
/* Check if we finished mid byte in a version 0 packet. */
|
||||
if (other_half)
|
||||
ptr++;
|
||||
/*endif*/
|
||||
if (ptr > pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
|
||||
/* 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. */
|
||||
@ -561,7 +608,9 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8
|
||||
ptr++;
|
||||
else
|
||||
other_half = true;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
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;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
/* Decode field_data */
|
||||
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;
|
||||
msg = NULL;
|
||||
}
|
||||
/*endif*/
|
||||
span_log(&s->logging,
|
||||
SPAN_LOG_FLOW,
|
||||
"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_field_type = t30_field_type;
|
||||
}
|
||||
/*endfor*/
|
||||
/* Check if we finished mid byte in a version 0 packet. */
|
||||
if (other_half)
|
||||
ptr++;
|
||||
/*endif*/
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
if (ptr > pkt_len)
|
||||
return ret;
|
||||
/*endif*/
|
||||
return ptr;
|
||||
}
|
||||
/*- 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);
|
||||
return 0;
|
||||
}
|
||||
/*endif*/
|
||||
/* Distinguish between a little bit out of sequence, and a huge hop. */
|
||||
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++;
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
}
|
||||
/*endif*/
|
||||
s->rx_expected_seq_no = seq_no;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
if (len < 1)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Bad packet length - %d\n", log_seq_no, len);
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
/* 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
|
||||
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)
|
||||
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;
|
||||
}
|
||||
/*endif*/
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -704,6 +768,7 @@ static int t38_encode_indicator(t38_core_state_t *s, uint8_t buf[], int indicato
|
||||
len = 0;
|
||||
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
||||
len = 4;
|
||||
/*endif*/
|
||||
|
||||
/* Data field not present */
|
||||
/* Indicator packet */
|
||||
@ -721,9 +786,10 @@ static int t38_encode_indicator(t38_core_state_t *s, uint8_t buf[], int indicato
|
||||
{
|
||||
len = -1;
|
||||
}
|
||||
/*endif*/
|
||||
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
||||
{
|
||||
/* Fill in the TPKT header (se RFC1006) */
|
||||
/* Fill in the TPKT header (see RFC1006) */
|
||||
/* Version */
|
||||
buf[0] = 3;
|
||||
/* 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[3] = len & 0xFF;
|
||||
}
|
||||
/*endif*/
|
||||
return len;
|
||||
}
|
||||
/*- 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;
|
||||
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
|
||||
len = 4;
|
||||
/*endif*/
|
||||
|
||||
/* There seems no valid reason why a packet would ever be generated without a data field present */
|
||||
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;
|
||||
}
|
||||
/*endif*/
|
||||
|
||||
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);
|
||||
enclen = 0x4000*multiplier;
|
||||
}
|
||||
/*endif*/
|
||||
|
||||
fragment_len = enclen;
|
||||
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 */
|
||||
if (q->field_type > T38_FIELD_T4_NON_ECM_SIG_END)
|
||||
return -1;
|
||||
/*endif*/
|
||||
buf[len++] = (uint8_t) ((field_data_present << 7) | (q->field_type << 4));
|
||||
}
|
||||
else
|
||||
@ -834,22 +905,28 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
/* Encode field_data */
|
||||
if (field_data_present)
|
||||
{
|
||||
if (q->field_len < 1 || q->field_len > 65535)
|
||||
return -1;
|
||||
/*endif*/
|
||||
buf[len++] = (uint8_t) (((q->field_len - 1) >> 8) & 0xFF);
|
||||
buf[len++] = (uint8_t) ((q->field_len - 1) & 0xFF);
|
||||
memcpy(&buf[len], q->field, q->field_len);
|
||||
len += q->field_len;
|
||||
}
|
||||
/*endif*/
|
||||
data_field_no++;
|
||||
}
|
||||
/*endfor*/
|
||||
}
|
||||
while ((int) encoded_len != fields || fragment_len >= 16384);
|
||||
}
|
||||
/*endif*/
|
||||
|
||||
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),
|
||||
field[data_field_no].field_len);
|
||||
}
|
||||
/*endfor*/
|
||||
|
||||
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[3] = len & 0xFF;
|
||||
}
|
||||
/*endif*/
|
||||
|
||||
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
|
||||
{
|
||||
sprintf(tag, "Tx %5d: IFP", s->tx_seq_no);
|
||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
|
||||
}
|
||||
/*endif*/
|
||||
return len;
|
||||
}
|
||||
/*- 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);
|
||||
return len;
|
||||
}
|
||||
/*endif*/
|
||||
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)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx packet handler failure\n");
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
||||
if (s->pace_transmission)
|
||||
{
|
||||
delay = modem_startup_time[indicator].training;
|
||||
if (s->allow_for_tep)
|
||||
delay += modem_startup_time[indicator].tep;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
s->current_tx_indicator = indicator;
|
||||
}
|
||||
/*endif*/
|
||||
return delay;
|
||||
}
|
||||
/*- 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)
|
||||
return modem_startup_time[indicator].flags;
|
||||
/*endif*/
|
||||
return 0;
|
||||
}
|
||||
/*- 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)
|
||||
return modem_startup_time[indicator].training;
|
||||
/*endif*/
|
||||
return 0;
|
||||
}
|
||||
/*- 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);
|
||||
return len;
|
||||
}
|
||||
/*endif*/
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
||||
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);
|
||||
return len;
|
||||
}
|
||||
/*endif*/
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
/*endif*/
|
||||
s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
|
||||
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)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
memset(s, 0, sizeof(*s));
|
||||
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
||||
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);
|
||||
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*/
|
||||
@ -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);
|
||||
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*/
|
||||
@ -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);
|
||||
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*/
|
||||
}
|
||||
else
|
||||
@ -1937,13 +1937,13 @@ static void t38_hdlc_rx_put_bit(hdlc_rx_state_t *t, int new_bit)
|
||||
if (t->len == 1)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
/* 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
|
||||
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
|
||||
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");
|
||||
|
@ -330,6 +330,7 @@ static void process_hdlc_data(t38_terminal_front_end_state_t *fe, const uint8_t
|
||||
{
|
||||
fe->rx_data_missing = true;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -95,14 +95,14 @@ int has_MMX(void)
|
||||
/*endif*/
|
||||
__asm__ __volatile__(
|
||||
" push %%ebx;\n"
|
||||
" mov $1,%%eax;\n"
|
||||
" mov $1,%%eax;\n"
|
||||
" cpuid;\n"
|
||||
" xor %%eax,%%eax;\n"
|
||||
" test $0x800000,%%edx;\n"
|
||||
" jz 1f;\n" /* no MMX support */
|
||||
" inc %%eax;\n" /* MMX support */
|
||||
" test $0x800000,%%edx;\n"
|
||||
" jz 1f;\n" /* no MMX support */
|
||||
" inc %%eax;\n" /* MMX support */
|
||||
"1:\n"
|
||||
" pop %%ebx;\n"
|
||||
" pop %%ebx;\n"
|
||||
: "=a" (result)
|
||||
:
|
||||
: "ecx", "edx");
|
||||
@ -119,14 +119,14 @@ int has_SIMD(void)
|
||||
/*endif*/
|
||||
__asm__ __volatile__(
|
||||
" push %%ebx;\n"
|
||||
" mov $1,%%eax;\n"
|
||||
" mov $1,%%eax;\n"
|
||||
" cpuid;\n"
|
||||
" xor %%eax,%%eax;\n"
|
||||
" test $0x02000000,%%edx;\n"
|
||||
" jz 1f;\n" /* no SIMD support */
|
||||
" inc %%eax;\n" /* SIMD support */
|
||||
" test $0x02000000,%%edx;\n"
|
||||
" jz 1f;\n" /* no SIMD support */
|
||||
" inc %%eax;\n" /* SIMD support */
|
||||
"1:\n"
|
||||
" pop %%ebx;\n"
|
||||
" pop %%ebx;\n"
|
||||
: "=a" (result)
|
||||
:
|
||||
: "ecx", "edx");
|
||||
@ -143,14 +143,14 @@ int has_SIMD2(void)
|
||||
/*endif*/
|
||||
__asm__ __volatile__(
|
||||
" push %%ebx;\n"
|
||||
" mov $1,%%eax;\n"
|
||||
" mov $1,%%eax;\n"
|
||||
" cpuid;\n"
|
||||
" xor %%eax,%%eax;\n"
|
||||
" test $0x04000000,%%edx;\n"
|
||||
" jz 1f;\n" /* no SIMD2 support */
|
||||
" inc %%eax;\n" /* SIMD2 support */
|
||||
" test $0x04000000,%%edx;\n"
|
||||
" jz 1f;\n" /* no SIMD2 support */
|
||||
" inc %%eax;\n" /* SIMD2 support */
|
||||
"1:\n"
|
||||
" pop %%ebx;\n"
|
||||
" pop %%ebx;\n"
|
||||
: "=a" (result)
|
||||
:
|
||||
: "ecx", "edx");
|
||||
@ -167,19 +167,19 @@ int has_3DNow(void)
|
||||
/*endif*/
|
||||
__asm__ __volatile__(
|
||||
" push %%ebx;\n"
|
||||
" mov $0x80000000,%%eax;\n"
|
||||
" mov $0x80000000,%%eax;\n"
|
||||
" cpuid;\n"
|
||||
" xor %%ecx,%%ecx;\n"
|
||||
" cmp $0x80000000,%%eax;\n"
|
||||
" jbe 1f;\n" /* no extended MSR(1), so no 3DNow! */
|
||||
" mov $0x80000001,%%eax;\n"
|
||||
" cmp $0x80000000,%%eax;\n"
|
||||
" jbe 1f;\n" /* no extended MSR(1), so no 3DNow! */
|
||||
" mov $0x80000001,%%eax;\n"
|
||||
" cpuid;\n"
|
||||
" xor %%ecx,%%ecx;\n"
|
||||
" test $0x80000000,%%edx;\n"
|
||||
" jz 1f;\n" /* no 3DNow! support */
|
||||
" inc %%ecx;\n" /* 3DNow! support */
|
||||
" test $0x80000000,%%edx;\n"
|
||||
" jz 1f;\n" /* no 3DNow! support */
|
||||
" inc %%ecx;\n" /* 3DNow! support */
|
||||
"1:\n"
|
||||
" pop %%ebx;\n"
|
||||
" pop %%ebx;\n"
|
||||
: "=c" (result)
|
||||
:
|
||||
: "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)
|
||||
{
|
||||
/* 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));
|
||||
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 */
|
||||
memcpy(&out[out_len], s->buf, sizeof(int16_t)*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;
|
||||
|
||||
ret = queue_free(s->tx_queue);
|
||||
ret = v8_release(s);
|
||||
span_free(s);
|
||||
return ret;
|
||||
}
|
||||
|
@ -61,6 +61,17 @@ typedef void (*faxtester_front_end_step_complete_handler_t)(faxtester_state_t *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. */
|
||||
xmlNodePtr cur;
|
||||
|
||||
@ -113,6 +124,19 @@ struct faxtester_state_s
|
||||
int64_t timer;
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
xmlParserCtxtPtr ctxt;
|
||||
xmlDocPtr doc;
|
||||
xmlNsPtr ns;
|
||||
xmlNodePtr cur;
|
||||
|
||||
@ -1435,7 +1434,7 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
||||
exit(2);
|
||||
}
|
||||
/* 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");
|
||||
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)
|
||||
{
|
||||
fprintf(stderr, "Failed to validate the XML document\n");
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeDoc(s->doc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
printf("Test failed\n");
|
||||
exit(2);
|
||||
@ -1452,9 +1451,9 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
|
||||
/* 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");
|
||||
printf("Test failed\n");
|
||||
exit(2);
|
||||
@ -1462,7 +1461,7 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
||||
/*endif*/
|
||||
if (xmlStrcmp(cur->name, (const xmlChar *) "fax-tests"))
|
||||
{
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeDoc(s->doc);
|
||||
fprintf(stderr, "Document of the wrong type, root node != fax-tests");
|
||||
printf("Test failed\n");
|
||||
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)
|
||||
{
|
||||
parse_config(s, doc, ns, cur->xmlChildrenNode);
|
||||
parse_config(s, s->doc, ns, cur->xmlChildrenNode);
|
||||
}
|
||||
/*endif*/
|
||||
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. */
|
||||
exchange(s);
|
||||
@ -1499,7 +1498,7 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
||||
cur = cur->next;
|
||||
}
|
||||
/*endwhile*/
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeDoc(s->doc);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user