mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-13 15:50:59 +00:00
Fixed a problem in FAX where a received handshake, delayed so much it is
received as we queue a retry, causes the retry frame to remain queued in the HDLC entity.
This commit is contained in:
parent
37a194d956
commit
3549488e8e
@ -184,5 +184,46 @@
|
||||
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</test>
|
||||
<test name="Phase-D-collision">
|
||||
<!-- DUT calls tester and sends 1 IMPRESS and 1 WHITE page. The MCF after the first
|
||||
page is delayed enough to cause a collision with a retry of the MPS from the DUT. -->
|
||||
<step type="ANSWER" value="etsi_300_242_a4_impress_white.tif"/>
|
||||
<step dir="T" type="SET" tag="IDENT" value="+0123456789"/>
|
||||
|
||||
<step dir="R" type="CNG"/>
|
||||
|
||||
<step dir="T" type="CED"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="TSI+" value="FF C0 C2 9C 1C EC 6C AC 2C CC 4C 8C 0C D4 04 04 04 04 04 04 04 04 04 ..."/>
|
||||
<step dir="R" type="HDLC" tag="DCS+" value="FF C8 C1 ..."/>
|
||||
<step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="CFR" value="FF C8 21"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="MSG" modem="V.27ter/4800" timeout="180000"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MPS+" value="FF C8 F2"/>
|
||||
|
||||
<step type="WAIT" value="3500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
|
||||
</test>
|
||||
</test-group>
|
||||
</fax-tests>
|
||||
|
@ -1029,13 +1029,13 @@ SPAN_DECLARE(int) adsi_add_field(adsi_tx_state_t *s, uint8_t *msg, int len, uint
|
||||
msg[len++] = (uint8_t) field_len;
|
||||
if (field_len == DLE)
|
||||
msg[len++] = (uint8_t) field_len;
|
||||
memcpy(msg + len, field_body, field_len);
|
||||
memcpy(&msg[len], field_body, field_len);
|
||||
len += field_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No field type or length, for restricted single message formats */
|
||||
memcpy(msg + len, field_body, field_len);
|
||||
memcpy(&msg[len], field_body, field_len);
|
||||
len += field_len;
|
||||
}
|
||||
}
|
||||
@ -1080,7 +1080,7 @@ SPAN_DECLARE(int) adsi_add_field(adsi_tx_state_t *s, uint8_t *msg, int len, uint
|
||||
x = msg[--len];
|
||||
if (field_type != CLIP_DTMF_HASH_UNSPECIFIED)
|
||||
msg[len++] = field_type;
|
||||
memcpy(msg + len, field_body, field_len);
|
||||
memcpy(&msg[len], field_body, field_len);
|
||||
msg[len + field_len] = (uint8_t) x;
|
||||
len += (field_len + 1);
|
||||
}
|
||||
|
@ -5411,7 +5411,7 @@ static int command_search(const char *u, int *matched)
|
||||
|
||||
entry = 0;
|
||||
/* Loop over the length of the string to search the trie... */
|
||||
for (i = 0, ptr = 0; ptr < COMMAND_TRIE_LEN; i++)
|
||||
for (i = 0, ptr = 0; ptr < COMMAND_TRIE_LEN - 2; i++)
|
||||
{
|
||||
/* The character in u we are processing... */
|
||||
/* V.250 5.4.1 says upper and lower case are equivalent in commands */
|
||||
|
@ -172,7 +172,10 @@ SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_
|
||||
|
||||
s = (fax_modems_state_t *) user_data;
|
||||
|
||||
hdlc_tx_frame(&s->hdlc_tx, msg, len);
|
||||
if (len == -1)
|
||||
hdlc_tx_restart(&s->hdlc_tx);
|
||||
else
|
||||
hdlc_tx_frame(&s->hdlc_tx, msg, len);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -311,6 +311,20 @@ SPAN_DECLARE(void) hdlc_rx_set_octet_counting_report_interval(hdlc_rx_state_t *s
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) hdlc_rx_restart(hdlc_rx_state_t *s)
|
||||
{
|
||||
s->framing_ok_announced = false;
|
||||
s->flags_seen = 0;
|
||||
s->raw_bit_stream = 0;
|
||||
s->byte_in_progress = 0;
|
||||
s->num_bits = 0;
|
||||
s->octet_counting_mode = false;
|
||||
s->octet_count = 0;
|
||||
s->len = 0;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(hdlc_rx_state_t *) hdlc_rx_init(hdlc_rx_state_t *s,
|
||||
bool crc32,
|
||||
bool report_bad_frames,
|
||||
@ -375,7 +389,7 @@ SPAN_DECLARE(int) hdlc_rx_get_stats(hdlc_rx_state_t *s,
|
||||
|
||||
SPAN_DECLARE(int) hdlc_tx_frame(hdlc_tx_state_t *s, const uint8_t *frame, size_t len)
|
||||
{
|
||||
if (len <= 0)
|
||||
if (len == 0)
|
||||
{
|
||||
s->tx_end = true;
|
||||
return 0;
|
||||
@ -394,7 +408,7 @@ SPAN_DECLARE(int) hdlc_tx_frame(hdlc_tx_state_t *s, const uint8_t *frame, size_t
|
||||
if (s->len)
|
||||
return -1;
|
||||
}
|
||||
memcpy(s->buffer + s->len, frame, len);
|
||||
memcpy(&s->buffer[s->len], frame, len);
|
||||
if (s->crc_bytes == 2)
|
||||
s->crc = crc_itu16_calc(frame, len, (uint16_t) s->crc);
|
||||
else
|
||||
@ -589,6 +603,24 @@ SPAN_DECLARE(void) hdlc_tx_set_max_frame_len(hdlc_tx_state_t *s, size_t max_len)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) hdlc_tx_restart(hdlc_tx_state_t *s)
|
||||
{
|
||||
s->octets_in_progress = 0;
|
||||
s->num_bits = 0;
|
||||
s->idle_octet = 0x7E;
|
||||
s->flag_octets = 0;
|
||||
s->abort_octets = 0;
|
||||
s->report_flag_underflow = false;
|
||||
s->len = 0;
|
||||
s->pos = 0;
|
||||
s->crc = 0;
|
||||
s->byte = 0;
|
||||
s->bits = 0;
|
||||
s->tx_end = false;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
||||
bool crc32,
|
||||
int inter_frame_flags,
|
||||
@ -602,7 +634,6 @@ SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->idle_octet = 0x7E;
|
||||
s->underflow_handler = handler;
|
||||
s->user_data = user_data;
|
||||
s->inter_frame_flags = (inter_frame_flags < 1) ? 1 : inter_frame_flags;
|
||||
@ -616,6 +647,7 @@ SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
||||
s->crc_bytes = 2;
|
||||
s->crc = 0xFFFF;
|
||||
}
|
||||
s->idle_octet = 0x7E;
|
||||
s->progressive = progressive;
|
||||
s->max_frame_len = HDLC_MAXFRAME_LEN;
|
||||
return s;
|
||||
|
@ -58,21 +58,21 @@ static void save_history(plc_state_t *s, int16_t *buf, int len)
|
||||
if (len >= PLC_HISTORY_LEN)
|
||||
{
|
||||
/* Just keep the last part of the new data, starting at the beginning of the buffer */
|
||||
memcpy(s->history, buf + len - PLC_HISTORY_LEN, sizeof(int16_t)*PLC_HISTORY_LEN);
|
||||
memcpy(s->history, &buf[len - PLC_HISTORY_LEN], sizeof(int16_t)*PLC_HISTORY_LEN);
|
||||
s->buf_ptr = 0;
|
||||
return;
|
||||
}
|
||||
if (s->buf_ptr + len > PLC_HISTORY_LEN)
|
||||
{
|
||||
/* Wraps around - must break into two sections */
|
||||
memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr));
|
||||
memcpy(&s->history[s->buf_ptr], buf, sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr));
|
||||
len -= (PLC_HISTORY_LEN - s->buf_ptr);
|
||||
memcpy(s->history, buf + (PLC_HISTORY_LEN - s->buf_ptr), sizeof(int16_t)*len);
|
||||
memcpy(s->history, &buf[PLC_HISTORY_LEN - s->buf_ptr], sizeof(int16_t)*len);
|
||||
s->buf_ptr = len;
|
||||
return;
|
||||
}
|
||||
/* Can use just one section */
|
||||
memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t)*len);
|
||||
memcpy(&s->history[s->buf_ptr], buf, sizeof(int16_t)*len);
|
||||
s->buf_ptr += len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -84,8 +84,8 @@ static __inline__ void normalise_history(plc_state_t *s)
|
||||
if (s->buf_ptr == 0)
|
||||
return;
|
||||
memcpy(tmp, s->history, sizeof(int16_t)*s->buf_ptr);
|
||||
memmove(s->history, s->history + s->buf_ptr, sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr));
|
||||
memcpy(s->history + PLC_HISTORY_LEN - s->buf_ptr, tmp, sizeof(int16_t)*s->buf_ptr);
|
||||
memmove(s->history, &s->history[s->buf_ptr], sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr));
|
||||
memcpy(&s->history[PLC_HISTORY_LEN - s->buf_ptr], tmp, sizeof(int16_t)*s->buf_ptr);
|
||||
s->buf_ptr = 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -119,8 +119,8 @@ SPAN_DECLARE(int) queue_view(queue_state_t *s, uint8_t *buf, int len)
|
||||
/* A two step process */
|
||||
if (buf)
|
||||
{
|
||||
memcpy(buf, s->data + optr, to_end);
|
||||
memcpy(buf + to_end, s->data, real_len - to_end);
|
||||
memcpy(buf, &s->data[optr], to_end);
|
||||
memcpy(&buf[to_end], s->data, real_len - to_end);
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
@ -128,7 +128,7 @@ SPAN_DECLARE(int) queue_view(queue_state_t *s, uint8_t *buf, int len)
|
||||
{
|
||||
/* A one step process */
|
||||
if (buf)
|
||||
memcpy(buf, s->data + optr, real_len);
|
||||
memcpy(buf, &s->data[optr], real_len);
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
@ -170,8 +170,8 @@ SPAN_DECLARE(int) queue_read(queue_state_t *s, uint8_t *buf, int len)
|
||||
/* A two step process */
|
||||
if (buf)
|
||||
{
|
||||
memcpy(buf, s->data + optr, to_end);
|
||||
memcpy(buf + to_end, s->data, real_len - to_end);
|
||||
memcpy(buf, &s->data[optr], to_end);
|
||||
memcpy(&buf[to_end], s->data, real_len - to_end);
|
||||
}
|
||||
/*endif*/
|
||||
new_optr = real_len - to_end;
|
||||
@ -180,7 +180,7 @@ SPAN_DECLARE(int) queue_read(queue_state_t *s, uint8_t *buf, int len)
|
||||
{
|
||||
/* A one step process */
|
||||
if (buf)
|
||||
memcpy(buf, s->data + optr, real_len);
|
||||
memcpy(buf, &s->data[optr], real_len);
|
||||
/*endif*/
|
||||
new_optr = optr + real_len;
|
||||
if (new_optr >= s->len)
|
||||
@ -253,7 +253,7 @@ SPAN_DECLARE(int) queue_write(queue_state_t *s, const uint8_t *buf, int len)
|
||||
if (iptr < optr || to_end >= real_len)
|
||||
{
|
||||
/* A one step process */
|
||||
memcpy(s->data + iptr, buf, real_len);
|
||||
memcpy(&s->data[iptr], buf, real_len);
|
||||
new_iptr = iptr + real_len;
|
||||
if (new_iptr >= s->len)
|
||||
new_iptr = 0;
|
||||
@ -262,8 +262,8 @@ SPAN_DECLARE(int) queue_write(queue_state_t *s, const uint8_t *buf, int len)
|
||||
else
|
||||
{
|
||||
/* A two step process */
|
||||
memcpy(s->data + iptr, buf, to_end);
|
||||
memcpy(s->data, buf + to_end, real_len - to_end);
|
||||
memcpy(&s->data[iptr], buf, to_end);
|
||||
memcpy(s->data, &buf[to_end], real_len - to_end);
|
||||
new_iptr = real_len - to_end;
|
||||
}
|
||||
/*endif*/
|
||||
@ -367,8 +367,8 @@ SPAN_DECLARE(int) queue_write_msg(queue_state_t *s, const uint8_t *buf, int len)
|
||||
if (iptr < optr || to_end >= real_len)
|
||||
{
|
||||
/* A one step process */
|
||||
memcpy(s->data + iptr, &lenx, sizeof(uint16_t));
|
||||
memcpy(s->data + iptr + sizeof(uint16_t), buf, len);
|
||||
memcpy(&s->data[iptr], &lenx, sizeof(uint16_t));
|
||||
memcpy(&s->data[iptr + sizeof(uint16_t)], buf, len);
|
||||
new_iptr = iptr + real_len;
|
||||
if (new_iptr >= s->len)
|
||||
new_iptr = 0;
|
||||
@ -380,16 +380,16 @@ SPAN_DECLARE(int) queue_write_msg(queue_state_t *s, const uint8_t *buf, int len)
|
||||
if (to_end >= sizeof(uint16_t))
|
||||
{
|
||||
/* The actual message wraps around the end of the buffer */
|
||||
memcpy(s->data + iptr, &lenx, sizeof(uint16_t));
|
||||
memcpy(s->data + iptr + sizeof(uint16_t), buf, to_end - sizeof(uint16_t));
|
||||
memcpy(s->data, buf + to_end - sizeof(uint16_t), real_len - to_end);
|
||||
memcpy(&s->data[iptr], &lenx, sizeof(uint16_t));
|
||||
memcpy(&s->data[iptr + sizeof(uint16_t)], buf, to_end - sizeof(uint16_t));
|
||||
memcpy(s->data, &buf[to_end - sizeof(uint16_t)], real_len - to_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The message length wraps around the end of the buffer */
|
||||
memcpy(s->data + iptr, (uint8_t *) &lenx, to_end);
|
||||
memcpy(&s->data[iptr], (uint8_t *) &lenx, to_end);
|
||||
memcpy(s->data, ((uint8_t *) &lenx) + to_end, sizeof(uint16_t) - to_end);
|
||||
memcpy(s->data + sizeof(uint16_t) - to_end, buf, len);
|
||||
memcpy(&s->data[sizeof(uint16_t) - to_end], buf, len);
|
||||
}
|
||||
new_iptr = real_len - to_end;
|
||||
}
|
||||
|
@ -99,6 +99,13 @@ SPAN_DECLARE(hdlc_rx_state_t *) hdlc_rx_init(hdlc_rx_state_t *s,
|
||||
hdlc_frame_handler_t handler,
|
||||
void *user_data);
|
||||
|
||||
/*! Re-initialise an HDLC receiver context. This does not reset the usage statistics.
|
||||
\brief Re-initialise an HDLC receiver context.
|
||||
\param s A pointer to an HDLC receiver context.
|
||||
\return 0 for success.
|
||||
*/
|
||||
SPAN_DECLARE(int) hdlc_rx_restart(hdlc_rx_state_t *s);
|
||||
|
||||
/*! Change the put_bit function associated with an HDLC receiver context.
|
||||
\brief Change the put_bit function associated with an HDLC receiver context.
|
||||
\param s A pointer to an HDLC receiver context.
|
||||
@ -167,7 +174,8 @@ SPAN_DECLARE_NONSTD(void) hdlc_rx_put_byte(hdlc_rx_state_t *s, int new_byte);
|
||||
*/
|
||||
SPAN_DECLARE_NONSTD(void) hdlc_rx_put(hdlc_rx_state_t *s, const uint8_t buf[], int len);
|
||||
|
||||
/*! \brief Initialise an HDLC transmitter context.
|
||||
/*! Initialise an HDLC transmitter context.
|
||||
\brief Initialise an HDLC transmitter context.
|
||||
\param s A pointer to an HDLC transmitter context.
|
||||
\param crc32 True to use ITU CRC32. False to use ITU CRC16.
|
||||
\param inter_frame_flags The minimum flag octets to insert between frames (usually one).
|
||||
@ -183,8 +191,23 @@ SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
||||
hdlc_underflow_handler_t handler,
|
||||
void *user_data);
|
||||
|
||||
/*! Re-initialise an HDLC transmitter context.
|
||||
\brief Re-initialise an HDLC transmitter context.
|
||||
\param s A pointer to an HDLC transmitter context.
|
||||
\return 0 for success.
|
||||
*/
|
||||
SPAN_DECLARE(int) hdlc_tx_restart(hdlc_tx_state_t *s);
|
||||
|
||||
/*! Release an HDLC transmitter context.
|
||||
\brief Release an HDLC transmitter context.
|
||||
\param s A pointer to an HDLC transmitter context.
|
||||
\return 0 for OK */
|
||||
SPAN_DECLARE(int) hdlc_tx_release(hdlc_tx_state_t *s);
|
||||
|
||||
/*! Free an HDLC transmitter context.
|
||||
\brief Free an HDLC transmitter context.
|
||||
\param s A pointer to an HDLC transmitter context.
|
||||
\return 0 for OK */
|
||||
SPAN_DECLARE(int) hdlc_tx_free(hdlc_tx_state_t *s);
|
||||
|
||||
/*! \brief Set the maximum frame length for an HDLC transmitter context.
|
||||
|
@ -5109,20 +5109,34 @@ static void queue_phase(t30_state_t *s, int phase)
|
||||
if (s->rx_signal_present)
|
||||
{
|
||||
/* We need to wait for that signal to go away */
|
||||
if (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
|
||||
phase */
|
||||
if (s->send_hdlc_handler)
|
||||
s->send_hdlc_handler(s->send_hdlc_user_data, NULL, -1);
|
||||
}
|
||||
s->next_phase = phase;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't need to queue the new phase. We can change to it immediately. */
|
||||
set_phase(s, phase);
|
||||
s->next_phase = T30_PHASE_IDLE;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void set_phase(t30_state_t *s, int phase)
|
||||
{
|
||||
//if (phase = s->phase)
|
||||
// return;
|
||||
if (phase != s->next_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
|
||||
phase */
|
||||
if (s->send_hdlc_handler)
|
||||
s->send_hdlc_handler(s->send_hdlc_user_data, NULL, -1);
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Changing from phase %s to %s\n", phase_names[s->phase], phase_names[phase]);
|
||||
/* We may be killing a receiver before it has declared the end of the
|
||||
signal. Force the signal present indicator to off, because the
|
||||
@ -5132,6 +5146,7 @@ static void set_phase(t30_state_t *s, int phase)
|
||||
s->rx_trained = false;
|
||||
s->rx_frame_received = false;
|
||||
s->phase = phase;
|
||||
s->next_phase = T30_PHASE_IDLE;
|
||||
switch (phase)
|
||||
{
|
||||
case T30_PHASE_A_CED:
|
||||
@ -5470,6 +5485,14 @@ static void timer_t1_expired(t30_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void timer_t1a_expired(t30_state_t *s)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
|
||||
t30_set_status(s, T30_ERR_HDLC_CARRIER);
|
||||
disconnect(s);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void timer_t2_expired(t30_state_t *s)
|
||||
{
|
||||
if (s->timer_t2_t4_is != TIMER_IS_T2B)
|
||||
@ -5541,14 +5564,6 @@ static void timer_t2_expired(t30_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void timer_t1a_expired(t30_state_t *s)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
|
||||
t30_set_status(s, T30_ERR_HDLC_CARRIER);
|
||||
disconnect(s);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void timer_t2a_expired(t30_state_t *s)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
|
||||
@ -5680,7 +5695,7 @@ static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt
|
||||
|
||||
if ((t = span_alloc(len - 1)) == NULL)
|
||||
return 0;
|
||||
memcpy(t, pkt + 1, len - 1);
|
||||
memcpy(t, &pkt[1], len - 1);
|
||||
*msg = t;
|
||||
return len - 1;
|
||||
}
|
||||
@ -5777,10 +5792,7 @@ static void t30_non_ecm_rx_status(void *user_data, int status)
|
||||
break;
|
||||
}
|
||||
if (s->next_phase != T30_PHASE_IDLE)
|
||||
{
|
||||
set_phase(s, s->next_phase);
|
||||
s->next_phase = T30_PHASE_IDLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "Unexpected non-ECM rx status - %d!\n", status);
|
||||
@ -6012,7 +6024,6 @@ static void t30_hdlc_rx_status(void *user_data, int status)
|
||||
{
|
||||
/* The appropriate timer for the next phase should already be in progress */
|
||||
set_phase(s, s->next_phase);
|
||||
s->next_phase = T30_PHASE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -282,7 +282,7 @@ SPAN_DECLARE(int) t30_set_tx_nsf(t30_state_t *s, const uint8_t *nsf, int len)
|
||||
span_free(s->tx_info.nsf);
|
||||
if (nsf && len > 0 && (s->tx_info.nsf = span_alloc(len + 3)))
|
||||
{
|
||||
memcpy(s->tx_info.nsf + 3, nsf, len);
|
||||
memcpy(&s->tx_info.nsf[3], nsf, len);
|
||||
s->tx_info.nsf_len = len;
|
||||
}
|
||||
else
|
||||
@ -316,7 +316,7 @@ SPAN_DECLARE(int) t30_set_tx_nsc(t30_state_t *s, const uint8_t *nsc, int len)
|
||||
span_free(s->tx_info.nsc);
|
||||
if (nsc && len > 0 && (s->tx_info.nsc = span_alloc(len + 3)))
|
||||
{
|
||||
memcpy(s->tx_info.nsc + 3, nsc, len);
|
||||
memcpy(&s->tx_info.nsc[3], nsc, len);
|
||||
s->tx_info.nsc_len = len;
|
||||
}
|
||||
else
|
||||
@ -350,7 +350,7 @@ SPAN_DECLARE(int) t30_set_tx_nss(t30_state_t *s, const uint8_t *nss, int len)
|
||||
span_free(s->tx_info.nss);
|
||||
if (nss && len > 0 && (s->tx_info.nss = span_alloc(len + 3)))
|
||||
{
|
||||
memcpy(s->tx_info.nss + 3, nss, len);
|
||||
memcpy(&s->tx_info.nss[3], nss, len);
|
||||
s->tx_info.nss_len = len;
|
||||
}
|
||||
else
|
||||
|
@ -1877,7 +1877,7 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int
|
||||
buf[0] = (ok) ? AT_RESPONSE_CODE_OK : AT_RESPONSE_CODE_ERROR;
|
||||
/* It is safe to look at the two bytes beyond the length of the message,
|
||||
and expect to find the FCS there. */
|
||||
memcpy(buf + 1, msg, len + 2);
|
||||
memcpy(&buf[1], msg, len + 2);
|
||||
queue_write_msg(s->rx_queue, buf, len + 3);
|
||||
}
|
||||
/*endif*/
|
||||
|
@ -842,7 +842,7 @@ static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, co
|
||||
return -1;
|
||||
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);
|
||||
memcpy(&buf[len], q->field, q->field_len);
|
||||
len += q->field_len;
|
||||
}
|
||||
data_field_no++;
|
||||
|
@ -616,20 +616,28 @@ static void send_hdlc(void *user_data, const uint8_t *msg, int len)
|
||||
t38_terminal_state_t *s;
|
||||
|
||||
s = (t38_terminal_state_t *) user_data;
|
||||
if (len <= 0)
|
||||
if (len == 0)
|
||||
{
|
||||
/* A length of zero means shut down the HDLC transmission */
|
||||
/* Setting len to -1 makes HDLC shut down */
|
||||
s->t38_fe.hdlc_tx.len = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->t38_fe.us_per_tx_chunk)
|
||||
s->t38_fe.hdlc_tx.extra_bits = extra_bits_in_stuffed_frame(msg, len);
|
||||
/*endif*/
|
||||
bit_reverse(s->t38_fe.hdlc_tx.buf, msg, len);
|
||||
s->t38_fe.hdlc_tx.len = len;
|
||||
s->t38_fe.hdlc_tx.ptr = 0;
|
||||
return;
|
||||
}
|
||||
/*endif*/
|
||||
if (len == -1)
|
||||
{
|
||||
/* A length of -1 means flush any buffered HDLC data */
|
||||
s->t38_fe.hdlc_tx.len = 0;
|
||||
s->t38_fe.hdlc_tx.ptr = 0;
|
||||
return;
|
||||
}
|
||||
/*endif*/
|
||||
if (s->t38_fe.us_per_tx_chunk)
|
||||
s->t38_fe.hdlc_tx.extra_bits = extra_bits_in_stuffed_frame(msg, len);
|
||||
/*endif*/
|
||||
bit_reverse(s->t38_fe.hdlc_tx.buf, msg, len);
|
||||
s->t38_fe.hdlc_tx.len = len;
|
||||
s->t38_fe.hdlc_tx.ptr = 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -190,12 +190,12 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
||||
if (s->fill + len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
memcpy(s->buf + s->fill, in, sizeof(int16_t)*len);
|
||||
memcpy(&s->buf[s->fill], in, sizeof(int16_t)*len);
|
||||
s->fill += len;
|
||||
return out_len;
|
||||
}
|
||||
k = s->buf_len - s->fill;
|
||||
memcpy(s->buf + s->fill, in, sizeof(int16_t)*k);
|
||||
memcpy(&s->buf[s->fill], in, sizeof(int16_t)*k);
|
||||
in_len += k;
|
||||
s->fill = s->buf_len;
|
||||
while (s->fill == s->buf_len)
|
||||
@ -207,12 +207,12 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
||||
if (len - in_len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
memcpy(s->buf, in + in_len, sizeof(int16_t)*(len - in_len));
|
||||
memcpy(s->buf, &in[in_len], sizeof(int16_t)*(len - in_len));
|
||||
s->fill = len - in_len;
|
||||
s->lcp -= s->buf_len;
|
||||
return out_len;
|
||||
}
|
||||
memcpy(s->buf, in + in_len, sizeof(int16_t)*s->buf_len);
|
||||
memcpy(s->buf, &in[in_len], sizeof(int16_t)*s->buf_len);
|
||||
in_len += s->buf_len;
|
||||
s->lcp -= s->buf_len;
|
||||
}
|
||||
@ -220,16 +220,16 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
||||
{
|
||||
memcpy(&out[out_len], s->buf, sizeof(int16_t)*s->lcp);
|
||||
out_len += s->lcp;
|
||||
memcpy(s->buf, s->buf + s->lcp, sizeof(int16_t)*(s->buf_len - s->lcp));
|
||||
memcpy(s->buf, &s->buf[s->lcp], sizeof(int16_t)*(s->buf_len - s->lcp));
|
||||
if (len - in_len < s->lcp)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
memcpy(s->buf + (s->buf_len - s->lcp), in + in_len, sizeof(int16_t)*(len - in_len));
|
||||
memcpy(&s->buf[s->buf_len - s->lcp], &in[in_len], sizeof(int16_t)*(len - in_len));
|
||||
s->fill = s->buf_len - s->lcp + len - in_len;
|
||||
s->lcp = 0;
|
||||
return out_len;
|
||||
}
|
||||
memcpy(s->buf + (s->buf_len - s->lcp), in + in_len, sizeof(int16_t)*s->lcp);
|
||||
memcpy(&s->buf[s->buf_len - s->lcp], &in[in_len], sizeof(int16_t)*s->lcp);
|
||||
in_len += s->lcp;
|
||||
s->lcp = 0;
|
||||
}
|
||||
@ -263,11 +263,11 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
||||
if (len - in_len < pitch)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
memcpy(s->buf + s->buf_len - pitch, in + in_len, sizeof(int16_t)*(len - in_len));
|
||||
memcpy(&s->buf[s->buf_len - pitch], &in[in_len], sizeof(int16_t)*(len - in_len));
|
||||
s->fill += (len - in_len - pitch);
|
||||
return out_len;
|
||||
}
|
||||
memcpy(s->buf + s->buf_len - pitch, in + in_len, sizeof(int16_t)*pitch);
|
||||
memcpy(&s->buf[s->buf_len - pitch], &in[in_len], sizeof(int16_t)*pitch);
|
||||
in_len += pitch;
|
||||
}
|
||||
else
|
||||
|
@ -238,7 +238,7 @@ static int tx_unnumbered_frame(lapm_state_t *s, uint8_t addr, uint8_t ctrl, uint
|
||||
f->len = 2;
|
||||
if (info && len)
|
||||
{
|
||||
memcpy(buf + f->len, info, len);
|
||||
memcpy(&buf[f->len], info, len);
|
||||
f->len += len;
|
||||
}
|
||||
return 0;
|
||||
|
@ -211,12 +211,24 @@ static int check_rx_dcs(const uint8_t *msg, int len)
|
||||
}
|
||||
|
||||
octets_per_ecm_frame = (dcs_frame[6] & DISBIT4) ? 256 : 64;
|
||||
|
||||
if ((dcs_frame[8] & DISBIT1))
|
||||
y_resolution = T4_Y_RESOLUTION_SUPERFINE;
|
||||
else if (dcs_frame[4] & DISBIT7)
|
||||
y_resolution = T4_Y_RESOLUTION_FINE;
|
||||
else
|
||||
y_resolution = T4_Y_RESOLUTION_STANDARD;
|
||||
|
||||
if ((dcs_frame[8] & DISBIT3))
|
||||
{
|
||||
x_resolution = T4_X_RESOLUTION_R16;
|
||||
y_resolution = T4_Y_RESOLUTION_SUPERFINE;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_resolution = T4_X_RESOLUTION_R8;
|
||||
}
|
||||
|
||||
image_width = widths[(dcs_frame[8] & DISBIT3) ? 2 : 1][dcs_frame[5] & (DISBIT2 | DISBIT1)];
|
||||
|
||||
/* Check which compression we will use. */
|
||||
@ -344,9 +356,9 @@ static void v21_put_bit(void *user_data, int bit)
|
||||
}
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "V.21 Rx bit %d - %d\n", rx_bits++, bit);
|
||||
if (fast_trained == FAX_NONE)
|
||||
hdlc_rx_put_bit(&hdlcrx, bit);
|
||||
//printf("V.21 Rx bit %d - %d\n", rx_bits++, bit);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@ -501,8 +513,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
memset(&t30_dummy, 0, sizeof(t30_dummy));
|
||||
span_log_init(&t30_dummy.logging, SPAN_LOG_FLOW, NULL);
|
||||
span_log_set_protocol(&t30_dummy.logging, "T.30");
|
||||
logging = t30_get_logging_state(&t30_dummy);
|
||||
span_log_init(logging, SPAN_LOG_NONE, NULL);
|
||||
span_log_set_protocol(logging, "T.30");
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
|
||||
|
||||
hdlc_rx_init(&hdlcrx, false, true, 5, hdlc_accept, NULL);
|
||||
fsk = fsk_rx_init(NULL, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, v21_put_bit, NULL);
|
||||
@ -520,24 +534,20 @@ int main(int argc, char *argv[])
|
||||
|
||||
#if 1
|
||||
logging = v17_rx_get_logging_state(v17);
|
||||
span_log_init(logging, SPAN_LOG_FLOW, NULL);
|
||||
span_log_set_protocol(logging, "V.17");
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
|
||||
|
||||
logging = v29_rx_get_logging_state(v29);
|
||||
span_log_init(logging, SPAN_LOG_FLOW, NULL);
|
||||
span_log_set_protocol(logging, "V.29");
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
|
||||
|
||||
logging = v27ter_rx_get_logging_state(v27ter_4800);
|
||||
span_log_init(logging, SPAN_LOG_FLOW, NULL);
|
||||
span_log_set_protocol(logging, "V.27ter-4800");
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
|
||||
|
||||
logging = v27ter_rx_get_logging_state(v27ter_2400);
|
||||
span_log_init(logging, SPAN_LOG_FLOW, NULL);
|
||||
span_log_set_protocol(logging, "V.27ter-2400");
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
|
||||
span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
|
||||
#endif
|
||||
|
||||
if (t4_rx_init(&t4_rx_state, "fax_decode.tif", T4_COMPRESSION_T4_2D) == NULL)
|
||||
@ -556,6 +566,17 @@ int main(int argc, char *argv[])
|
||||
v29_rx(v29, amp, len);
|
||||
v27ter_rx(v27ter_4800, amp, len);
|
||||
v27ter_rx(v27ter_2400, amp, len);
|
||||
|
||||
logging = t30_get_logging_state(&t30_dummy);
|
||||
span_log_bump_samples(logging, len);
|
||||
logging = v17_rx_get_logging_state(v17);
|
||||
span_log_bump_samples(logging, len);
|
||||
logging = v29_rx_get_logging_state(v29);
|
||||
span_log_bump_samples(logging, len);
|
||||
logging = v27ter_rx_get_logging_state(v27ter_4800);
|
||||
span_log_bump_samples(logging, len);
|
||||
logging = v27ter_rx_get_logging_state(v27ter_2400);
|
||||
span_log_bump_samples(logging, len);
|
||||
}
|
||||
t4_rx_release(&t4_rx_state);
|
||||
|
||||
|
@ -112,7 +112,7 @@ static void hdlc_underflow_handler(void *user_data)
|
||||
buf[1] = 0x03;
|
||||
buf[2] = 0x06;
|
||||
buf[3] = s->image_ptr/s->ecm_frame_size;
|
||||
memcpy(buf + 4, &s->image_buffer[s->image_ptr], s->ecm_frame_size);
|
||||
memcpy(&buf[4], &s->image_buffer[s->image_ptr], s->ecm_frame_size);
|
||||
hdlc_tx_frame(&s->modems.hdlc_tx, buf, 4 + s->ecm_frame_size);
|
||||
if (s->corrupt_crc >= 0 && s->corrupt_crc == s->image_ptr/s->ecm_frame_size)
|
||||
hdlc_tx_corrupt_frame(&s->modems.hdlc_tx);
|
||||
|
@ -168,7 +168,7 @@ static int power_surge_detector_file_test(const char *file)
|
||||
|
||||
if ((inhandle = sf_open_telephony_read(file, 1)) == NULL)
|
||||
{
|
||||
printf(" Cannot open audio file '%s'\n", file);
|
||||
fprintf(stderr, " Cannot open audio file '%s'\n", file);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ typedef struct
|
||||
static const TIFFFieldInfo tiff_fx_tiff_field_info[] =
|
||||
{
|
||||
{TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, FIELD_CUSTOM, false, false, (char *) "Indexed"},
|
||||
{TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, FIELD_CUSTOM, false, false, (char *) "GlobalParametersIFD"},
|
||||
{TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, FIELD_CUSTOM, false, false, (char *) "GlobalParametersIFD"},
|
||||
{TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "ProfileType"},
|
||||
{TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, FIELD_CUSTOM, false, false, (char *) "FaxProfile"},
|
||||
{TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "CodingMethods"},
|
||||
@ -86,7 +86,7 @@ static TIFFFieldArray tifffxFieldArray;
|
||||
static TIFFField tiff_fx_tiff_fields[] =
|
||||
{
|
||||
{ TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "Indexed" },
|
||||
{ TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, (char *) "GlobalParametersIFD", &tifffxFieldArray },
|
||||
{ TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, (char *) "GlobalParametersIFD", &tifffxFieldArray },
|
||||
{ TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "ProfileType", NULL },
|
||||
{ TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "FaxProfile", NULL },
|
||||
{ TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "CodingMethods", NULL },
|
||||
|
@ -28,7 +28,7 @@ run_tsb85_test()
|
||||
fi
|
||||
}
|
||||
|
||||
for TEST in PPS-MPS-lost-PPS V17-12000-V29-9600
|
||||
for TEST in PPS-MPS-lost-PPS V17-12000-V29-9600 Phase-D-collision
|
||||
do
|
||||
run_tsb85_test
|
||||
done
|
||||
|
@ -299,7 +299,7 @@ static int document_handler(void *user_data, int event)
|
||||
|
||||
ch = 'A';
|
||||
s = (t30_state_t *) user_data;
|
||||
fprintf(stderr, "%d: Document handler on channel %d - event %d\n", ch, ch, event);
|
||||
fprintf(stderr, "%c: Document handler on channel %c - event %d\n", ch, ch, event);
|
||||
if (next_tx_file[0])
|
||||
{
|
||||
t30_set_tx_file(s, next_tx_file, -1, -1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user