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++)
{
case SIG_STATUS_LINK_IDLE:
return "Link idle";
}
+ /*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
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;
}
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;
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 --------------------------------------------------------*/
hdlc_tx_restart(&s->hdlc_tx);
else
hdlc_tx_frame(&s->hdlc_tx, msg, len);
+ /*endif*/
}
/*- End of function --------------------------------------------------------*/
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);
{
if ((s = (fax_modems_state_t *) span_alloc(sizeof(*s))) == NULL)
return NULL;
+ /*endif*/
}
/*endif*/
memset(s, 0, sizeof(*s));
int32_t sum;
sum = (int32_t) a + (int32_t) b;
- return saturate16(sum);
+ return saturate16(sum);
#endif
}
/*- End of function --------------------------------------------------------*/
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 --------------------------------------------------------*/
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 --------------------------------------------------------*/
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 --------------------------------------------------------*/
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
{
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*/
#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
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;
static __inline__ void fir16_free(fir16_state_t *fir)
{
- free(fir->history);
+ span_free(fir->history);
}
/*- End of function --------------------------------------------------------*/
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;
static __inline__ void fir32_free(fir32_state_t *fir)
{
- free(fir->history);
+ span_free(fir->history);
}
/*- End of function --------------------------------------------------------*/
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;
static __inline__ void fir_float_free(fir_float_state_t *fir)
{
- free(fir->history);
+ span_free(fir->history);
}
/*- End of function --------------------------------------------------------*/
{
#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.
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;
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];
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;
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;
{
/*! 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;
\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.
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);
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,
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;
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])
{
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;
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
{
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
#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"
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;
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*/
{"\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},
{"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},
case T38_IND_V33_14400_TRAINING:
return "v33-14400-training";
}
+ /*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
case T38_DATA_V33_14400:
return "v33-14400";
}
+ /*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
case T38_FIELD_V34RATE:
return "v34rate";
}
+ /*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
case '6':
return "V.34 HDX-only FAX receiving terminal";
}
+ /*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
{
if (len < 2)
return "???";
+ /*endif*/
switch (data[0])
{
case 'A':
case '0':
return "ACK";
}
+ /*endswitch*/
break;
case 'N':
switch (data[1])
/* Response for profiles 5 and 6 */
return "NACK: V.34 only FAX.";
}
+ /*endswitch*/
break;
}
+ /*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
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 --------------------------------------------------------*/
/* In the near future */
return 1;
}
+ /*endif*/
if (expected < actual + ACCEPTABLE_SEQ_NO_OFFSET)
{
/* In the recent past */
return -1;
}
+ /*endif*/
}
else
{
/* 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;
}
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)
/* 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:
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)
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;
/* 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
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
/* 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
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. */
{
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. */
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
{
{
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. */
ptr++;
else
other_half = true;
+ /*endif*/
}
+ /*endif*/
}
else
{
{
t30_field_type = (buf[ptr++] >> 3) & 0x7;
}
+ /*endif*/
}
+ /*endif*/
/* Decode field_data */
if (field_data_present)
{
numocts = 0;
msg = NULL;
}
+ /*endif*/
span_log(&s->logging,
SPAN_LOG_FLOW,
"Rx %5d: (%d) data %s/%s + %d byte(s)\n",
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 --------------------------------------------------------*/
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))
{
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
{
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 --------------------------------------------------------*/
len = 0;
if (s->data_transport_protocol == T38_TRANSPORT_TCP_TPKT)
len = 4;
+ /*endif*/
/* Data field not present */
/* Indicator packet */
{
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 */
buf[2] = (len >> 8) & 0xFF;
buf[3] = len & 0xFF;
}
+ /*endif*/
return len;
}
/*- End of function --------------------------------------------------------*/
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;
{
return -1;
}
+ /*endif*/
if (data_field_present)
{
buf[len++] = (uint8_t) (0xC0 | multiplier);
enclen = 0x4000*multiplier;
}
+ /*endif*/
fragment_len = enclen;
encoded_len += fragment_len;
/* 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
{
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++)
{
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)
{
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 --------------------------------------------------------*/
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 --------------------------------------------------------*/
{
if (s->pace_transmission)
return modem_startup_time[indicator].flags;
+ /*endif*/
return 0;
}
/*- End of function --------------------------------------------------------*/
{
if (s->pace_transmission)
return modem_startup_time[indicator].training;
+ /*endif*/
return 0;
}
/*- End of function --------------------------------------------------------*/
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;
}
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;
}
{
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");
{
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*/
{
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*/
{
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
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");
{
fe->rx_data_missing = true;
}
+ /*endif*/
}
/*- End of function --------------------------------------------------------*/
/*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");
/*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");
/*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");
/*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");
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)
{
/* 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);
}
}
}
{
int ret;
- ret = queue_free(s->tx_queue);
+ ret = v8_release(s);
span_free(s);
return ret;
}
*/
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;
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;
};
static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test)
{
xmlParserCtxtPtr ctxt;
- xmlDocPtr doc;
xmlNsPtr ns;
xmlNodePtr cur;
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");
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);
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);
/*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);
{
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);
cur = cur->next;
}
/*endwhile*/
- xmlFreeDoc(doc);
+ xmlFreeDoc(s->doc);
return 0;
}
/*- End of function --------------------------------------------------------*/