From 3549488e8eb56fe230db92728c895c68a0c91004 Mon Sep 17 00:00:00 2001 From: Steve Underwood <steveu@coppice.org> Date: Wed, 4 Jun 2014 23:54:03 +0800 Subject: [PATCH] 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. --- libs/spandsp/spandsp/fax-tests.xml | 41 +++++++++++++++++++++++ libs/spandsp/src/adsi.c | 6 ++-- libs/spandsp/src/at_interpreter.c | 2 +- libs/spandsp/src/fax_modems.c | 5 ++- libs/spandsp/src/hdlc.c | 38 ++++++++++++++++++++-- libs/spandsp/src/plc.c | 12 +++---- libs/spandsp/src/queue.c | 32 +++++++++--------- libs/spandsp/src/spandsp/hdlc.h | 25 +++++++++++++- libs/spandsp/src/t30.c | 43 ++++++++++++++++--------- libs/spandsp/src/t30_api.c | 6 ++-- libs/spandsp/src/t31.c | 2 +- libs/spandsp/src/t38_core.c | 2 +- libs/spandsp/src/t38_terminal.c | 28 ++++++++++------ libs/spandsp/src/time_scale.c | 18 +++++------ libs/spandsp/src/v42.c | 2 +- libs/spandsp/tests/fax_decode.c | 43 ++++++++++++++++++------- libs/spandsp/tests/fax_tester.c | 2 +- libs/spandsp/tests/power_meter_tests.c | 2 +- libs/spandsp/tests/t43_tests.c | 4 +-- libs/spandsp/tests/tsb85_extra_tests.sh | 2 +- libs/spandsp/tests/tsb85_tests.c | 2 +- 21 files changed, 228 insertions(+), 89 deletions(-) diff --git a/libs/spandsp/spandsp/fax-tests.xml b/libs/spandsp/spandsp/fax-tests.xml index 23f333a396..495eadec7e 100644 --- a/libs/spandsp/spandsp/fax-tests.xml +++ b/libs/spandsp/spandsp/fax-tests.xml @@ -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> diff --git a/libs/spandsp/src/adsi.c b/libs/spandsp/src/adsi.c index 1f711bf44f..72d85319c1 100644 --- a/libs/spandsp/src/adsi.c +++ b/libs/spandsp/src/adsi.c @@ -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); } diff --git a/libs/spandsp/src/at_interpreter.c b/libs/spandsp/src/at_interpreter.c index 9bebde6272..5d6dc42043 100644 --- a/libs/spandsp/src/at_interpreter.c +++ b/libs/spandsp/src/at_interpreter.c @@ -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 */ diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c index a09b0c9506..df89b088c2 100644 --- a/libs/spandsp/src/fax_modems.c +++ b/libs/spandsp/src/fax_modems.c @@ -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 --------------------------------------------------------*/ diff --git a/libs/spandsp/src/hdlc.c b/libs/spandsp/src/hdlc.c index 7a20bf2451..74b2760e70 100644 --- a/libs/spandsp/src/hdlc.c +++ b/libs/spandsp/src/hdlc.c @@ -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; diff --git a/libs/spandsp/src/plc.c b/libs/spandsp/src/plc.c index cb40ea88e0..52f4e24044 100644 --- a/libs/spandsp/src/plc.c +++ b/libs/spandsp/src/plc.c @@ -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 --------------------------------------------------------*/ diff --git a/libs/spandsp/src/queue.c b/libs/spandsp/src/queue.c index d569039969..98f19e3962 100644 --- a/libs/spandsp/src/queue.c +++ b/libs/spandsp/src/queue.c @@ -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; } diff --git a/libs/spandsp/src/spandsp/hdlc.h b/libs/spandsp/src/spandsp/hdlc.h index a0916d1d5f..52f68505b1 100644 --- a/libs/spandsp/src/spandsp/hdlc.h +++ b/libs/spandsp/src/spandsp/hdlc.h @@ -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. diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 8a9c1cd193..e7f958552c 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -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 { diff --git a/libs/spandsp/src/t30_api.c b/libs/spandsp/src/t30_api.c index 6d0bca3840..5bf164b998 100644 --- a/libs/spandsp/src/t30_api.c +++ b/libs/spandsp/src/t30_api.c @@ -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 diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c index 47f26c9e49..ef8dcd16f6 100644 --- a/libs/spandsp/src/t31.c +++ b/libs/spandsp/src/t31.c @@ -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*/ diff --git a/libs/spandsp/src/t38_core.c b/libs/spandsp/src/t38_core.c index 5fb57bbc82..c310ebbd95 100644 --- a/libs/spandsp/src/t38_core.c +++ b/libs/spandsp/src/t38_core.c @@ -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++; diff --git a/libs/spandsp/src/t38_terminal.c b/libs/spandsp/src/t38_terminal.c index 0349eb4283..03f8ede658 100644 --- a/libs/spandsp/src/t38_terminal.c +++ b/libs/spandsp/src/t38_terminal.c @@ -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 --------------------------------------------------------*/ diff --git a/libs/spandsp/src/time_scale.c b/libs/spandsp/src/time_scale.c index 6006333674..2378b4f1c8 100644 --- a/libs/spandsp/src/time_scale.c +++ b/libs/spandsp/src/time_scale.c @@ -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 diff --git a/libs/spandsp/src/v42.c b/libs/spandsp/src/v42.c index fb54fa5b39..806f7aa212 100644 --- a/libs/spandsp/src/v42.c +++ b/libs/spandsp/src/v42.c @@ -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; diff --git a/libs/spandsp/tests/fax_decode.c b/libs/spandsp/tests/fax_decode.c index 9fedc23c66..12cc11bb92 100644 --- a/libs/spandsp/tests/fax_decode.c +++ b/libs/spandsp/tests/fax_decode.c @@ -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); diff --git a/libs/spandsp/tests/fax_tester.c b/libs/spandsp/tests/fax_tester.c index df6aeeaf60..4cd85d68a7 100644 --- a/libs/spandsp/tests/fax_tester.c +++ b/libs/spandsp/tests/fax_tester.c @@ -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); diff --git a/libs/spandsp/tests/power_meter_tests.c b/libs/spandsp/tests/power_meter_tests.c index da04372778..518fa3a694 100644 --- a/libs/spandsp/tests/power_meter_tests.c +++ b/libs/spandsp/tests/power_meter_tests.c @@ -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); } diff --git a/libs/spandsp/tests/t43_tests.c b/libs/spandsp/tests/t43_tests.c index 76946b94b3..bc9242d044 100644 --- a/libs/spandsp/tests/t43_tests.c +++ b/libs/spandsp/tests/t43_tests.c @@ -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 }, diff --git a/libs/spandsp/tests/tsb85_extra_tests.sh b/libs/spandsp/tests/tsb85_extra_tests.sh index 8aa3b24740..08d8336eee 100755 --- a/libs/spandsp/tests/tsb85_extra_tests.sh +++ b/libs/spandsp/tests/tsb85_extra_tests.sh @@ -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 diff --git a/libs/spandsp/tests/tsb85_tests.c b/libs/spandsp/tests/tsb85_tests.c index 221c70634b..f383eb8f47 100644 --- a/libs/spandsp/tests/tsb85_tests.c +++ b/libs/spandsp/tests/tsb85_tests.c @@ -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);