diff --git a/libs/broadvoice/autogen.sh b/libs/broadvoice/autogen.sh index cc2a3321fa..842a9d19b6 100755 --- a/libs/broadvoice/autogen.sh +++ b/libs/broadvoice/autogen.sh @@ -16,9 +16,6 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# $Id: autogen.sh,v 1.1.1.1 2009/11/19 12:10:48 steveu Exp $ -# UNAME=`uname` diff --git a/libs/broadvoice/tests/regression_tests.sh.in b/libs/broadvoice/tests/regression_tests.sh.in index f7adfdf706..ede719f379 100644 --- a/libs/broadvoice/tests/regression_tests.sh.in +++ b/libs/broadvoice/tests/regression_tests.sh.in @@ -16,9 +16,6 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# $Id: regression_tests.sh.in,v 1.2 2009/11/20 13:12:24 steveu Exp $ -# STDOUT_DEST=xyzzy STDERR_DEST=xyzzy2 diff --git a/libs/broadvoice/tests/timing.h b/libs/broadvoice/tests/timing.h index d3bfd34139..9368894bcf 100644 --- a/libs/broadvoice/tests/timing.h +++ b/libs/broadvoice/tests/timing.h @@ -21,8 +21,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: timing.h,v 1.1.1.1 2009/11/19 12:10:48 steveu Exp $ */ #if !defined(_TIMING_H_) diff --git a/libs/spandsp/src/async.c b/libs/spandsp/src/async.c index bd4166aab9..28d44b4130 100644 --- a/libs/spandsp/src/async.c +++ b/libs/spandsp/src/async.c @@ -90,7 +90,7 @@ SPAN_DECLARE(const char *) signal_status_to_str(int status) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit) +SPAN_DECLARE(void) async_rx_put_bit(void *user_data, int bit) { async_rx_state_t *s; @@ -215,7 +215,7 @@ SPAN_DECLARE(int) async_rx_free(async_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) async_tx_get_bit(void *user_data) +SPAN_DECLARE(int) async_tx_get_bit(void *user_data) { async_tx_state_t *s; int bit; diff --git a/libs/spandsp/src/fax.c b/libs/spandsp/src/fax.c index d3dff3fe97..b34bb8231e 100644 --- a/libs/spandsp/src/fax.c +++ b/libs/spandsp/src/fax.c @@ -161,7 +161,7 @@ static void hdlc_underflow_handler(void *user_data) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_rx(fax_state_t *s, int16_t *amp, int len) +SPAN_DECLARE(int) fax_rx(fax_state_t *s, int16_t *amp, int len) { int i; @@ -180,7 +180,7 @@ SPAN_DECLARE_NONSTD(int) fax_rx(fax_state_t *s, int16_t *amp, int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len) +SPAN_DECLARE(int) fax_rx_fillin(fax_state_t *s, int len) { /* To mitigate the effect of lost packets on a packet network we should try to sustain the status quo. If there is no receive modem running, keep @@ -209,7 +209,7 @@ SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len) +SPAN_DECLARE(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len) { int len; #if defined(LOG_FAX_AUDIO) diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c index 78d5b198d0..0b405cc246 100644 --- a/libs/spandsp/src/fax_modems.c +++ b/libs/spandsp/src/fax_modems.c @@ -152,7 +152,7 @@ SPAN_DECLARE(const char *) fax_modem_to_str(int modem) /*- End of function --------------------------------------------------------*/ //static void fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) -SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) +SPAN_DECLARE(void) fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) { fax_modems_state_t *s; @@ -168,7 +168,7 @@ SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_accept(void *user_data, const uint8_t } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len) +SPAN_DECLARE(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len) { fax_modems_state_t *s; @@ -206,7 +206,7 @@ static void v17_rx_status_handler(void *user_data, int status) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len) +SPAN_DECLARE(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len) { fax_modems_state_t *s; @@ -224,7 +224,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t am } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len) +SPAN_DECLARE(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len) { fax_modems_state_t *s; @@ -253,7 +253,7 @@ static void v27ter_rx_status_handler(void *user_data, int status) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len) +SPAN_DECLARE(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len) { fax_modems_state_t *s; @@ -271,7 +271,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len) +SPAN_DECLARE(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len) { fax_modems_state_t *s; @@ -300,7 +300,7 @@ static void v29_rx_status_handler(void *user_data, int status) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len) +SPAN_DECLARE(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len) { fax_modems_state_t *s; @@ -318,7 +318,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t am } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len) +SPAN_DECLARE(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len) { fax_modems_state_t *s; diff --git a/libs/spandsp/src/fsk.c b/libs/spandsp/src/fsk.c index 07c242bfc4..8b714d1c1d 100644 --- a/libs/spandsp/src/fsk.c +++ b/libs/spandsp/src/fsk.c @@ -200,7 +200,7 @@ SPAN_DECLARE(int) fsk_tx_free(fsk_tx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fsk_tx(fsk_tx_state_t *s, int16_t amp[], int len) +SPAN_DECLARE(int) fsk_tx(fsk_tx_state_t *s, int16_t amp[], int len) { int sample; int bit; @@ -382,7 +382,7 @@ static void report_status_change(fsk_rx_state_t *s, int status) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len) +SPAN_DECLARE(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len) { int buf_ptr; int baudstate; @@ -626,7 +626,7 @@ SPAN_DECLARE_NONSTD(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) fsk_rx_fillin(fsk_rx_state_t *s, int len) +SPAN_DECLARE(int) fsk_rx_fillin(fsk_rx_state_t *s, int len) { int buf_ptr; int i; diff --git a/libs/spandsp/src/hdlc.c b/libs/spandsp/src/hdlc.c index c3de12d01e..80062fe4c7 100644 --- a/libs/spandsp/src/hdlc.c +++ b/libs/spandsp/src/hdlc.c @@ -299,7 +299,7 @@ static __inline__ void hdlc_rx_put_bit_core(hdlc_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) hdlc_rx_put_bit(hdlc_rx_state_t *s, int new_bit) +SPAN_DECLARE(void) hdlc_rx_put_bit(hdlc_rx_state_t *s, int new_bit) { if (new_bit < 0) { @@ -312,7 +312,7 @@ SPAN_DECLARE_NONSTD(void) hdlc_rx_put_bit(hdlc_rx_state_t *s, int new_bit) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) hdlc_rx_put_byte(hdlc_rx_state_t *s, int new_byte) +SPAN_DECLARE(void) hdlc_rx_put_byte(hdlc_rx_state_t *s, int new_byte) { int i; @@ -332,7 +332,7 @@ SPAN_DECLARE_NONSTD(void) hdlc_rx_put_byte(hdlc_rx_state_t *s, int new_byte) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) hdlc_rx_put(hdlc_rx_state_t *s, const uint8_t buf[], int len) +SPAN_DECLARE(void) hdlc_rx_put(hdlc_rx_state_t *s, const uint8_t buf[], int len) { int i; @@ -517,7 +517,7 @@ SPAN_DECLARE(int) hdlc_tx_corrupt_frame(hdlc_tx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) hdlc_tx_get_byte(hdlc_tx_state_t *s) +SPAN_DECLARE(int) hdlc_tx_get_byte(hdlc_tx_state_t *s) { int i; int byte_in_progress; @@ -636,7 +636,7 @@ SPAN_DECLARE_NONSTD(int) hdlc_tx_get_byte(hdlc_tx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) hdlc_tx_get_bit(hdlc_tx_state_t *s) +SPAN_DECLARE(int) hdlc_tx_get_bit(hdlc_tx_state_t *s) { int txbit; @@ -652,7 +652,7 @@ SPAN_DECLARE_NONSTD(int) hdlc_tx_get_bit(hdlc_tx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) hdlc_tx_get(hdlc_tx_state_t *s, uint8_t buf[], size_t max_len) +SPAN_DECLARE(int) hdlc_tx_get(hdlc_tx_state_t *s, uint8_t buf[], size_t max_len) { size_t i; int x; diff --git a/libs/spandsp/src/modem_connect_tones.c b/libs/spandsp/src/modem_connect_tones.c index 98262a1cad..cb43f219e0 100644 --- a/libs/spandsp/src/modem_connect_tones.c +++ b/libs/spandsp/src/modem_connect_tones.c @@ -110,9 +110,9 @@ SPAN_DECLARE(const char *) modem_connect_tone_to_str(int tone) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *s, - int16_t amp[], - int len) +SPAN_DECLARE(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *s, + int16_t amp[], + int len) { int16_t mod; int i; @@ -456,9 +456,9 @@ static void v21_put_bit(void *user_data, int bit) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *s, - const int16_t amp[], - int len) +SPAN_DECLARE(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *s, + const int16_t amp[], + int len) { int i; int16_t notched; @@ -700,7 +700,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t * } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx_fillin(modem_connect_tones_rx_state_t *s, int len) +SPAN_DECLARE(int) modem_connect_tones_rx_fillin(modem_connect_tones_rx_state_t *s, int len) { return 0; } diff --git a/libs/spandsp/src/silence_gen.c b/libs/spandsp/src/silence_gen.c index 7c24f4334e..e2da8fa387 100644 --- a/libs/spandsp/src/silence_gen.c +++ b/libs/spandsp/src/silence_gen.c @@ -57,7 +57,7 @@ #include "spandsp/private/silence_gen.h" -SPAN_DECLARE_NONSTD(int) silence_gen(silence_gen_state_t *s, int16_t *amp, int max_len) +SPAN_DECLARE(int) silence_gen(silence_gen_state_t *s, int16_t *amp, int max_len) { if (s->remaining_samples != INT_MAX) { @@ -151,7 +151,7 @@ SPAN_DECLARE(int) silence_gen_free(silence_gen_state_t *s) /* The following dummy routines, to absorb data, don't really have a proper home, so they have been put here. */ -SPAN_DECLARE_NONSTD(int) span_dummy_rx(void *user_data, const int16_t amp[], int len) +SPAN_DECLARE(int) span_dummy_rx(void *user_data, const int16_t amp[], int len) { return 0; } @@ -163,7 +163,7 @@ SPAN_DECLARE(int) span_dummy_mod(void *user_data, int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) span_dummy_rx_fillin(void *user_data, int len) +SPAN_DECLARE(int) span_dummy_rx_fillin(void *user_data, int len) { return 0; } diff --git a/libs/spandsp/src/spandsp/async.h b/libs/spandsp/src/spandsp/async.h index eabb41d3f1..290b3acc1d 100644 --- a/libs/spandsp/src/spandsp/async.h +++ b/libs/spandsp/src/spandsp/async.h @@ -156,7 +156,7 @@ SPAN_DECLARE(const char *) signal_status_to_str(int status); - SIG_STATUS_TRAINING_SUCCEEDED - SIG_STATUS_TRAINING_FAILED - SIG_STATUS_END_OF_DATA */ -SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit); +SPAN_DECLARE(void) async_rx_put_bit(void *user_data, int bit); /*! Initialise an asynchronous data receiver context. \brief Initialise an asynchronous data receiver context. @@ -190,7 +190,7 @@ SPAN_DECLARE(void) async_tx_presend_bits(async_tx_state_t *s, int bits); \brief Get the next bit of a transmitted serial bit stream. \param user_data An opaque point which must point to a transmitter context. \return the next bit, or PUTBIT_END_OF_DATA to indicate the data stream has ended. */ -SPAN_DECLARE_NONSTD(int) async_tx_get_bit(void *user_data); +SPAN_DECLARE(int) async_tx_get_bit(void *user_data); /*! Initialise an asynchronous data transmit context. \brief Initialise an asynchronous data transmit context. diff --git a/libs/spandsp/src/spandsp/fax.h b/libs/spandsp/src/spandsp/fax.h index 499b2b3b25..de6d52da0e 100644 --- a/libs/spandsp/src/spandsp/fax.h +++ b/libs/spandsp/src/spandsp/fax.h @@ -50,7 +50,7 @@ extern "C" \return The number of samples unprocessed. This should only be non-zero if the software has reached the end of the FAX call. */ -SPAN_DECLARE_NONSTD(int) fax_rx(fax_state_t *s, int16_t *amp, int len); +SPAN_DECLARE(int) fax_rx(fax_state_t *s, int16_t *amp, int len); /*! Apply fake T.30 receive processing when a block of audio samples is missing (e.g due to packet loss). @@ -60,7 +60,7 @@ SPAN_DECLARE_NONSTD(int) fax_rx(fax_state_t *s, int16_t *amp, int len); \return The number of samples unprocessed. This should only be non-zero if the software has reached the end of the FAX call. */ -SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len); +SPAN_DECLARE(int) fax_rx_fillin(fax_state_t *s, int len); /*! Apply T.30 transmit processing to generate a block of audio samples. \brief Apply T.30 transmit processing to generate a block of audio samples. @@ -70,7 +70,7 @@ SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len); \return The number of samples actually generated. This will be zero when there is nothing to send. */ -SPAN_DECLARE_NONSTD(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len); +SPAN_DECLARE(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len); /*! Select whether silent audio will be sent when FAX transmit is idle. \brief Select whether silent audio will be sent when FAX transmit is idle. diff --git a/libs/spandsp/src/spandsp/fax_modems.h b/libs/spandsp/src/spandsp/fax_modems.h index a076c0332f..15cc802474 100644 --- a/libs/spandsp/src/spandsp/fax_modems.h +++ b/libs/spandsp/src/spandsp/fax_modems.h @@ -64,7 +64,7 @@ extern "C" #endif /* TEMPORARY FUDGE */ -SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok); +SPAN_DECLARE(void) fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok); /*! Convert a FAX modem type to a short text description. \brief Convert a FAX modem type to a short text description. @@ -73,14 +73,14 @@ SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_accept(void *user_data, const uint8_t SPAN_DECLARE(const char *) fax_modem_to_str(int modem); /* N.B. the following are currently a work in progress */ -SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len); -SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len); -SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len); -SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len); -SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len); -SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len); +SPAN_DECLARE(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len); +SPAN_DECLARE(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len); +SPAN_DECLARE(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len); +SPAN_DECLARE(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len); +SPAN_DECLARE(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len); +SPAN_DECLARE(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len); -SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len); +SPAN_DECLARE(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_t *msg, int len); SPAN_DECLARE(void) fax_modems_hdlc_tx_flags(fax_modems_state_t *s, int flags); diff --git a/libs/spandsp/src/spandsp/fsk.h b/libs/spandsp/src/spandsp/fsk.h index b65cd7842f..c016eca8a5 100644 --- a/libs/spandsp/src/spandsp/fsk.h +++ b/libs/spandsp/src/spandsp/fsk.h @@ -187,7 +187,7 @@ SPAN_DECLARE(void) fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, modem_stat \param len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) fsk_tx(fsk_tx_state_t *s, int16_t amp[], int len); +SPAN_DECLARE(int) fsk_tx(fsk_tx_state_t *s, int16_t amp[], int len); /*! Get the current received signal power. \param s The modem context. @@ -228,7 +228,7 @@ SPAN_DECLARE(int) fsk_rx_free(fsk_rx_state_t *s); \param len The number of samples in the buffer. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len); +SPAN_DECLARE(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len); /*! Fake processing of a missing block of received FSK modem audio samples (e.g due to packet loss). @@ -237,7 +237,7 @@ SPAN_DECLARE_NONSTD(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len); \param len The number of samples to fake. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) fsk_rx_fillin(fsk_rx_state_t *s, int len); +SPAN_DECLARE(int) fsk_rx_fillin(fsk_rx_state_t *s, int len); SPAN_DECLARE(void) fsk_rx_set_put_bit(fsk_rx_state_t *s, put_bit_func_t put_bit, void *user_data); diff --git a/libs/spandsp/src/spandsp/hdlc.h b/libs/spandsp/src/spandsp/hdlc.h index a9369475c1..1349a57a04 100644 --- a/libs/spandsp/src/spandsp/hdlc.h +++ b/libs/spandsp/src/spandsp/hdlc.h @@ -160,20 +160,20 @@ SPAN_DECLARE(int) hdlc_rx_get_stats(hdlc_rx_state_t *s, \param s A pointer to an HDLC receiver context. \param new_bit The bit. */ -SPAN_DECLARE_NONSTD(void) hdlc_rx_put_bit(hdlc_rx_state_t *s, int new_bit); +SPAN_DECLARE(void) hdlc_rx_put_bit(hdlc_rx_state_t *s, int new_bit); /*! \brief Put a byte of data to an HDLC receiver. \param s A pointer to an HDLC receiver context. \param new_byte The byte of data. */ -SPAN_DECLARE_NONSTD(void) hdlc_rx_put_byte(hdlc_rx_state_t *s, int new_byte); +SPAN_DECLARE(void) hdlc_rx_put_byte(hdlc_rx_state_t *s, int new_byte); /*! \brief Put a series of bytes of data to an HDLC receiver. \param s A pointer to an HDLC receiver context. \param buf The buffer of data. \param len The length of the data in the buffer. */ -SPAN_DECLARE_NONSTD(void) hdlc_rx_put(hdlc_rx_state_t *s, const uint8_t buf[], int len); +SPAN_DECLARE(void) hdlc_rx_put(hdlc_rx_state_t *s, const uint8_t buf[], int len); /*! Initialise an HDLC transmitter context. \brief Initialise an HDLC transmitter context. @@ -250,13 +250,13 @@ SPAN_DECLARE(int) hdlc_tx_abort(hdlc_tx_state_t *s); \param s A pointer to an HDLC transmitter context. \return The next bit for transmission. */ -SPAN_DECLARE_NONSTD(int) hdlc_tx_get_bit(hdlc_tx_state_t *s); +SPAN_DECLARE(int) hdlc_tx_get_bit(hdlc_tx_state_t *s); /*! \brief Get the next byte for transmission. \param s A pointer to an HDLC transmitter context. \return The next byte for transmission. */ -SPAN_DECLARE_NONSTD(int) hdlc_tx_get_byte(hdlc_tx_state_t *s); +SPAN_DECLARE(int) hdlc_tx_get_byte(hdlc_tx_state_t *s); /*! \brief Get the next sequence of bytes for transmission. \param s A pointer to an HDLC transmitter context. @@ -264,7 +264,7 @@ SPAN_DECLARE_NONSTD(int) hdlc_tx_get_byte(hdlc_tx_state_t *s); \param max_len The number of bytes to get. \return The number of bytes actually got. */ -SPAN_DECLARE_NONSTD(int) hdlc_tx_get(hdlc_tx_state_t *s, uint8_t buf[], size_t max_len); +SPAN_DECLARE(int) hdlc_tx_get(hdlc_tx_state_t *s, uint8_t buf[], size_t max_len); #if defined(__cplusplus) } diff --git a/libs/spandsp/src/spandsp/modem_connect_tones.h b/libs/spandsp/src/spandsp/modem_connect_tones.h index 713f813bbb..bbfc6f3b97 100644 --- a/libs/spandsp/src/spandsp/modem_connect_tones.h +++ b/libs/spandsp/src/spandsp/modem_connect_tones.h @@ -127,9 +127,9 @@ SPAN_DECLARE(int) modem_connect_tones_tx_free(modem_connect_tones_tx_state_t *s) \param len The number of samples to generate. \return The number of samples generated. */ -SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *s, - int16_t amp[], - int len); +SPAN_DECLARE(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *s, + int16_t amp[], + int len); /*! \brief Process a block of samples through an instance of the modem connect tones detector. @@ -138,9 +138,9 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t * \param len The number of samples in the array. \return The number of unprocessed samples. */ -SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *s, - const int16_t amp[], - int len); +SPAN_DECLARE(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *s, + const int16_t amp[], + int len); /*! Fake processing of a missing block of received modem connect tone samples (e.g due to packet loss). @@ -149,7 +149,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t * \param len The number of samples to fake. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx_fillin(modem_connect_tones_rx_state_t *s, int len); +SPAN_DECLARE(int) modem_connect_tones_rx_fillin(modem_connect_tones_rx_state_t *s, int len); /*! \brief Test if a modem_connect tone has been detected. \param s The context. diff --git a/libs/spandsp/src/spandsp/silence_gen.h b/libs/spandsp/src/spandsp/silence_gen.h index df90ec0e9e..94357b7247 100644 --- a/libs/spandsp/src/spandsp/silence_gen.h +++ b/libs/spandsp/src/spandsp/silence_gen.h @@ -41,7 +41,7 @@ extern "C" \return The number of samples actually generated. This will be zero when there is nothing to send. */ -SPAN_DECLARE_NONSTD(int) silence_gen(silence_gen_state_t *s, int16_t *amp, int max_len); +SPAN_DECLARE(int) silence_gen(silence_gen_state_t *s, int16_t *amp, int max_len); /*! Set a silence generator context to output continuous silence. \brief Set a silence generator context to output continuous silence. @@ -110,7 +110,7 @@ SPAN_DECLARE(int) silence_gen_free(silence_gen_state_t *s); \param len The length of the signal buffer \return 0. */ -SPAN_DECLARE_NONSTD(int) span_dummy_rx(void *user_data, const int16_t amp[], int len); +SPAN_DECLARE(int) span_dummy_rx(void *user_data, const int16_t amp[], int len); /*! A dummy routine to use as a signal modifier callback, when we aren't really trying to process the signal. It just returns without affecting @@ -131,7 +131,7 @@ SPAN_DECLARE(int) span_dummy_mod(void *user_data, int16_t amp[], int len); \param len The length of the signal buffer \return 0. */ -SPAN_DECLARE_NONSTD(int) span_dummy_rx_fillin(void *user_data, int len); +SPAN_DECLARE(int) span_dummy_rx_fillin(void *user_data, int len); #if defined(__cplusplus) } diff --git a/libs/spandsp/src/spandsp/stdbool.h b/libs/spandsp/src/spandsp/stdbool.h index ce1dc387b5..faceaac3f9 100644 --- a/libs/spandsp/src/spandsp/stdbool.h +++ b/libs/spandsp/src/spandsp/stdbool.h @@ -32,14 +32,16 @@ #if !defined(_STDBOOL_H) #define _STDBOOL_H + #ifdef _MSC_VER #pragma warning (disable: 4005) #endif + #if !defined(__cplusplus) #define _Bool int -#define false 0 #define bool int +#define false 0 #define true (!false) #else diff --git a/libs/spandsp/src/spandsp/t30.h b/libs/spandsp/src/spandsp/t30.h index b3c0b6ad36..00749004f2 100644 --- a/libs/spandsp/src/spandsp/t30.h +++ b/libs/spandsp/src/spandsp/t30.h @@ -576,7 +576,7 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status); \brief Get a bit of received non-ECM image data. \param user_data An opaque pointer, which must point to the T.30 context. \return The next bit to transmit. */ -SPAN_DECLARE_NONSTD(int) t30_non_ecm_get_bit(void *user_data); +SPAN_DECLARE(int) t30_non_ecm_get_bit(void *user_data); /*! Get a chunk of received non-ECM image data. \brief Get a bit of received non-ECM image data. @@ -590,7 +590,7 @@ SPAN_DECLARE(int) t30_non_ecm_get(void *user_data, uint8_t buf[], int max_len); \brief Process a bit of received non-ECM image data \param user_data An opaque pointer, which must point to the T.30 context. \param bit The received bit. */ -SPAN_DECLARE_NONSTD(void) t30_non_ecm_put_bit(void *user_data, int bit); +SPAN_DECLARE(void) t30_non_ecm_put_bit(void *user_data, int bit); /*! Process a chunk of received non-ECM image data. \brief Process a chunk of received non-ECM image data @@ -605,7 +605,7 @@ SPAN_DECLARE(void) t30_non_ecm_put(void *user_data, const uint8_t buf[], int len \param msg The HDLC message. \param len The length of the message, in octets. \param ok True if the frame was received without error. */ -SPAN_DECLARE_NONSTD(void) t30_hdlc_accept(void *user_data, const uint8_t msg[], int len, int ok); +SPAN_DECLARE(void) t30_hdlc_accept(void *user_data, const uint8_t msg[], int len, int ok); /*! Report the passage of time to the T.30 engine. \brief Report the passage of time to the T.30 engine. diff --git a/libs/spandsp/src/spandsp/t31.h b/libs/spandsp/src/spandsp/t31.h index b61a4142f9..45237c4e7c 100644 --- a/libs/spandsp/src/spandsp/t31.h +++ b/libs/spandsp/src/spandsp/t31.h @@ -65,7 +65,7 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len); \param amp The audio sample buffer. \param len The number of samples in the buffer. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len); +SPAN_DECLARE(int) t31_rx(t31_state_t *s, int16_t amp[], int len); /*! Fake processing of a missing block of received T.31 modem audio samples (e.g due to packet loss). @@ -73,7 +73,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len); \param s The T.31 modem context. \param len The number of samples to fake. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) t31_rx_fillin(t31_state_t *s, int len); +SPAN_DECLARE(int) t31_rx_fillin(t31_state_t *s, int len); /*! Generate a block of T.31 modem audio samples. \brief Generate a block of T.31 modem audio samples. @@ -82,7 +82,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx_fillin(t31_state_t *s, int len); \param max_len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len); +SPAN_DECLARE(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len); SPAN_DECLARE(int) t31_t38_send_timeout(t31_state_t *s, int samples); diff --git a/libs/spandsp/src/spandsp/t38_core.h b/libs/spandsp/src/spandsp/t38_core.h index 86e45089ac..3d3d83da51 100644 --- a/libs/spandsp/src/spandsp/t38_core.h +++ b/libs/spandsp/src/spandsp/t38_core.h @@ -288,7 +288,7 @@ SPAN_DECLARE(int) t38_core_send_data_multi_field(t38_core_state_t *s, int data_t \param len The length of the packet contents. \param seq_no The packet sequence number. \return 0 for OK, else -1. */ -SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no); +SPAN_DECLARE(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no); /*! \brief Process a received T.38 IFP packet from a reliable stream (e.g. TCP). \param s The T.38 context. @@ -296,7 +296,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8 \param len The length of the packet contents. \param seq_no The packet sequence number, used for logging purposes. \return The length of the packet processed, or -1 if there is an error in the packet, or too few bytes of data to complete it. */ -SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t log_seq_no); +SPAN_DECLARE(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t log_seq_no); /*! Set the method to be used for data rate management, as per the T.38 spec. \param s The T.38 context. diff --git a/libs/spandsp/src/spandsp/t38_gateway.h b/libs/spandsp/src/spandsp/t38_gateway.h index 8d7f2e0500..c6f4a876f3 100644 --- a/libs/spandsp/src/spandsp/t38_gateway.h +++ b/libs/spandsp/src/spandsp/t38_gateway.h @@ -102,7 +102,7 @@ SPAN_DECLARE(int) t38_gateway_free(t38_gateway_state_t *s); \param amp The audio sample buffer. \param len The number of samples in the buffer. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], int len); +SPAN_DECLARE(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], int len); /*! Apply fake processing when a block of audio samples is missing (e.g due to packet loss). @@ -112,7 +112,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], i \return The number of samples unprocessed. This should only be non-zero if the software has reached the end of the FAX call. */ -SPAN_DECLARE_NONSTD(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len); +SPAN_DECLARE(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len); /*! Generate a block of FAX audio samples. \brief Generate a block of FAX audio samples. @@ -121,7 +121,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len); \param max_len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], int max_len); +SPAN_DECLARE(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], int max_len); /*! Control whether error correcting mode (ECM) is allowed. \brief Control whether error correcting mode (ECM) is allowed. diff --git a/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h b/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h index 3ca28c3d12..a841177d60 100644 --- a/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h +++ b/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h @@ -124,7 +124,7 @@ SPAN_DECLARE(void) t38_non_ecm_buffer_report_output_status(t38_non_ecm_buffer_st /*! \brief Get the next bit of data from a T.38 rate adapting non-ECM buffer context. \param user_data The buffer context, cast to a void pointer. \return The next bit, or one of the values indicating a change of modem status. */ -SPAN_DECLARE_NONSTD(int) t38_non_ecm_buffer_get_bit(void *user_data); +SPAN_DECLARE(int) t38_non_ecm_buffer_get_bit(void *user_data); #if defined(__cplusplus) } diff --git a/libs/spandsp/src/spandsp/telephony.h b/libs/spandsp/src/spandsp/telephony.h index 58a8e29c6a..0d0f306fe1 100644 --- a/libs/spandsp/src/spandsp/telephony.h +++ b/libs/spandsp/src/spandsp/telephony.h @@ -28,21 +28,17 @@ #if defined(_M_IX86) || defined(_M_X64) #if defined(LIBSPANDSP_EXPORTS) -#define SPAN_DECLARE(type) __declspec(dllexport) type __stdcall -#define SPAN_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl +#define SPAN_DECLARE(type) __declspec(dllexport) type #define SPAN_DECLARE_DATA __declspec(dllexport) #else -#define SPAN_DECLARE(type) __declspec(dllimport) type __stdcall -#define SPAN_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl +#define SPAN_DECLARE(type) __declspec(dllimport) type #define SPAN_DECLARE_DATA __declspec(dllimport) #endif #elif defined(SPANDSP_USE_EXPORT_CAPABILITY) && (defined(__GNUC__) || defined(__SUNCC__)) #define SPAN_DECLARE(type) __attribute__((visibility("default"))) type -#define SPAN_DECLARE_NONSTD(type) __attribute__((visibility("default"))) type #define SPAN_DECLARE_DATA __attribute__((visibility("default"))) #else #define SPAN_DECLARE(type) /**/ type -#define SPAN_DECLARE_NONSTD(type) /**/ type #define SPAN_DECLARE_DATA /**/ #endif diff --git a/libs/spandsp/src/spandsp/tone_generate.h b/libs/spandsp/src/spandsp/tone_generate.h index 7fe140c216..a3d1b5a893 100644 --- a/libs/spandsp/src/spandsp/tone_generate.h +++ b/libs/spandsp/src/spandsp/tone_generate.h @@ -88,7 +88,7 @@ SPAN_DECLARE(tone_gen_descriptor_t *) tone_gen_descriptor_init(tone_gen_descript SPAN_DECLARE(void) tone_gen_descriptor_free(tone_gen_descriptor_t *s); -SPAN_DECLARE_NONSTD(int) tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples); +SPAN_DECLARE(int) tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples); SPAN_DECLARE(tone_gen_state_t *) tone_gen_init(tone_gen_state_t *s, tone_gen_descriptor_t *t); diff --git a/libs/spandsp/src/spandsp/v17rx.h b/libs/spandsp/src/spandsp/v17rx.h index 8aebe85263..8f6c34993d 100644 --- a/libs/spandsp/src/spandsp/v17rx.h +++ b/libs/spandsp/src/spandsp/v17rx.h @@ -284,7 +284,7 @@ SPAN_DECLARE(void) v17_rx_set_modem_status_handler(v17_rx_state_t *s, modem_stat \param len The number of samples in the buffer. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len); +SPAN_DECLARE(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len); /*! Fake processing of a missing block of received V.17 modem audio samples. (e.g due to packet loss). @@ -293,7 +293,7 @@ SPAN_DECLARE_NONSTD(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) \param len The number of samples to fake. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v17_rx_fillin(v17_rx_state_t *s, int len); +SPAN_DECLARE(int) v17_rx_fillin(v17_rx_state_t *s, int len); /*! Get a snapshot of the current equalizer coefficients. \brief Get a snapshot of the current equalizer coefficients. diff --git a/libs/spandsp/src/spandsp/v17tx.h b/libs/spandsp/src/spandsp/v17tx.h index 02fb7309ad..79d65629fc 100644 --- a/libs/spandsp/src/spandsp/v17tx.h +++ b/libs/spandsp/src/spandsp/v17tx.h @@ -155,7 +155,7 @@ SPAN_DECLARE(void) v17_tx_set_modem_status_handler(v17_tx_state_t *s, modem_stat \param len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) v17_tx(v17_tx_state_t *s, int16_t amp[], int len); +SPAN_DECLARE(int) v17_tx(v17_tx_state_t *s, int16_t amp[], int len); #if defined(__cplusplus) } diff --git a/libs/spandsp/src/spandsp/v18.h b/libs/spandsp/src/spandsp/v18.h index 04c0db7c15..50aa5ab260 100644 --- a/libs/spandsp/src/spandsp/v18.h +++ b/libs/spandsp/src/spandsp/v18.h @@ -143,7 +143,7 @@ SPAN_DECLARE(int) v18_free(v18_state_t *s); \param max_len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t amp[], int max_len); +SPAN_DECLARE(int) v18_tx(v18_state_t *s, int16_t amp[], int max_len); /*! Process a block of received V.18 audio samples. \brief Process a block of received V.18 audio samples. @@ -152,7 +152,7 @@ SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t amp[], int max_len); \param len The number of samples in the buffer. \return The number of unprocessed samples. */ -SPAN_DECLARE_NONSTD(int) v18_rx(v18_state_t *s, const int16_t amp[], int len); +SPAN_DECLARE(int) v18_rx(v18_state_t *s, const int16_t amp[], int len); /*! Fake processing of a missing block of received V.18 audio samples. (e.g due to packet loss). @@ -161,7 +161,7 @@ SPAN_DECLARE_NONSTD(int) v18_rx(v18_state_t *s, const int16_t amp[], int len); \param len The number of samples to fake. \return The number of unprocessed samples. */ -SPAN_DECLARE_NONSTD(int) v18_rx_fillin(v18_state_t *s, int len); +SPAN_DECLARE(int) v18_rx_fillin(v18_state_t *s, int len); /*! \brief Put a string to a V.18 context's input buffer. \param s The V.18 context. diff --git a/libs/spandsp/src/spandsp/v22bis.h b/libs/spandsp/src/spandsp/v22bis.h index 50b2fb4467..fd93373cec 100644 --- a/libs/spandsp/src/spandsp/v22bis.h +++ b/libs/spandsp/src/spandsp/v22bis.h @@ -78,7 +78,7 @@ extern "C" \param amp The audio sample buffer. \param len The number of samples in the buffer. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len); +SPAN_DECLARE(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len); /*! Fake processing of a missing block of received V.22bis modem audio samples. (e.g due to packet loss). @@ -86,7 +86,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l \param s The modem context. \param len The number of samples to fake. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v22bis_rx_fillin(v22bis_state_t *s, int len); +SPAN_DECLARE(int) v22bis_rx_fillin(v22bis_state_t *s, int len); /*! Get a snapshot of the current equalizer coefficients. \brief Get a snapshot of the current equalizer coefficients. @@ -130,7 +130,7 @@ SPAN_DECLARE(void) v22bis_rx_set_qam_report_handler(v22bis_state_t *s, qam_repor \param amp The audio sample buffer. \param len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len); +SPAN_DECLARE(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len); /*! Adjust a V.22bis modem transmit context's power output. \brief Adjust a V.22bis modem transmit context's output power. diff --git a/libs/spandsp/src/spandsp/v27ter_rx.h b/libs/spandsp/src/spandsp/v27ter_rx.h index 80fdb3655f..cf8eaa99f7 100644 --- a/libs/spandsp/src/spandsp/v27ter_rx.h +++ b/libs/spandsp/src/spandsp/v27ter_rx.h @@ -117,7 +117,7 @@ SPAN_DECLARE(void) v27ter_rx_set_modem_status_handler(v27ter_rx_state_t *s, mode \param len The number of samples in the buffer. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len); +SPAN_DECLARE(int) v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len); /*! Fake processing of a missing block of received V.27ter modem audio samples. (e.g due to packet loss). @@ -126,7 +126,7 @@ SPAN_DECLARE_NONSTD(int) v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], in \param len The number of samples to fake. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v27ter_rx_fillin(v27ter_rx_state_t *s, int len); +SPAN_DECLARE(int) v27ter_rx_fillin(v27ter_rx_state_t *s, int len); /*! Get a snapshot of the current equalizer coefficients. \brief Get a snapshot of the current equalizer coefficients. diff --git a/libs/spandsp/src/spandsp/v27ter_tx.h b/libs/spandsp/src/spandsp/v27ter_tx.h index fba064fea0..96a0df5f54 100644 --- a/libs/spandsp/src/spandsp/v27ter_tx.h +++ b/libs/spandsp/src/spandsp/v27ter_tx.h @@ -136,7 +136,7 @@ SPAN_DECLARE(void) v27ter_tx_set_modem_status_handler(v27ter_tx_state_t *s, mode \param len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len); +SPAN_DECLARE(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len); #if defined(__cplusplus) } diff --git a/libs/spandsp/src/spandsp/v29rx.h b/libs/spandsp/src/spandsp/v29rx.h index 378d4fe955..9ef548e4c7 100644 --- a/libs/spandsp/src/spandsp/v29rx.h +++ b/libs/spandsp/src/spandsp/v29rx.h @@ -196,7 +196,7 @@ SPAN_DECLARE(void) v29_rx_set_modem_status_handler(v29_rx_state_t *s, modem_stat \param amp The audio sample buffer. \param len The number of samples in the buffer. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v29_rx(v29_rx_state_t *s, const int16_t amp[], int len); +SPAN_DECLARE(int) v29_rx(v29_rx_state_t *s, const int16_t amp[], int len); /*! Fake processing of a missing block of received V.29 modem audio samples. (e.g due to packet loss). @@ -204,7 +204,7 @@ SPAN_DECLARE_NONSTD(int) v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) \param s The modem context. \param len The number of samples to fake. \return The number of samples unprocessed. */ -SPAN_DECLARE_NONSTD(int) v29_rx_fillin(v29_rx_state_t *s, int len); +SPAN_DECLARE(int) v29_rx_fillin(v29_rx_state_t *s, int len); /*! Get a snapshot of the current equalizer coefficients. \brief Get a snapshot of the current equalizer coefficients. diff --git a/libs/spandsp/src/spandsp/v29tx.h b/libs/spandsp/src/spandsp/v29tx.h index 18bcf66b6a..6bdb5de9e7 100644 --- a/libs/spandsp/src/spandsp/v29tx.h +++ b/libs/spandsp/src/spandsp/v29tx.h @@ -167,7 +167,7 @@ SPAN_DECLARE(void) v29_tx_set_modem_status_handler(v29_tx_state_t *s, modem_stat \param len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) v29_tx(v29_tx_state_t *s, int16_t amp[], int len); +SPAN_DECLARE(int) v29_tx(v29_tx_state_t *s, int16_t amp[], int len); #if defined(__cplusplus) } diff --git a/libs/spandsp/src/spandsp/v42.h b/libs/spandsp/src/spandsp/v42.h index 8002d43eed..fa1d7c1b5f 100644 --- a/libs/spandsp/src/spandsp/v42.h +++ b/libs/spandsp/src/spandsp/v42.h @@ -45,7 +45,7 @@ extern "C" SPAN_DECLARE(const char *) lapm_status_to_str(int status); -SPAN_DECLARE_NONSTD(void) lapm_receive(void *user_data, const uint8_t *frame, int len, int ok); +SPAN_DECLARE(void) lapm_receive(void *user_data, const uint8_t *frame, int len, int ok); SPAN_DECLARE(void) v42_start(v42_state_t *s); diff --git a/libs/spandsp/src/spandsp/v8.h b/libs/spandsp/src/spandsp/v8.h index 9ded271aec..ab3d1466c5 100644 --- a/libs/spandsp/src/spandsp/v8.h +++ b/libs/spandsp/src/spandsp/v8.h @@ -173,7 +173,7 @@ SPAN_DECLARE(logging_state_t *) v8_get_logging_state(v8_state_t *s); \param max_len The number of samples to be generated. \return The number of samples actually generated. */ -SPAN_DECLARE_NONSTD(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len); +SPAN_DECLARE(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len); /*! Process a block of received V.8 audio samples. \brief Process a block of received V.8 audio samples. @@ -181,7 +181,7 @@ SPAN_DECLARE_NONSTD(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len); \param amp The audio sample buffer. \param len The number of samples in the buffer. */ -SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len); +SPAN_DECLARE(int) v8_rx(v8_state_t *s, const int16_t *amp, int len); /*! Log the list of supported modulations. \brief Log the list of supported modulations. diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 3a31893e30..f13d4eb879 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -6401,7 +6401,7 @@ static void t30_non_ecm_rx_status(void *user_data, int status) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) t30_non_ecm_put_bit(void *user_data, int bit) +SPAN_DECLARE(void) t30_non_ecm_put_bit(void *user_data, int bit) { t30_state_t *s; int res; @@ -6499,7 +6499,7 @@ SPAN_DECLARE(void) t30_non_ecm_put(void *user_data, const uint8_t buf[], int len } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t30_non_ecm_get_bit(void *user_data) +SPAN_DECLARE(int) t30_non_ecm_get_bit(void *user_data) { int bit; t30_state_t *s; @@ -6705,7 +6705,7 @@ static void t30_hdlc_rx_status(void *user_data, int status) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) t30_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) +SPAN_DECLARE(void) t30_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) { t30_state_t *s; diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c index e63eb229e8..91e1e8063c 100644 --- a/libs/spandsp/src/t31.c +++ b/libs/spandsp/src/t31.c @@ -2772,7 +2772,7 @@ static int initial_timed_rx(void *user_data, const int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len) +SPAN_DECLARE(int) t31_rx(t31_state_t *s, int16_t amp[], int len) { int i; int32_t power; @@ -2822,7 +2822,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t31_rx_fillin(t31_state_t *s, int len) +SPAN_DECLARE(int) t31_rx_fillin(t31_state_t *s, int len) { /* To mitigate the effect of lost packets on a packet network we should try to sustain the status quo. If there is no receive modem running, keep @@ -2848,7 +2848,7 @@ SPAN_DECLARE_NONSTD(int) t31_rx_fillin(t31_state_t *s, int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len) +SPAN_DECLARE(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len) { int len; diff --git a/libs/spandsp/src/t38_core.c b/libs/spandsp/src/t38_core.c index de13af3e11..347549549f 100644 --- a/libs/spandsp/src/t38_core.c +++ b/libs/spandsp/src/t38_core.c @@ -347,7 +347,7 @@ static __inline__ int classify_seq_no_offset(int expected, int actual) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t log_seq_no) +SPAN_DECLARE(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t log_seq_no) { int i; int t30_indicator; @@ -668,7 +668,7 @@ SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_stream(t38_core_state_t *s, const uint8 } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no) +SPAN_DECLARE(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no) { int log_seq_no; int ptr; diff --git a/libs/spandsp/src/t38_gateway.c b/libs/spandsp/src/t38_gateway.c index 4467a615ad..53c877e591 100644 --- a/libs/spandsp/src/t38_gateway.c +++ b/libs/spandsp/src/t38_gateway.c @@ -2134,7 +2134,7 @@ static void update_rx_timing(t38_gateway_state_t *s, int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], int len) +SPAN_DECLARE(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], int len) { int i; @@ -2153,7 +2153,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], i } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len) +SPAN_DECLARE(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len) { /* To mitigate the effect of lost packets on a packet network we should try to sustain the status quo. If there is no receive modem running, keep @@ -2181,7 +2181,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx_fillin(t38_gateway_state_t *s, int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], int max_len) +SPAN_DECLARE(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], int max_len) { int len; #if defined(LOG_FAX_AUDIO) diff --git a/libs/spandsp/src/t38_non_ecm_buffer.c b/libs/spandsp/src/t38_non_ecm_buffer.c index b5b2c8244b..99fa456a96 100644 --- a/libs/spandsp/src/t38_non_ecm_buffer.c +++ b/libs/spandsp/src/t38_non_ecm_buffer.c @@ -85,7 +85,7 @@ static void restart_buffer(t38_non_ecm_buffer_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) t38_non_ecm_buffer_get_bit(void *user_data) +SPAN_DECLARE(int) t38_non_ecm_buffer_get_bit(void *user_data) { t38_non_ecm_buffer_state_t *s; int bit; diff --git a/libs/spandsp/src/tone_generate.c b/libs/spandsp/src/tone_generate.c index be3f6854a4..c01c970674 100644 --- a/libs/spandsp/src/tone_generate.c +++ b/libs/spandsp/src/tone_generate.c @@ -119,7 +119,7 @@ SPAN_DECLARE(void) tone_gen_descriptor_free(tone_gen_descriptor_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples) +SPAN_DECLARE(int) tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples) { int samples; int limit; diff --git a/libs/spandsp/src/v17rx.c b/libs/spandsp/src/v17rx.c index aea4e5913d..cda544990e 100644 --- a/libs/spandsp/src/v17rx.c +++ b/libs/spandsp/src/v17rx.c @@ -1229,7 +1229,7 @@ static __inline__ int signal_detect(v17_rx_state_t *s, int16_t amp) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) +SPAN_DECLARE(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) { int i; int step; @@ -1341,7 +1341,7 @@ SPAN_DECLARE_NONSTD(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v17_rx_fillin(v17_rx_state_t *s, int len) +SPAN_DECLARE(int) v17_rx_fillin(v17_rx_state_t *s, int len) { int i; diff --git a/libs/spandsp/src/v17tx.c b/libs/spandsp/src/v17tx.c index 4d3d8f9990..a57bc9f705 100644 --- a/libs/spandsp/src/v17tx.c +++ b/libs/spandsp/src/v17tx.c @@ -296,7 +296,7 @@ static __inline__ complexf_t getbaud(v17_tx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v17_tx(v17_tx_state_t *s, int16_t amp[], int len) +SPAN_DECLARE(int) v17_tx(v17_tx_state_t *s, int16_t amp[], int len) { #if defined(SPANDSP_USE_FIXED_POINT) complexi16_t v; diff --git a/libs/spandsp/src/v18.c b/libs/spandsp/src/v18.c index 3b72b296e1..0f34415720 100644 --- a/libs/spandsp/src/v18.c +++ b/libs/spandsp/src/v18.c @@ -978,7 +978,7 @@ static void v18_textphone_put_async_byte(void *user_data, int byte) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t *amp, int max_len) +SPAN_DECLARE(int) v18_tx(v18_state_t *s, int16_t *amp, int max_len) { int len; int lenx; @@ -1006,7 +1006,7 @@ SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t *amp, int max_len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v18_rx(v18_state_t *s, const int16_t amp[], int len) +SPAN_DECLARE(int) v18_rx(v18_state_t *s, const int16_t amp[], int len) { if (s->rx_suppression > 0) { @@ -1037,7 +1037,7 @@ SPAN_DECLARE_NONSTD(int) v18_rx(v18_state_t *s, const int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v18_rx_fillin(v18_state_t *s, int len) +SPAN_DECLARE(int) v18_rx_fillin(v18_state_t *s, int len) { if (s->rx_suppression > 0) { diff --git a/libs/spandsp/src/v22bis_rx.c b/libs/spandsp/src/v22bis_rx.c index af922882a6..cfb4e1378a 100644 --- a/libs/spandsp/src/v22bis_rx.c +++ b/libs/spandsp/src/v22bis_rx.c @@ -776,7 +776,7 @@ static __inline__ void process_half_baud(v22bis_state_t *s, const complexf_t *sa } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len) +SPAN_DECLARE(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len) { int i; int step; @@ -919,7 +919,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v22bis_rx_fillin(v22bis_state_t *s, int len) +SPAN_DECLARE(int) v22bis_rx_fillin(v22bis_state_t *s, int len) { int i; diff --git a/libs/spandsp/src/v22bis_tx.c b/libs/spandsp/src/v22bis_tx.c index 430ebc5d84..41afff55c7 100644 --- a/libs/spandsp/src/v22bis_tx.c +++ b/libs/spandsp/src/v22bis_tx.c @@ -469,7 +469,7 @@ static complexf_t getbaud(v22bis_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len) +SPAN_DECLARE(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len) { #if defined(SPANDSP_USE_FIXED_POINT) complexi16_t v; diff --git a/libs/spandsp/src/v27ter_rx.c b/libs/spandsp/src/v27ter_rx.c index 93d3b4680d..9383d46af0 100644 --- a/libs/spandsp/src/v27ter_rx.c +++ b/libs/spandsp/src/v27ter_rx.c @@ -828,7 +828,7 @@ static __inline__ int signal_detect(v27ter_rx_state_t *s, int16_t amp) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) +SPAN_DECLARE(int) v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) { int i; int step; @@ -978,7 +978,7 @@ SPAN_DECLARE_NONSTD(int) v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], in } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v27ter_rx_fillin(v27ter_rx_state_t *s, int len) +SPAN_DECLARE(int) v27ter_rx_fillin(v27ter_rx_state_t *s, int len) { int i; diff --git a/libs/spandsp/src/v27ter_tx.c b/libs/spandsp/src/v27ter_tx.c index f6b69917bb..e0f2aaf1af 100644 --- a/libs/spandsp/src/v27ter_tx.c +++ b/libs/spandsp/src/v27ter_tx.c @@ -241,7 +241,7 @@ static complexf_t getbaud(v27ter_tx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len) +SPAN_DECLARE(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len) { #if defined(SPANDSP_USE_FIXED_POINT) complexi16_t v; diff --git a/libs/spandsp/src/v29rx.c b/libs/spandsp/src/v29rx.c index da1ef0c909..4bed319246 100644 --- a/libs/spandsp/src/v29rx.c +++ b/libs/spandsp/src/v29rx.c @@ -910,7 +910,7 @@ static __inline__ int signal_detect(v29_rx_state_t *s, int16_t amp) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) +SPAN_DECLARE(int) v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) { int i; int step; @@ -1026,7 +1026,7 @@ SPAN_DECLARE_NONSTD(int) v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v29_rx_fillin(v29_rx_state_t *s, int len) +SPAN_DECLARE(int) v29_rx_fillin(v29_rx_state_t *s, int len) { int i; diff --git a/libs/spandsp/src/v29tx.c b/libs/spandsp/src/v29tx.c index c36027701d..bef54364e8 100644 --- a/libs/spandsp/src/v29tx.c +++ b/libs/spandsp/src/v29tx.c @@ -212,7 +212,7 @@ static __inline__ complexf_t getbaud(v29_tx_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v29_tx(v29_tx_state_t *s, int16_t amp[], int len) +SPAN_DECLARE(int) v29_tx(v29_tx_state_t *s, int16_t amp[], int len) { #if defined(SPANDSP_USE_FIXED_POINT) complexi16_t v; diff --git a/libs/spandsp/src/v42.c b/libs/spandsp/src/v42.c index 44e6bd01d9..4dac118f65 100644 --- a/libs/spandsp/src/v42.c +++ b/libs/spandsp/src/v42.c @@ -1065,7 +1065,7 @@ static void lapm_hdlc_underflow(void *user_data) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(void) lapm_receive(void *user_data, const uint8_t *frame, int len, int ok) +SPAN_DECLARE(void) lapm_receive(void *user_data, const uint8_t *frame, int len, int ok) { lapm_state_t *s; v42_state_t *ss; diff --git a/libs/spandsp/src/v8.c b/libs/spandsp/src/v8.c index 40cc6feac1..4c5dd43244 100644 --- a/libs/spandsp/src/v8.c +++ b/libs/spandsp/src/v8.c @@ -734,7 +734,7 @@ static void send_cm_jm(v8_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len) +SPAN_DECLARE(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len) { int len; @@ -852,7 +852,7 @@ static void handle_modem_connect_tone(v8_state_t *s, int tone) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len) +SPAN_DECLARE(int) v8_rx(v8_state_t *s, const int16_t *amp, int len) { int residual_samples; int tone; diff --git a/libs/spandsp/tests/Makefile.am b/libs/spandsp/tests/Makefile.am index 47ee06aec3..55d84e4d99 100644 --- a/libs/spandsp/tests/Makefile.am +++ b/libs/spandsp/tests/Makefile.am @@ -225,7 +225,7 @@ echo_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspand fax_decode_SOURCES = fax_decode.c fax_decode_LDADD = $(LIBDIR) -lspandsp -fax_tests_SOURCES = fax_tests.c fax_utils.c media_monitor.cpp +fax_tests_SOURCES = fax_tests.c fax_utils.c media_monitor.cpp fax_tester.c fax_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp fsk_tests_SOURCES = fsk_tests.c diff --git a/libs/spandsp/tests/fax_tester.c b/libs/spandsp/tests/fax_tester.c index fb5dcc1ac1..8885957972 100644 --- a/libs/spandsp/tests/fax_tester.c +++ b/libs/spandsp/tests/fax_tester.c @@ -85,7 +85,7 @@ struct xml_node_parms_s xmlChar *compression; }; -static struct +struct { const char *tag; int code; @@ -162,16 +162,278 @@ static void timer_update(faxtester_state_t *s, int len) if (s->timer > s->timeout) { s->timeout = 0x7FFFFFFFFFFFFFFFLL; - if (s->front_end_step_timeout_handler) - s->front_end_step_timeout_handler(s, s->front_end_step_timeout_user_data); + span_log(&s->logging, SPAN_LOG_FLOW, "FAX tester step timed out\n"); + printf("Test failed\n"); + exit(2); } } /*- End of function --------------------------------------------------------*/ static void front_end_step_complete(faxtester_state_t *s) { - if (s->front_end_step_complete_handler) - s->front_end_step_complete_handler(s, s->front_end_step_complete_user_data); + while (faxtester_next_step(s) == 0) + ; + /*endwhile*/ +} +/*- End of function --------------------------------------------------------*/ + +static int faxtester_phase_b_handler(void *user_data, int result) +{ + int ch; + int status; + faxtester_state_t *s; + const char *u; + + s = (faxtester_state_t *) user_data; + ch = s->far_tag; + status = T30_ERR_OK; + if ((u = t30_get_rx_ident(s->far_t30))) + { + printf("%c: Phase B: remote ident '%s'\n", ch, u); + if (s->expected_rx_info.ident[0] && strcmp(s->expected_rx_info.ident, u)) + { + printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", ch, s->expected_rx_info.ident); + status = T30_ERR_IDENT_UNACCEPTABLE; + } + } + else + { + if (s->expected_rx_info.ident[0]) + { + printf("%c: Phase B: remote ident missing!\n", ch); + status = T30_ERR_IDENT_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_sub_address(s->far_t30))) + { + printf("%c: Phase B: remote sub-address '%s'\n", ch, u); + if (s->expected_rx_info.sub_address[0] && strcmp(s->expected_rx_info.sub_address, u)) + { + printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", ch, s->expected_rx_info.sub_address); + status = T30_ERR_SUB_UNACCEPTABLE; + } + } + else + { + if (s->expected_rx_info.sub_address[0]) + { + printf("%c: Phase B: remote sub-address missing!\n", ch); + status = T30_ERR_SUB_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_polled_sub_address(s->far_t30))) + { + printf("%c: Phase B: remote polled sub-address '%s'\n", ch, u); + if (s->expected_rx_info.polled_sub_address[0] && strcmp(s->expected_rx_info.polled_sub_address, u)) + { + printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", ch, s->expected_rx_info.polled_sub_address); + status = T30_ERR_PSA_UNACCEPTABLE; + } + } + else + { + if (s->expected_rx_info.polled_sub_address[0]) + { + printf("%c: Phase B: remote polled sub-address missing!\n", ch); + status = T30_ERR_PSA_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_selective_polling_address(s->far_t30))) + { + printf("%c: Phase B: remote selective polling address '%s'\n", ch, u); + if (s->expected_rx_info.selective_polling_address[0] && strcmp(s->expected_rx_info.selective_polling_address, u)) + { + printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", ch, s->expected_rx_info.selective_polling_address); + status = T30_ERR_SEP_UNACCEPTABLE; + } + } + else + { + if (s->expected_rx_info.selective_polling_address[0]) + { + printf("%c: Phase B: remote selective polling address missing!\n", ch); + status = T30_ERR_SEP_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_sender_ident(s->far_t30))) + { + printf("%c: Phase B: remote sender ident '%s'\n", ch, u); + if (s->expected_rx_info.sender_ident[0] && strcmp(s->expected_rx_info.sender_ident, u)) + { + printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", ch, s->expected_rx_info.sender_ident); + status = T30_ERR_SID_UNACCEPTABLE; + } + } + else + { + if (s->expected_rx_info.sender_ident[0]) + { + printf("%c: Phase B: remote sender ident missing!\n", ch); + status = T30_ERR_SID_UNACCEPTABLE; + } + } + if ((u = t30_get_rx_password(s->far_t30))) + { + printf("%c: Phase B: remote password '%s'\n", ch, u); + if (s->expected_rx_info.password[0] && strcmp(s->expected_rx_info.password, u)) + { + printf("%c: Phase B: remote password incorrect! - expected '%s'\n", ch, s->expected_rx_info.password); + status = T30_ERR_PWD_UNACCEPTABLE; + } + } + else + { + if (s->expected_rx_info.password[0]) + { + printf("%c: Phase B: remote password missing!\n", ch); + status = T30_ERR_PWD_UNACCEPTABLE; + } + } + printf("%c: Phase B handler on channel %c - (0x%X) %s\n", ch, ch, result, t30_frametype(result)); + return status; +} +/*- End of function --------------------------------------------------------*/ + +static int faxtester_phase_d_handler(void *user_data, int result) +{ + int i; + int ch; + faxtester_state_t *s; + char tag[20]; + + s = (faxtester_state_t *) user_data; + ch = s->far_tag; + i = 0; + snprintf(tag, sizeof(tag), "%c: Phase D", ch); + printf("%c: Phase D handler on channel %c - (0x%X) %s\n", ch, ch, result, t30_frametype(result)); + fax_log_page_transfer_statistics(s->far_t30, tag); + fax_log_tx_parameters(s->far_t30, tag); + fax_log_rx_parameters(s->far_t30, tag); + + if (s->use_receiver_not_ready) + t30_set_receiver_not_ready(s->far_t30, 3); + + if (s->test_local_interrupt) + { + if (i == 0) + { + printf("%c: Initiating interrupt request\n", ch); + t30_local_interrupt_request(s->far_t30, true); + } + else + { + switch (result) + { + case T30_PIP: + case T30_PRI_MPS: + case T30_PRI_EOM: + case T30_PRI_EOP: + printf("%c: Accepting interrupt request\n", ch); + t30_local_interrupt_request(s->far_t30, true); + break; + case T30_PIN: + break; + } + } + } + return T30_ERR_OK; +} +/*- End of function --------------------------------------------------------*/ + +static void faxtester_phase_e_handler(void *user_data, int result) +{ + int ch; + faxtester_state_t *s; + char tag[20]; + + s = (faxtester_state_t *) user_data; + ch = s->far_tag; + snprintf(tag, sizeof(tag), "%c: Phase E", ch); + printf("%c: Phase E handler on channel %c - (%d) %s\n", ch, ch, result, t30_completion_code_to_str(result)); + fax_log_final_transfer_statistics(s->far_t30, tag); + fax_log_tx_parameters(s->far_t30, tag); + fax_log_rx_parameters(s->far_t30, tag); +} +/*- End of function --------------------------------------------------------*/ + +static void t30_real_time_frame_handler(void *user_data, + bool incoming, + const uint8_t *msg, + int len) +{ + if (msg == NULL) + { + } + else + { + fprintf(stderr, + "T.30: Real time frame handler - %s, %s, length = %d\n", + (incoming) ? "line->T.30" : "T.30->line", + t30_frametype(msg[2]), + len); + } +} +/*- End of function --------------------------------------------------------*/ + +static int faxtester_document_handler(void *user_data, int event) +{ + int ch; + faxtester_state_t *s; + t30_state_t *t; + + s = (faxtester_state_t *) user_data; + ch = s->far_tag; + t = s->far_t30; + fprintf(stderr, "%c: Document handler on channel %c - event %d\n", ch, ch, event); + if (s->next_tx_file[0]) + { + t30_set_tx_file(t, s->next_tx_file, -1, -1); + s->next_tx_file[0] = '\0'; + return true; + } + return false; +} +/*- End of function --------------------------------------------------------*/ + +static void faxtester_real_time_frame_handler(faxtester_state_t *s, + int direction, + const uint8_t *msg, + int len) +{ + if (msg == NULL) + { + while (faxtester_next_step(s) == 0) + ; + /*endwhile*/ + } + else + { + fprintf(stderr, + "TST: Real time frame handler - %s, %s, length = %d\n", + (direction) ? "line->tester" : "tester->line", + t30_frametype(msg[2]), + len); + if (direction && msg[1] == s->awaited[1]) + { + if ((s->awaited_len >= 0 && len != abs(s->awaited_len)) + || + (s->awaited_len < 0 && len < abs(s->awaited_len)) + || + memcmp(msg, s->awaited, abs(s->awaited_len)) != 0) + { + span_log_buf(&s->logging, SPAN_LOG_FLOW, "Expected", s->awaited, abs(s->awaited_len)); + span_log_buf(&s->logging, SPAN_LOG_FLOW, "Received", msg, len); + printf("Test failed\n"); + exit(2); + } + } + if (msg[1] == s->awaited[1]) + { + while (faxtester_next_step(s) == 0) + ; + /*endwhile*/ + } + } } /*- End of function --------------------------------------------------------*/ @@ -295,29 +557,17 @@ static int non_ecm_get_bit(void *user_data) } /*- End of function --------------------------------------------------------*/ -void faxtester_set_non_ecm_image_buffer(faxtester_state_t *s, const uint8_t *buf, int len) +static void faxtester_set_ecm_image_buffer(faxtester_state_t *s, int block, int frame_size, int crc_hit) { - s->image_ptr = 0; - s->image_bit_ptr = 8; - s->image_len = len; - s->image_buffer = buf; -} -/*- End of function --------------------------------------------------------*/ - -void faxtester_set_ecm_image_buffer(faxtester_state_t *s, const uint8_t *buf, int len, int block, int frame_size, int crc_hit) -{ - int start; - - start = 256*frame_size*block; - if (len > start + 256*frame_size) - len = start + 256*frame_size; + s->image_ptr = 256*frame_size*block; + if (s->image_len > s->image_ptr + 256*frame_size) + s->image_len = s->image_ptr + 256*frame_size; s->ecm_frame_size = frame_size; - s->image_ptr = start; s->image_bit_ptr = 8; - s->image_len = len; - s->image_buffer = buf; s->corrupt_crc = crc_hit; + s->image_buffer = s->image; + /* Send the first frame */ hdlc_underflow_handler(s); } @@ -343,10 +593,7 @@ static void non_ecm_rx_status(void *user_data, int status) break; case SIG_STATUS_CARRIER_DOWN: if (s->modems.rx_trained) - { - if (s->real_time_frame_handler) - s->real_time_frame_handler(s, s->real_time_frame_user_data, true, NULL, 0); - } + faxtester_real_time_frame_handler(s, true, NULL, 0); s->modems.rx_signal_present = false; s->modems.rx_trained = false; break; @@ -400,8 +647,7 @@ static void hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) return; } s = (faxtester_state_t *) user_data; - if (s->real_time_frame_handler) - s->real_time_frame_handler(s, s->real_time_frame_user_data, true, msg, len); + faxtester_real_time_frame_handler(s, true, msg, len); } /*- End of function --------------------------------------------------------*/ @@ -546,7 +792,7 @@ void faxtester_set_tx_type(void *user_data, int type, int bit_rate, int short_tr break; case T30_MODEM_CED: case T30_MODEM_CNG: - tone = (type == T30_MODEM_CED) ? MODEM_CONNECT_TONES_FAX_CED : MODEM_CONNECT_TONES_FAX_CNG; + tone = (type == T30_MODEM_CED) ? FAX_MODEM_CED_TONE_TX : FAX_MODEM_CNG_TONE_TX; fax_modems_start_slow_modem(t, tone); s->transmit = true; break; @@ -613,34 +859,996 @@ void faxtester_set_tep_mode(faxtester_state_t *s, int use_tep) } /*- End of function --------------------------------------------------------*/ -void faxtester_set_real_time_frame_handler(faxtester_state_t *s, faxtester_real_time_frame_handler_t handler, void *user_data) +static void corrupt_image(faxtester_state_t *s, const char *bad_rows) { - s->real_time_frame_handler = handler; - s->real_time_frame_user_data = user_data; + int i; + int j; + int k; + uint32_t bits; + uint32_t bitsx; + int list[1000]; + int x; + int row; + const char *t; + + /* Form the list of rows to be hit */ + x = 0; + t = bad_rows; + while (*t) + { + while (isspace((int) *t)) + t++; + if (sscanf(t, "%d", &list[x]) < 1) + break; + x++; + while (isdigit((int) *t)) + t++; + if (*t == ',') + t++; + } + + /* Go through the image, and corrupt the first bit of every listed row */ + bits = 0x7FF; + bitsx = 0x7FF; + row = 0; + for (i = 0; i < s->image_len; i++) + { + bits ^= (s->image[i] << 11); + bitsx ^= (s->image[i] << 11); + for (j = 0; j < 8; j++) + { + if ((bits & 0xFFF) == 0x800) + { + /* We are at an EOL. Is this row in the list of rows to be corrupted? */ + row++; + for (k = 0; k < x; k++) + { + if (list[k] == row) + { + /* Corrupt this row. TSB85 says to hit the first bit after the EOL */ + bitsx ^= 0x1000; + } + } + } + bits >>= 1; + bitsx >>= 1; + } + s->image[i] = (bitsx >> 3) & 0xFF; + } + span_log(&s->logging, SPAN_LOG_FLOW, "%d rows found. %d corrupted\n", row, x); } /*- End of function --------------------------------------------------------*/ -void faxtester_set_front_end_step_complete_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data) +static int string_to_msg(uint8_t msg[], uint8_t mask[], const char buf[]) { - s->front_end_step_complete_handler = handler; - s->front_end_step_complete_user_data = user_data; + int i; + int x; + const char *t; + + msg[0] = 0; + mask[0] = 0xFF; + i = 0; + t = (char *) buf; + while (*t) + { + /* Skip white space */ + while (isspace((int) *t)) + t++; + /* If we find ... we allow arbitrary additional info beyond this point in the message */ + if (t[0] == '.' && t[1] == '.' && t[2] == '.') + { + return -i; + } + else if (isxdigit((int) *t)) + { + for ( ; isxdigit((int) *t); t++) + { + x = *t; + if (x >= 'a') + x -= 0x20; + if (x >= 'A') + x -= ('A' - 10); + else + x -= '0'; + msg[i] = (msg[i] << 4) | x; + } + mask[i] = 0xFF; + if (*t == '/') + { + /* There is a mask following the byte */ + mask[i] = 0; + for (t++; isxdigit((int) *t); t++) + { + x = *t; + if (x >= 'a') + x -= 0x20; + if (x >= 'A') + x -= ('A' - 10); + else + x -= '0'; + mask[i] = (mask[i] << 4) | x; + } + } + if (*t && !isspace((int) *t)) + { + /* Bad string */ + return 0; + } + i++; + } + } + return i; } /*- End of function --------------------------------------------------------*/ -void faxtester_set_front_end_step_timeout_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data) +void faxtester_set_flush_handler(faxtester_state_t *s, faxtester_flush_handler_t handler, void *user_data) { - s->front_end_step_timeout_handler = handler; - s->front_end_step_timeout_user_data = user_data; + s->flush_handler = handler; + s->flush_user_data = user_data; } /*- End of function --------------------------------------------------------*/ -faxtester_state_t *faxtester_init(faxtester_state_t *s, int calling_party) +static void fax_prepare(faxtester_state_t *s) +{ + if (s->far_fax) + { + fax_set_transmit_on_idle(s->far_fax, true); + fax_set_tep_mode(s->far_fax, true); + } +#if 0 + t30_set_tx_ident(s->far_t30, "1234567890"); + t30_set_tx_sub_address(s->far_t30, "Sub-address"); + t30_set_tx_sender_ident(s->far_t30, "Sender ID"); + t30_set_tx_password(s->far_t30, "Password"); + t30_set_tx_polled_sub_address(s->far_t30, "Polled sub-address"); + t30_set_tx_selective_polling_address(s->far_t30, "Sel polling address"); +#endif + t30_set_tx_nsf(s->far_t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSF\x00", 16); + //t30_set_tx_nss(s->far_t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSS\x00", 16); + t30_set_tx_nsc(s->far_t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSC\x00", 16); + t30_set_ecm_capability(s->far_t30, true); + t30_set_supported_t30_features(s->far_t30, + T30_SUPPORT_IDENTIFICATION + | T30_SUPPORT_SELECTIVE_POLLING + | T30_SUPPORT_SUB_ADDRESSING); + t30_set_supported_image_sizes(s->far_t30, + T4_SUPPORT_WIDTH_215MM + | T4_SUPPORT_WIDTH_255MM + | T4_SUPPORT_WIDTH_303MM + | T4_SUPPORT_LENGTH_US_LETTER + | T4_SUPPORT_LENGTH_US_LEGAL + | T4_SUPPORT_LENGTH_UNLIMITED); + t30_set_supported_bilevel_resolutions(s->far_t30, + T4_RESOLUTION_R8_STANDARD + | T4_RESOLUTION_R8_FINE + | T4_RESOLUTION_R8_SUPERFINE + | T4_RESOLUTION_R16_SUPERFINE + | T4_RESOLUTION_100_100 + | T4_RESOLUTION_200_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_200_400 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_300_600 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_400_800 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_600_1200 + | T4_RESOLUTION_1200_1200); + t30_set_supported_colour_resolutions(s->far_t30, 0); + t30_set_supported_modems(s->far_t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17); + t30_set_supported_compressions(s->far_t30, T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6); + t30_set_phase_b_handler(s->far_t30, faxtester_phase_b_handler, (void *) s); + t30_set_phase_d_handler(s->far_t30, faxtester_phase_d_handler, (void *) s); + t30_set_phase_e_handler(s->far_t30, faxtester_phase_e_handler, (void *) s); + t30_set_real_time_frame_handler(s->far_t30, t30_real_time_frame_handler, (void *) s); + t30_set_document_handler(s->far_t30, faxtester_document_handler, (void *) s); +} +/*- End of function --------------------------------------------------------*/ + +static void get_node_parms(struct xml_node_parms_s *parms, xmlNodePtr node) +{ + parms->dir = xmlGetProp(node, (const xmlChar *) "dir"); + parms->type = xmlGetProp(node, (const xmlChar *) "type"); + parms->modem = xmlGetProp(node, (const xmlChar *) "modem"); + parms->value = xmlGetProp(node, (const xmlChar *) "value"); + parms->tag = xmlGetProp(node, (const xmlChar *) "tag"); + parms->bad_rows = xmlGetProp(node, (const xmlChar *) "bad_rows"); + parms->crc_error = xmlGetProp(node, (const xmlChar *) "crc_error"); + parms->pattern = xmlGetProp(node, (const xmlChar *) "pattern"); + parms->timein = xmlGetProp(node, (const xmlChar *) "timein"); + parms->timeout = xmlGetProp(node, (const xmlChar *) "timeout"); + parms->min_bits = xmlGetProp(node, (const xmlChar *) "min_bits"); + parms->frame_size = xmlGetProp(node, (const xmlChar *) "frame_size"); + parms->block = xmlGetProp(node, (const xmlChar *) "block"); + parms->compression = xmlGetProp(node, (const xmlChar *) "compression"); +} +/*- End of function --------------------------------------------------------*/ + +static void free_node_parms(struct xml_node_parms_s *parms) +{ + if (parms->dir) + xmlFree(parms->dir); + if (parms->type) + xmlFree(parms->type); + if (parms->modem) + xmlFree(parms->modem); + if (parms->value) + xmlFree(parms->value); + if (parms->tag) + xmlFree(parms->tag); + if (parms->bad_rows) + xmlFree(parms->bad_rows); + if (parms->crc_error) + xmlFree(parms->crc_error); + if (parms->pattern) + xmlFree(parms->pattern); + if (parms->timein) + xmlFree(parms->timein); + if (parms->timeout) + xmlFree(parms->timeout); + if (parms->min_bits) + xmlFree(parms->min_bits); + if (parms->frame_size) + xmlFree(parms->frame_size); + if (parms->block) + xmlFree(parms->block); + if (parms->compression) + xmlFree(parms->compression); +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) faxtester_next_step(faxtester_state_t *s) +{ + int delay; + int flags; + struct xml_node_parms_s parms; + uint8_t buf[1000]; + uint8_t mask[1000]; + char path[1024]; + int i; + int j; + int hdlc; + int short_train; + int min_row_bits; + int ecm_frame_size; + int ecm_block; + int compression_type; + xmlChar *min; + xmlChar *max; + t4_tx_state_t t4_tx_state; + t30_stats_t t30_stats; + + s->test_for_call_clear = false; + if (s->cur == NULL) + { + if (!s->final_delayed) + { + /* Add a bit of waiting at the end, to ensure everything gets flushed through, + any timers can expire, etc. */ + faxtester_set_timeout(s, -1); + faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); + faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, 120000, false); + s->final_delayed = true; + return 1; + } + /* Finished */ + printf("Test passed\n"); + exit(0); + } + for (;;) + { + if (s->cur == NULL) + { + if (s->repeat_parent == NULL) + { + /* Finished */ + printf("Test passed\n"); + exit(0); + } + if (++s->repeat_count > s->repeat_max) + { + /* Finished */ + printf("Too many repeats\n"); + printf("Test failed\n"); + exit(0); + } + if (s->repeat_count < s->repeat_min) + { + s->cur = s->repeat_start; + } + else + { + s->cur = s->repeat_parent->next; + s->repeat_parent = NULL; + } + } + if (xmlStrcmp(s->cur->name, (const xmlChar *) "step") == 0) + { + break; + } + if (s->repeat_parent == NULL && xmlStrcmp(s->cur->name, (const xmlChar *) "repeat") == 0) + { + min = xmlGetProp(s->cur, (const xmlChar *) "min"); + max = xmlGetProp(s->cur, (const xmlChar *) "max"); + s->repeat_min = min ? atoi((const char *) min) : 0; + s->repeat_max = max ? atoi((const char *) max) : INT_MAX; + s->repeat_count = 0; + if (min) + xmlFree(min); + if (max) + xmlFree(max); + if (s->repeat_min > 0) + { + s->repeat_parent = s->cur; + s->repeat_start = + s->cur = s->cur->xmlChildrenNode; + continue; + } + } + s->cur = s->cur->next; + } + + get_node_parms(&parms, s->cur); + + s->cur = s->cur->next; + + span_log(&s->logging, + SPAN_LOG_FLOW, + "Dir - %s, type - %s, modem - %s, value - %s, timein - %s, timeout - %s, tag - %s\n", + (parms.dir) ? (const char *) parms.dir : " ", + (parms.type) ? (const char *) parms.type : "", + (parms.modem) ? (const char *) parms.modem : "", + (parms.value) ? (const char *) parms.value : "", + (parms.timein) ? (const char *) parms.timein : "", + (parms.timeout) ? (const char *) parms.timeout : "", + (parms.tag) ? (const char *) parms.tag : ""); + if (parms.type == NULL) + { + free_node_parms(&parms); + return 1; + } + s->timein_x = (parms.timein) ? atoi((const char *) parms.timein) : -1; + s->timeout_x = (parms.timeout) ? atoi((const char *) parms.timeout) : -1; + + if (parms.dir && strcasecmp((const char *) parms.dir, "R") == 0) + { + /* Receive always has a timeout applied. */ + if (s->timeout_x < 0) + s->timeout_x = 7000; + faxtester_set_timeout(s, s->timeout_x); + if (parms.modem) + { + hdlc = (strcasecmp((const char *) parms.type, "PREAMBLE") == 0); + short_train = (strcasecmp((const char *) parms.type, "TCF") != 0); + faxtester_set_tx_type(s, T30_MODEM_NONE, 0, false, false); + if (strcasecmp((const char *) parms.modem, "V.21") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V21, 300, false, true); + } + else if (strcasecmp((const char *) parms.modem, "V.17/14400") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V17, 14400, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.17/12000") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V17, 12000, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.17/9600") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V17, 9600, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.17/7200") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V17, 7200, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.29/9600") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V29, 9600, false, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.29/7200") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V29, 7200, false, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.27ter/4800") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V27TER, 4800, false, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.27ter/2400") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_V27TER, 2400, false, hdlc); + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n"); + } + } + + if (strcasecmp((const char *) parms.type, "SET") == 0) + { + if (strcasecmp((const char *) parms.tag, "IDENT") == 0) + strcpy(s->expected_rx_info.ident, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "SUB") == 0) + strcpy(s->expected_rx_info.sub_address, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "SEP") == 0) + strcpy(s->expected_rx_info.selective_polling_address, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "PSA") == 0) + strcpy(s->expected_rx_info.polled_sub_address, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "SID") == 0) + strcpy(s->expected_rx_info.sender_ident, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "PWD") == 0) + strcpy(s->expected_rx_info.password, (const char *) parms.value); + free_node_parms(&parms); + return 0; + } + else if (strcasecmp((const char *) parms.type, "CNG") == 0) + { + /* Look for CNG */ + faxtester_set_rx_type(s, T30_MODEM_CNG, 0, false, false); + faxtester_set_tx_type(s, T30_MODEM_NONE, 0, false, false); + } + else if (strcasecmp((const char *) parms.type, "CED") == 0) + { + /* Look for CED */ + faxtester_set_rx_type(s, T30_MODEM_CED, 0, false, false); + faxtester_set_tx_type(s, T30_MODEM_NONE, 0, false, false); + } + else if (strcasecmp((const char *) parms.type, "HDLC") == 0) + { + i = string_to_msg(buf, mask, (const char *) parms.value); + bit_reverse(s->awaited, buf, abs(i)); + s->awaited_len = i; + } + else if (strcasecmp((const char *) parms.type, "TCF") == 0) + { + } + else if (strcasecmp((const char *) parms.type, "MSG") == 0) + { + } + else if (strcasecmp((const char *) parms.type, "PP") == 0) + { + } + else if (strcasecmp((const char *) parms.type, "SILENCE") == 0) + { + faxtest_set_rx_silence(s); + } + else if (strcasecmp((const char *) parms.type, "CLEAR") == 0) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Far end should drop the call\n"); + s->test_for_call_clear = true; + s->call_clear_timer = 0; + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised type '%s'\n", (const char *) parms.type); + free_node_parms(&parms); + return 0; + } + } + else + { + faxtester_set_timeout(s, s->timeout_x); + if (parms.modem) + { + hdlc = (strcasecmp((const char *) parms.type, "PREAMBLE") == 0); + short_train = (strcasecmp((const char *) parms.type, "TCF") != 0); + faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); + if (strcasecmp((const char *) parms.modem, "V.21") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V21, 300, false, true); + } + else if (strcasecmp((const char *) parms.modem, "V.17/14400") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V17, 14400, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.17/12000") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V17, 12000, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.17/9600") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V17, 9600, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.17/7200") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V17, 7200, short_train, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.29/9600") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V29, 9600, false, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.29/7200") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V29, 7200, false, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.27ter/4800") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V27TER, 4800, false, hdlc); + } + else if (strcasecmp((const char *) parms.modem, "V.27ter/2400") == 0) + { + faxtester_set_tx_type(s, T30_MODEM_V27TER, 2400, false, hdlc); + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n"); + } + } + + if (strcasecmp((const char *) parms.type, "SET") == 0) + { + if (strcasecmp((const char *) parms.tag, "IDENT") == 0) + t30_set_tx_ident(s->far_t30, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "SUB") == 0) + t30_set_tx_sub_address(s->far_t30, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "SEP") == 0) + t30_set_tx_selective_polling_address(s->far_t30, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "PSA") == 0) + t30_set_tx_polled_sub_address(s->far_t30, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "SID") == 0) + t30_set_tx_sender_ident(s->far_t30, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "PWD") == 0) + t30_set_tx_password(s->far_t30, (const char *) parms.value); + else if (strcasecmp((const char *) parms.tag, "RXFILE") == 0) + { + if (parms.value) + t30_set_rx_file(s->far_t30, (const char *) parms.value, -1); + else + t30_set_rx_file(s->far_t30, output_tiff_file_name, -1); + } + else if (strcasecmp((const char *) parms.tag, "TXFILE") == 0) + { + sprintf(s->next_tx_file, "%s/%s", s->image_path, (const char *) parms.value); + printf("Push '%s'\n", s->next_tx_file); + } + free_node_parms(&parms); + return 0; + } + else if (strcasecmp((const char *) parms.type, "CALL") == 0) + { + if (s->far_fax) + fax_restart(s->far_fax, false); + else + t38_terminal_restart(s->far_t38, false); + fax_prepare(s); + s->next_tx_file[0] = '\0'; + t30_set_rx_file(s->far_t30, output_tiff_file_name, -1); + /* Avoid libtiff 3.8.2 and earlier bug on complex 2D lines. */ + t30_set_supported_output_compressions(s->far_t30, T4_COMPRESSION_T4_1D); + if (parms.value) + { + sprintf(path, "%s/%s", s->image_path, (const char *) parms.value); + t30_set_tx_file(s->far_t30, path, -1, -1); + } + free_node_parms(&parms); + return 0; + } + else if (strcasecmp((const char *) parms.type, "ANSWER") == 0) + { + if (s->far_fax) + fax_restart(s->far_fax, true); + else + t38_terminal_restart(s->far_t38, true); + fax_prepare(s); + s->next_tx_file[0] = '\0'; + /* Avoid libtiff 3.8.2 and earlier bug on complex 2D lines. */ + t30_set_supported_output_compressions(s->far_t30, T4_COMPRESSION_T4_1D); + if (parms.value) + { + sprintf(path, "%s/%s", s->image_path, (const char *) parms.value); + t30_set_tx_file(s->far_t30, path, -1, -1); + } + free_node_parms(&parms); + return 0; + } + else if (strcasecmp((const char *) parms.type, "CNG") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); + faxtester_set_tx_type(s, T30_MODEM_CNG, 0, false, false); + } + else if (strcasecmp((const char *) parms.type, "CED") == 0) + { + faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); + faxtester_set_tx_type(s, T30_MODEM_CED, 0, false, false); + } + else if (strcasecmp((const char *) parms.type, "WAIT") == 0) + { + delay = (parms.value) ? atoi((const char *) parms.value) : 1; + faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); + faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, delay, false); + } + else if (strcasecmp((const char *) parms.type, "PREAMBLE") == 0) + { + flags = (parms.value) ? atoi((const char *) parms.value) : 37; + faxtester_send_hdlc_flags(s, flags); + } + else if (strcasecmp((const char *) parms.type, "POSTAMBLE") == 0) + { + flags = (parms.value) ? atoi((const char *) parms.value) : 5; + faxtester_send_hdlc_flags(s, flags); + } + else if (strcasecmp((const char *) parms.type, "HDLC") == 0) + { + i = string_to_msg(buf, mask, (const char *) parms.value); + bit_reverse(buf, buf, abs(i)); + if (parms.crc_error && strcasecmp((const char *) parms.crc_error, "0") == 0) + faxtester_send_hdlc_msg(s, buf, abs(i), false); + else + faxtester_send_hdlc_msg(s, buf, abs(i), true); + } + else if (strcasecmp((const char *) parms.type, "TCF") == 0) + { + i = (parms.value) ? atoi((const char *) parms.value) : 450; + if (parms.pattern) + { + /* TODO: implement proper patterns */ + j = atoi((const char *) parms.pattern); + memset(s->image, 0x55, j); + if (i > j) + memset(s->image + j, 0, i - j); + } + else + { + memset(s->image, 0, i); + } + s->image_ptr = 0; + s->image_bit_ptr = 8; + s->image_buffer = s->image; + s->image_len = i; + } + else if (strcasecmp((const char *) parms.type, "MSG") == 0) + { + /* A non-ECM page */ + min_row_bits = (parms.min_bits) ? atoi((const char *) parms.min_bits) : 0; + sprintf(path, "%s/%s", s->image_path, (const char *) parms.value); + if (t4_tx_init(&t4_tx_state, path, -1, -1) == NULL) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Failed to init T.4 send\n"); + printf("Test failed\n"); + exit(2); + } + t4_tx_set_header_info(&t4_tx_state, NULL); + compression_type = T4_COMPRESSION_T4_1D; + if (parms.compression) + { + if (strcasecmp((const char *) parms.compression, "T.4 1D") == 0) + compression_type = T4_COMPRESSION_T4_1D; + else if (strcasecmp((const char *) parms.compression, "T.4 2D") == 0) + compression_type = T4_COMPRESSION_T4_2D; + else if (strcasecmp((const char *) parms.compression, "T.6") == 0) + compression_type = T4_COMPRESSION_T6; + else if (strcasecmp((const char *) parms.compression, "T.85") == 0) + compression_type = T4_COMPRESSION_T85; + } + if (t4_tx_set_tx_image_format(&t4_tx_state, + compression_type, + T4_SUPPORT_WIDTH_215MM + | T4_SUPPORT_LENGTH_US_LETTER + | T4_SUPPORT_LENGTH_US_LEGAL + | T4_SUPPORT_LENGTH_UNLIMITED, + T4_RESOLUTION_R8_STANDARD + | T4_RESOLUTION_R8_FINE + | T4_RESOLUTION_R8_SUPERFINE + | T4_RESOLUTION_R16_SUPERFINE + | T4_RESOLUTION_200_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_200_400 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_300_600 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_400_800 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_600_1200 + | T4_RESOLUTION_1200_1200, + T4_RESOLUTION_100_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_1200_1200) < 0) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Failed to set T.4 compression\n"); + printf("Test failed\n"); + exit(2); + } + t4_tx_set_min_bits_per_row(&t4_tx_state, min_row_bits); + if (t4_tx_start_page(&t4_tx_state)) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Failed to start T.4 send\n"); + printf("Test failed\n"); + exit(2); + } + s->image_len = t4_tx_get(&t4_tx_state, s->image, sizeof(s->image)); + if (parms.bad_rows) + { + span_log(&s->logging, SPAN_LOG_FLOW, "We need to corrupt the image\n"); + corrupt_image(s, (const char *) parms.bad_rows); + } + t4_tx_release(&t4_tx_state); + span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM image is %d bytes (min row bits %d)\n", s->image_len, min_row_bits); + s->image_ptr = 0; + s->image_bit_ptr = 8; + s->image_buffer = s->image; + } + else if (strcasecmp((const char *) parms.type, "PP") == 0) + { + min_row_bits = (parms.min_bits) ? atoi((const char *) parms.min_bits) : 0; + ecm_block = (parms.block) ? atoi((const char *) parms.block) : 0; + ecm_frame_size = (parms.frame_size) ? atoi((const char *) parms.frame_size) : 64; + i = (parms.crc_error) ? atoi((const char *) parms.crc_error) : -1; + sprintf(path, "%s/%s", s->image_path, (const char *) parms.value); + if (t4_tx_init(&t4_tx_state, path, -1, -1) == NULL) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Failed to init T.4 send\n"); + printf("Test failed\n"); + exit(2); + } + t4_tx_set_header_info(&t4_tx_state, NULL); + compression_type = T4_COMPRESSION_T4_1D; + if (parms.compression) + { + if (strcasecmp((const char *) parms.compression, "T.4 1D") == 0) + compression_type = T4_COMPRESSION_T4_1D; + else if (strcasecmp((const char *) parms.compression, "T.4 2D") == 0) + compression_type = T4_COMPRESSION_T4_2D; + else if (strcasecmp((const char *) parms.compression, "T.6") == 0) + compression_type = T4_COMPRESSION_T6; + else if (strcasecmp((const char *) parms.compression, "T.85") == 0) + compression_type = T4_COMPRESSION_T85; + } + if (t4_tx_set_tx_image_format(&t4_tx_state, + compression_type, + T4_SUPPORT_WIDTH_215MM + | T4_SUPPORT_LENGTH_US_LETTER + | T4_SUPPORT_LENGTH_US_LEGAL + | T4_SUPPORT_LENGTH_UNLIMITED, + T4_RESOLUTION_R8_STANDARD + | T4_RESOLUTION_R8_FINE + | T4_RESOLUTION_R8_SUPERFINE + | T4_RESOLUTION_R16_SUPERFINE + | T4_RESOLUTION_200_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_200_400 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_300_600 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_400_800 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_600_1200 + | T4_RESOLUTION_1200_1200, + T4_RESOLUTION_100_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_1200_1200) < 0) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Failed to set T.4 compression\n"); + printf("Test failed\n"); + exit(2); + } + t4_tx_set_min_bits_per_row(&t4_tx_state, min_row_bits); + if (t4_tx_start_page(&t4_tx_state)) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Failed to start T.4 send\n"); + printf("Test failed\n"); + exit(2); + } + /*endif*/ + s->image_len = t4_tx_get(&t4_tx_state, s->image, sizeof(s->image)); + if (parms.bad_rows) + { + span_log(&s->logging, SPAN_LOG_FLOW, "We need to corrupt the image\n"); + corrupt_image(s, (const char *) parms.bad_rows); + } + /*endif*/ + t4_tx_release(&t4_tx_state); + span_log(&s->logging, SPAN_LOG_FLOW, "ECM image is %d bytes (min row bits %d)\n", s->image_len, min_row_bits); + faxtester_set_ecm_image_buffer(s, ecm_block, ecm_frame_size, i); + } + else if (strcasecmp((const char *) parms.type, "CLEAR") == 0) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Time to drop the call\n"); + t30_terminate(s->far_t30); + free_node_parms(&parms); + return 0; + } + else if (strcasecmp((const char *) parms.type, "STATUS") == 0) + { + if (parms.value) + { + for (i = 0; t30_status[i].code >= 0; i++) + { + if (strcmp(t30_status[i].tag, (const char *) parms.value) == 0) + break; + } + if (t30_status[i].code >= 0) + delay = t30_status[i].code; + else + delay = atoi((const char *) parms.value); + t30_get_transfer_statistics(s->far_t30, &t30_stats); + if (delay == t30_stats.current_status) + span_log(&s->logging, SPAN_LOG_FLOW, "Expected status (%s) found\n", t30_status[i].tag); + else + span_log(&s->logging, SPAN_LOG_FLOW, "Expected status %s, but found %s (%d)\n", t30_status[i].tag, t30_status[t30_stats.current_status].tag, t30_stats.current_status); + if (delay != t30_stats.current_status) + { + printf("Test failed\n"); + exit(2); + } + } + free_node_parms(&parms); + return 0; + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised type '%s'\n", (const char *) parms.type); + free_node_parms(&parms); + return 0; + } + /*endif*/ + } + /*endif*/ + free_node_parms(&parms); + return 1; +} +/*- End of function --------------------------------------------------------*/ + +static int parse_config(faxtester_state_t *s, xmlNodePtr cur) +{ + xmlChar *x; + xmlChar *y; + + while (cur) + { + if (xmlStrcmp(cur->name, (const xmlChar *) "path") == 0) + { + x = NULL; + y = NULL; + if ((x = xmlGetProp(cur, (const xmlChar *) "type")) + && + (y = xmlGetProp(cur, (const xmlChar *) "value"))) + { + if (strcasecmp((const char *) x, "IMAGE") == 0) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Found '%s' '%s'\n", (char *) x, (char *) y); + strcpy(s->image_path, (const char *) y); + } + /*endif*/ + } + /*endif*/ + if (x) + xmlFree(x); + /*endif*/ + if (y) + xmlFree(y); + /*endif*/ + } + /*endif*/ + cur = cur->next; + } + /*endwhile*/ + return -1; +} +/*- End of function --------------------------------------------------------*/ + +static int parse_test_group(faxtester_state_t *s, xmlNodePtr cur, const char *test) +{ + xmlChar *x; + + while (cur) + { + if (xmlStrcmp(cur->name, (const xmlChar *) "test") == 0) + { + if ((x = xmlGetProp(cur, (const xmlChar *) "name"))) + { + if (xmlStrcmp(x, (const xmlChar *) test) == 0) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Found '%s'\n", (char *) x); + s->cur = cur->xmlChildrenNode; + xmlFree(x); + return 0; + } + /*endif*/ + xmlFree(x); + } + /*endif*/ + } + /*endif*/ + cur = cur->next; + } + /*endwhile*/ + return -1; +} +/*- End of function --------------------------------------------------------*/ + +static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test) +{ + xmlParserCtxtPtr ctxt; + xmlNodePtr cur; + + if ((ctxt = xmlNewParserCtxt()) == NULL) + { + fprintf(stderr, "Failed to allocate XML parser context\n"); + return -1; + } + /* parse the file, activating the DTD validation option */ + if ((s->doc = xmlCtxtReadFile(ctxt, test_file, NULL, XML_PARSE_XINCLUDE | XML_PARSE_DTDVALID)) == NULL) + { + fprintf(stderr, "Failed to read the XML document\n"); + return -1; + } + if (ctxt->valid == 0) + { + fprintf(stderr, "Failed to validate the XML document\n"); + xmlFreeDoc(s->doc); + s->doc = NULL; + xmlFreeParserCtxt(ctxt); + return -1; + } + xmlFreeParserCtxt(ctxt); + + /* Check the document is of the right kind */ + if ((cur = xmlDocGetRootElement(s->doc)) == NULL) + { + xmlFreeDoc(s->doc); + s->doc = NULL; + fprintf(stderr, "Empty document\n"); + return -1; + } + /*endif*/ + if (xmlStrcmp(cur->name, (const xmlChar *) "fax-tests")) + { + xmlFreeDoc(s->doc); + s->doc = NULL; + fprintf(stderr, "Document of the wrong type, root node != fax-tests\n"); + return -1; + } + /*endif*/ + cur = cur->xmlChildrenNode; + while (cur && xmlIsBlankNode(cur)) + cur = cur->next; + /*endwhile*/ + if (cur == NULL) + { + fprintf(stderr, "XML test not found\n"); + return -1; + } + /*endif*/ + xmlCleanupParser(); + while (cur) + { + if (xmlStrcmp(cur->name, (const xmlChar *) "config") == 0) + parse_config(s, cur->xmlChildrenNode); + /*endif*/ + if (xmlStrcmp(cur->name, (const xmlChar *) "test-group") == 0) + { + if (parse_test_group(s, cur->xmlChildrenNode, test) == 0) + return 0; + /*endif*/ + } + /*endif*/ + cur = cur->next; + } + /*endwhile*/ + fprintf(stderr, "XML test not found\n"); + return -1; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(logging_state_t *) faxtester_get_logging_state(faxtester_state_t *s) +{ + return &s->logging; +} +/*- End of function --------------------------------------------------------*/ + +faxtester_state_t *faxtester_init(faxtester_state_t *s, const char *test_file, const char *test) { if (s == NULL) { if ((s = (faxtester_state_t *) malloc(sizeof(*s))) == NULL) return NULL; } + /*endif*/ memset(s, 0, sizeof(*s)); span_log_init(&s->logging, SPAN_LOG_NONE, NULL); @@ -656,29 +1864,38 @@ faxtester_state_t *faxtester_init(faxtester_state_t *s, int calling_party) fax_modems_set_tep_mode(&s->modems, false); fax_modems_set_rx_active(&s->modems, true); faxtester_set_timeout(s, -1); + s->timein_x = -1; + s->timeout_x = -1; faxtester_set_tx_type(s, T30_MODEM_NONE, 0, false, false); - + strcpy(s->image_path, "."); + s->next_tx_file[0] = '\0'; + if (get_test_set(s, test_file, test) < 0) + { + /* TODO: free the state, if it was allocated. */ + return NULL; + } + /*endif*/ + memset(&s->expected_rx_info, 0, sizeof(s->expected_rx_info)); return s; } /*- End of function --------------------------------------------------------*/ int faxtester_release(faxtester_state_t *s) { + if (s->doc) + { + xmlFreeDoc(s->doc); + s->doc = NULL; + } return 0; } /*- End of function --------------------------------------------------------*/ int faxtester_free(faxtester_state_t *s) { + faxtester_release(s); free(s); return 0; } /*- End of function --------------------------------------------------------*/ - -void faxtester_set_flush_handler(faxtester_state_t *s, faxtester_flush_handler_t handler, void *user_data) -{ - s->flush_handler = handler; - s->flush_user_data = user_data; -} -/*- End of function --------------------------------------------------------*/ /*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/tests/fax_tester.h b/libs/spandsp/tests/fax_tester.h index 48308f7329..412c1fc340 100644 --- a/libs/spandsp/tests/fax_tester.h +++ b/libs/spandsp/tests/fax_tester.h @@ -39,23 +39,6 @@ typedef struct faxtester_state_s faxtester_state_t; typedef void (*faxtester_flush_handler_t)(faxtester_state_t *s, void *user_data, int which); -/*! - FAX tester real time frame handler. - \brief FAX tester real time frame handler. - \param s The FAX tester context. - \param user_data An opaque pointer. - \param direction True for incoming, false for outgoing. - \param msg The HDLC message. - \param len The length of the message. -*/ -typedef void (*faxtester_real_time_frame_handler_t)(faxtester_state_t *s, - void *user_data, - int direction, - const uint8_t *msg, - int len); - -typedef void (*faxtester_front_end_step_complete_handler_t)(faxtester_state_t *s, void *user_data); - /*! FAX tester descriptor. */ @@ -63,9 +46,19 @@ struct faxtester_state_s { /*! \brief The far end FAX context */ fax_state_t *far_fax; + t38_terminal_state_t *far_t38; + + int far_tag; /*! \brief The far end T.38 terminal context */ t38_terminal_state_t *far_t38_fax; + + t30_state_t *far_t30; + + t30_exchanged_info_t expected_rx_info; + + bool use_receiver_not_ready; + bool test_local_interrupt; /*! \brief Path for the FAX image test files. */ char image_path[1024]; @@ -74,27 +67,23 @@ struct faxtester_state_s xmlDocPtr doc; /*! \brief Pointer to our current step in the test. */ xmlNodePtr cur; + + int repeat_min; + int repeat_max; + int repeat_count; + xmlNodePtr repeat_start; + xmlNodePtr repeat_parent; faxtester_flush_handler_t flush_handler; void *flush_user_data; - /*! \brief A pointer to a callback routine to be called when frames are - exchanged. */ - faxtester_real_time_frame_handler_t real_time_frame_handler; - /*! \brief An opaque pointer supplied in real time frame callbacks. */ - void *real_time_frame_user_data; - - faxtester_front_end_step_complete_handler_t front_end_step_complete_handler; - void *front_end_step_complete_user_data; - - faxtester_front_end_step_complete_handler_t front_end_step_timeout_handler; - void *front_end_step_timeout_user_data; - const uint8_t *image_buffer; int image_len; int image_ptr; int image_bit_ptr; + uint8_t image[1000000]; + int ecm_frame_size; int corrupt_crc; @@ -194,26 +183,24 @@ void faxtester_set_transmit_on_idle(faxtester_state_t *s, int transmit_on_idle); */ void faxtester_set_tep_mode(faxtester_state_t *s, int use_tep); -void faxtester_set_real_time_frame_handler(faxtester_state_t *s, faxtester_real_time_frame_handler_t handler, void *user_data); - -void faxtester_set_front_end_step_complete_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data); - -void faxtester_set_front_end_step_timeout_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data); - void faxtester_set_timeout(faxtester_state_t *s, int timeout); -void faxtester_set_non_ecm_image_buffer(faxtester_state_t *s, const uint8_t *buf, int len); +SPAN_DECLARE(int) faxtester_next_step(faxtester_state_t *s); -void faxtester_set_ecm_image_buffer(faxtester_state_t *s, const uint8_t *buf, int len, int block, int frame_size, int crc_hit); - -/*! Initialise a FAX context. - \brief Initialise a FAX context. +/*! Get the logging context associated with a FAX tester context. + \brief Get the logging context associated with a FAX tester context. \param s The FAX tester context. - \param calling_party true if the context is for a calling party. FALSE if the - context is for an answering party. + \return A pointer to the logging context */ +SPAN_DECLARE(logging_state_t *) faxtester_get_logging_state(faxtester_state_t *s); + +/*! Initialise a FAX tester context. + \brief Initialise a FAX tester context. + \param s The FAX tester context. + \param test_file The name of the file of XML test scripts. + \param test The name of the XML script test. \return A pointer to the FAX context, or NULL if there was a problem. */ -faxtester_state_t *faxtester_init(faxtester_state_t *s, int calling_party); +faxtester_state_t *faxtester_init(faxtester_state_t *s, const char *test_file, const char *test); /*! Release a FAX context. \brief Release a FAX context. diff --git a/libs/spandsp/tests/fax_tests.c b/libs/spandsp/tests/fax_tests.c index f3b34b91a3..57de0da361 100644 --- a/libs/spandsp/tests/fax_tests.c +++ b/libs/spandsp/tests/fax_tests.c @@ -99,48 +99,80 @@ The T.31 and TSB85 parts are incomplete right now. #define INPUT_TIFF_FILE_NAME "../test-data/itu/fax/itutests.tif" #define OUTPUT_TIFF_FILE_NAME "fax_tests.tif" +#define INPUT_WAVE_FILE_NAME "fax_cap.wav" #define OUTPUT_WAVE_FILE_NAME "fax_tests.wav" enum { - AUDIO_FAX, - T38_TERMINAL_FAX, - T38_GATEWAY_FAX, + AUDIO_FAX = 1, + T38_FAX, T31_AUDIO_FAX, - T31_T38_TERMINAL_FAX, - T31_T38_GATEWAY_FAX, + T31_T38_FAX, TSB85_AUDIO_FAX, - TSB85_T38_TERMINAL_FAX, - TSB85_T38_GATEWAY_FAX + TSB85_T38_FAX, + REPLAY_AUDIO_FAX, + REPLAY_T38_FAX, + AUDIO_TO_T38_GATEWAY, + PASSTHROUGH, + AUDIO_CHAN, + T38_CHAN }; -int mode[2] = {AUDIO_FAX, AUDIO_FAX}; +const char *output_tiff_file_name; -t30_state_t *t30_state[2] = {NULL, NULL}; -fax_state_t *fax_state[2] = {NULL, NULL}; -t38_gateway_state_t *t38_gateway_state[2] = {NULL, NULL}; -t38_terminal_state_t *t38_state[2] = {NULL, NULL}; -t38_core_state_t *t38_core_state[2] = {NULL, NULL}; -faxtester_state_t *faxtester[2] = {NULL, NULL}; -g1050_state_t *g1050_path[2] = {NULL, NULL}; -awgn_state_t *awgn_state[2] = {NULL, NULL}; -int16_t audio_buffer[2*2][SAMPLES_PER_CHUNK]; +struct audio_buf_s +{ + int16_t amp[SAMPLES_PER_CHUNK]; + int len; +}; -int t38_subst_seq[2] = {0, 0}; +struct chain_element_s +{ + int node_type; + int left_chan_type; + int right_chan_type; + struct + { + fax_state_t *fax_state; + t38_terminal_state_t *t38_state; + faxtester_state_t *faxtester_state; + t38_gateway_state_t *t38_gateway_state; + SNDFILE *wave_handle; + } node; + struct + { + g1050_state_t *g1050_path; + both_ways_line_model_state_t *line_model; + struct audio_buf_s *audio_in_buf; + struct audio_buf_s *audio_out_buf; + } path; + t30_state_t *t30_state; + t38_core_state_t *t38_core_state; + int t38_subst_seq; + bool phase_e_reached; + bool completed; + bool succeeded; + t30_exchanged_info_t expected_rx_info; -t30_exchanged_info_t expected_rx_info[2]; + awgn_state_t *awgn_state; + struct audio_buf_s audio_buf[2]; + + int peer; + int t38_peer; + + char tag[10]; +}; + +struct chain_element_s chain[7]; +int chain_elements = 2; + +bool t38_simulate_incrementing_repeats = false; bool use_receiver_not_ready = false; bool test_local_interrupt = false; double when = 0.0; -bool phase_e_reached[2] = {false, false}; -bool completed[2] = {false, false}; -bool succeeded[2] = {false, false}; - -bool t38_simulate_incrementing_repeats = false; - static int phase_b_handler(void *user_data, int result) { int i; @@ -151,10 +183,12 @@ static int phase_b_handler(void *user_data, int result) char tag[20]; const char *u; const uint8_t *v; + t30_exchanged_info_t *info; i = (int) (intptr_t) user_data; - s = t30_state[i]; + s = chain[i].t30_state; ch = i + 'A'; + info = &chain[i].expected_rx_info; snprintf(tag, sizeof(tag), "%c: Phase B", ch); printf("%c: Phase B handler - (0x%X) %s\n", ch, result, t30_frametype(result)); fax_log_rx_parameters(s, tag); @@ -163,15 +197,15 @@ static int phase_b_handler(void *user_data, int result) if ((u = t30_get_rx_ident(s))) { printf("%c: Phase B remote ident '%s'\n", ch, u); - if (expected_rx_info[i].ident[0] && strcmp(expected_rx_info[i].ident, u)) + if (info->ident[0] && strcmp(info->ident, u)) { - printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", ch, expected_rx_info[i].ident); + printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", ch, info->ident); status = T30_ERR_IDENT_UNACCEPTABLE; } } else { - if (expected_rx_info[i].ident[0]) + if (info->ident[0]) { printf("%c: Phase B: remote ident missing!\n", ch); status = T30_ERR_IDENT_UNACCEPTABLE; @@ -180,15 +214,15 @@ static int phase_b_handler(void *user_data, int result) if ((u = t30_get_rx_sub_address(s))) { printf("%c: Phase B: remote sub-address '%s'\n", ch, u); - if (expected_rx_info[i].sub_address[0] && strcmp(expected_rx_info[i].sub_address, u)) + if (info->sub_address[0] && strcmp(info->sub_address, u)) { - printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", ch, expected_rx_info[i].sub_address); + printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", ch, info->sub_address); status = T30_ERR_SUB_UNACCEPTABLE; } } else { - if (expected_rx_info[i].sub_address[0]) + if (info->sub_address[0]) { printf("%c: Phase B: remote sub-address missing!\n", ch); status = T30_ERR_SUB_UNACCEPTABLE; @@ -197,15 +231,15 @@ static int phase_b_handler(void *user_data, int result) if ((u = t30_get_rx_polled_sub_address(s))) { printf("%c: Phase B: remote polled sub-address '%s'\n", ch, u); - if (expected_rx_info[i].polled_sub_address[0] && strcmp(expected_rx_info[i].polled_sub_address, u)) + if (info->polled_sub_address[0] && strcmp(info->polled_sub_address, u)) { - printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", ch, expected_rx_info[i].polled_sub_address); + printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", ch, info->polled_sub_address); status = T30_ERR_PSA_UNACCEPTABLE; } } else { - if (expected_rx_info[i].polled_sub_address[0]) + if (info->polled_sub_address[0]) { printf("%c: Phase B: remote polled sub-address missing!\n", ch); status = T30_ERR_PSA_UNACCEPTABLE; @@ -214,15 +248,15 @@ static int phase_b_handler(void *user_data, int result) if ((u = t30_get_rx_selective_polling_address(s))) { printf("%c: Phase B: remote selective polling address '%s'\n", ch, u); - if (expected_rx_info[i].selective_polling_address[0] && strcmp(expected_rx_info[i].selective_polling_address, u)) + if (info->selective_polling_address[0] && strcmp(info->selective_polling_address, u)) { - printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", ch, expected_rx_info[i].selective_polling_address); + printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", ch, info->selective_polling_address); status = T30_ERR_SEP_UNACCEPTABLE; } } else { - if (expected_rx_info[i].selective_polling_address[0]) + if (info->selective_polling_address[0]) { printf("%c: Phase B: remote selective polling address missing!\n", ch); status = T30_ERR_SEP_UNACCEPTABLE; @@ -231,15 +265,15 @@ static int phase_b_handler(void *user_data, int result) if ((u = t30_get_rx_sender_ident(s))) { printf("%c: Phase B: remote sender ident '%s'\n", ch, u); - if (expected_rx_info[i].sender_ident[0] && strcmp(expected_rx_info[i].sender_ident, u)) + if (info->sender_ident[0] && strcmp(info->sender_ident, u)) { - printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", ch, expected_rx_info[i].sender_ident); + printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", ch, info->sender_ident); status = T30_ERR_SID_UNACCEPTABLE; } } else { - if (expected_rx_info[i].sender_ident[0]) + if (info->sender_ident[0]) { printf("%c: Phase B: remote sender ident missing!\n", ch); status = T30_ERR_SID_UNACCEPTABLE; @@ -248,15 +282,15 @@ static int phase_b_handler(void *user_data, int result) if ((u = t30_get_rx_password(s))) { printf("%c: Phase B: remote password '%s'\n", ch, u); - if (expected_rx_info[i].password[0] && strcmp(expected_rx_info[i].password, u)) + if (info->password[0] && strcmp(info->password, u)) { - printf("%c: Phase B: remote password incorrect! - expected '%s'\n", ch, expected_rx_info[i].password); + printf("%c: Phase B: remote password incorrect! - expected '%s'\n", ch, info->password); status = T30_ERR_PWD_UNACCEPTABLE; } } else { - if (expected_rx_info[i].password[0]) + if (info->password[0]) { printf("%c: Phase B: remote password missing!\n", ch); status = T30_ERR_PWD_UNACCEPTABLE; @@ -265,46 +299,46 @@ static int phase_b_handler(void *user_data, int result) if ((len = t30_get_rx_nsf(s, &v))) { printf("%c: Phase B: NSF %d bytes\n", ch, len); - if (expected_rx_info[i].nsf_len && (expected_rx_info[i].nsf_len != len || memcmp(expected_rx_info[i].nsf, v, len))) + if (info->nsf_len && (info->nsf_len != len || memcmp(info->nsf, v, len))) { - printf("%c: Phase B: remote NSF incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); + printf("%c: Phase B: remote NSF incorrect! - expected %u bytes\n", ch, (unsigned int) info->nsf_len); } } else { - if (expected_rx_info[i].nsf_len) + if (info->nsf_len) { - printf("%c: Phase B: remote NSF missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); + printf("%c: Phase B: remote NSF missing! - expected %u bytes\n", ch, (unsigned int) info->nsf_len); } } if ((len = t30_get_rx_nsc(s, &v))) { printf("%c: Phase B: NSC %d bytes\n", ch, len); - if (expected_rx_info[i].nsc_len && (expected_rx_info[i].nsc_len != len || memcmp(expected_rx_info[i].nsc, v, len))) + if (info->nsc_len && (info->nsc_len != len || memcmp(info->nsc, v, len))) { - printf("%c: Phase B: remote NSC incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsc_len); + printf("%c: Phase B: remote NSC incorrect! - expected %u bytes\n", ch, (unsigned int) info->nsc_len); } } else { - if (expected_rx_info[i].nsc_len) + if (info->nsc_len) { - printf("%c: Phase B: remote NSC missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsc_len); + printf("%c: Phase B: remote NSC missing! - expected %u bytes\n", ch, (unsigned int) info->nsc_len); } } if ((len = t30_get_rx_nss(s, &v))) { printf("%c: Phase B: NSS %d bytes\n", ch, len); - if (expected_rx_info[i].nss_len && (expected_rx_info[i].nss_len != len || memcmp(expected_rx_info[i].nss, v, len))) + if (info->nss_len && (info->nss_len != len || memcmp(info->nss, v, len))) { - printf("%c: Phase B: remote NSS incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nss_len); + printf("%c: Phase B: remote NSS incorrect! - expected %u bytes\n", ch, (unsigned int) info->nss_len); } } else { - if (expected_rx_info[i].nss_len) + if (info->nss_len) { - printf("%c: Phase B: remote NSS missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); + printf("%c: Phase B: remote NSS missing! - expected %u bytes\n", ch, (unsigned int) info->nsf_len); } } @@ -320,7 +354,7 @@ static int phase_d_handler(void *user_data, int result) char tag[20]; i = (int) (intptr_t) user_data; - s = t30_state[i]; + s = chain[i].t30_state; ch = i + 'A'; snprintf(tag, sizeof(tag), "%c: Phase D", ch); printf("%c: Phase D handler - (0x%X) %s\n", ch, result, t30_frametype(result)); @@ -367,7 +401,7 @@ static void phase_e_handler(void *user_data, int result) char tag[20]; i = (int) (intptr_t) user_data; - s = t30_state[i]; + s = chain[i].t30_state; ch = i + 'A'; snprintf(tag, sizeof(tag), "%c: Phase E", ch); printf("%c: Phase E handler - (%d) %s\n", ch, result, t30_completion_code_to_str(result)); @@ -375,15 +409,15 @@ static void phase_e_handler(void *user_data, int result) fax_log_tx_parameters(s, tag); fax_log_rx_parameters(s, tag); t30_get_transfer_statistics(s, &t); - succeeded[i] = (result == T30_ERR_OK); - phase_e_reached[i] = true; + chain[i].succeeded = (result == T30_ERR_OK); + chain[i].phase_e_reached = true; } /*- End of function --------------------------------------------------------*/ -static void real_time_frame_handler(void *user_data, - bool incoming, - const uint8_t *msg, - int len) +static void real_time_t30_frame_handler(void *user_data, + bool incoming, + const uint8_t *msg, + int len) { int i; int ch; @@ -415,7 +449,7 @@ static void set_t30_callbacks(t30_state_t *t30, int chan) t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) chan); t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) chan); t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) chan); - t30_set_real_time_frame_handler(t30, real_time_frame_handler, (void *) (intptr_t) chan); + t30_set_real_time_frame_handler(t30, real_time_t30_frame_handler, (void *) (intptr_t) chan); t30_set_document_handler(t30, document_handler, (void *) (intptr_t) chan); } /*- End of function --------------------------------------------------------*/ @@ -447,11 +481,11 @@ static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t { for (i = 0; i < count; i++) { - span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", t38_subst_seq[chan], len); + span_log(&s->logging, SPAN_LOG_FLOW, "Send seq %d, len %d\n", chain[chan].t38_subst_seq, len); - if (g1050_put(g1050_path[chan], buf, len, t38_subst_seq[chan], when) < 0) - printf("Lost packet %d\n", t38_subst_seq[chan]); - t38_subst_seq[chan] = (t38_subst_seq[chan] + 1) & 0xFFFF; + if (g1050_put(chain[chan].path.g1050_path, buf, len, chain[chan].t38_subst_seq, when) < 0) + printf("Lost packet %d\n", chain[chan].t38_subst_seq); + chain[chan].t38_subst_seq = (chain[chan].t38_subst_seq + 1) & 0xFFFF; } } else @@ -460,7 +494,7 @@ static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t for (i = 0; i < count; i++) { - if (g1050_put(g1050_path[chan], buf, len, s->tx_seq_no, when) < 0) + if (g1050_put(chain[chan].path.g1050_path, buf, len, s->tx_seq_no, when) < 0) printf("Lost packet %d\n", s->tx_seq_no); } } @@ -468,36 +502,84 @@ static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t } /*- End of function --------------------------------------------------------*/ +static void t33_tests(void) +{ + int n; + int item_no; + int type; + uint8_t num[21]; + uint8_t new_t33[133]; + /* These patterns are from the T.33 spec */ + static const uint8_t *pkts[] = + { + (const uint8_t *) "#1234567890#1234", + (const uint8_t *) "1234#5678#8910", + (const uint8_t *) "#6174444100#1234#567", + (const uint8_t *) "1234#5678##2032223", + (const uint8_t *) "#2037445555##6446666", + (const uint8_t *) "#2037445555#1234##6446666#5678", + //(const uint8_t *) "#123456789012345678901#1234##6446666#5678", + (const uint8_t *) "" + }; + + printf("T.33 sub-address packing/unpacking tests\n"); + for (n = 0; pkts[n][0]; n++) + { + new_t33[0] = '\0'; + printf("'%s'\n", pkts[n]); + for (item_no = 0; item_no < 100; item_no++) + { + if ((type = t33_sub_address_extract_field(num, pkts[n], item_no)) <= 0) + { + if (type == T33_NONE) + break; + printf("Bad sub-address field\n"); + exit(2); + } + switch (type) + { + case T33_SST: + printf("SST '%s'\n", num); + t33_sub_address_add_field(new_t33, num, type); + break; + case T33_EXT: + printf(" EXT '%s'\n", num); + t33_sub_address_add_field(new_t33, num, type); + break; + } + } + if (strcmp((const char *) pkts[n], (const char *) new_t33)) + { + printf("Re-encode mismatch '%s' '%s'\n", pkts[n], new_t33); + exit(2); + } + } +} +/*- End of function --------------------------------------------------------*/ + int main(int argc, char *argv[]) { int16_t silence[SAMPLES_PER_CHUNK]; - int16_t t30_amp[2][SAMPLES_PER_CHUNK]; - int16_t t38_amp[2][SAMPLES_PER_CHUNK]; int16_t t38_amp_hist_a[8][SAMPLES_PER_CHUNK]; int16_t t38_amp_hist_b[8][SAMPLES_PER_CHUNK]; - int16_t out_amp[SAMPLES_PER_CHUNK*4]; - int16_t *fax_rx_buf[2]; - int16_t *fax_tx_buf[2]; - int16_t *t38_gateway_rx_buf[2]; - int16_t *t38_gateway_tx_buf[2]; - int t30_len[2]; - int t38_len[2]; + int16_t audio_log[SAMPLES_PER_CHUNK*4]; int hist_ptr; int log_audio; int msg_len; uint8_t msg[1024]; int outframes; SNDFILE *wave_handle; - SNDFILE *input_wave_handle; bool use_ecm; bool use_tep; - int feedback_audio; - int use_transmit_on_idle; + bool use_polled_mode; + bool use_transmit_on_idle; + bool feedback_audio; int t38_version; const char *input_tiff_file_name; - const char *decode_file_name; + const char *replay_file_name; int i; int j; + int k; int seq_no; int g1050_model_no; int g1050_speed_pattern_no; @@ -526,9 +608,13 @@ int main(int argc, char *argv[]) int expected_pages; char *page_header_info; char *page_header_tz; - const char *tag; const char *xml_file_name; + const char *xml_test_name[2]; + int xml_step; char buf[132 + 1]; + int line_model_no; + int channel_codec; + int rbs_pattern; #if defined(ENABLE_GUI) int use_gui; #endif @@ -540,6 +626,7 @@ int main(int argc, char *argv[]) use_ecm = false; t38_version = 1; input_tiff_file_name = INPUT_TIFF_FILE_NAME; + output_tiff_file_name = OUTPUT_TIFF_FILE_NAME; t38_simulate_incrementing_repeats = false; g1050_model_no = 0; g1050_speed_pattern_no = 1; @@ -547,6 +634,7 @@ int main(int argc, char *argv[]) use_tep = false; feedback_audio = false; use_transmit_on_idle = true; + use_polled_mode = false; supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17; page_header_info = NULL; page_header_tz = NULL; @@ -557,16 +645,22 @@ int main(int argc, char *argv[]) signal_level = 0; noise_level = -99; scan_line_time = 0; - decode_file_name = NULL; + replay_file_name = INPUT_WAVE_FILE_NAME; code_to_look_up = -1; allowed_bilevel_resolutions[0] = 0; allowed_bilevel_resolutions[1] = 0; allowed = 0; + line_model_no = 0; + channel_codec = MUNGE_CODEC_NONE; + rbs_pattern = 0; colour_enabled = false; t37_like_output = false; t38_transport = T38_TRANSPORT_UDPTL; xml_file_name = "../spandsp/tsb85.xml"; - while ((opt = getopt(argc, argv, "7b:c:Cd:D:efFgH:i:Ilm:M:n:p:s:S:tT:u:v:x:z:")) != -1) + xml_test_name[0] = "MRGN01"; + xml_test_name[1] = "MRGN01"; + xml_step = 0; + while ((opt = getopt(argc, argv, "7b:c:Cd:D:efFgH:i:Ilm:M:n:p:Ps:S:tT:u:v:x:X:z:")) != -1) { switch (opt) { @@ -584,7 +678,7 @@ int main(int argc, char *argv[]) colour_enabled = true; break; case 'd': - decode_file_name = optarg; + replay_file_name = optarg; break; case 'D': drop_frame_rate = @@ -629,31 +723,75 @@ int main(int argc, char *argv[]) noise_level = atoi(optarg); break; case 'p': - for (i = 0; i < 2; i++) + /* + -p FAX-audio-FAX + -p FAX-T38-FAX + -p FAX-audio-T38gateway-T38-T38gateway-audio-FAX + -p FAX-T38-T38gateway-audio-T38gateway-T38-FAX + -p FAX-T38-T38gateway-audio-FAX + -p FAX-audio-T38gateway-T38-FAX + -p tester-audio-FAX + -p tester-T38-FAX + -p tester-audio-T38gateway-T38-T38gateway-audio-FAX + -p tester-T38-T38gateway-audio-T38gateway-T38-FAX + -p tester-T38-T38gateway-audio-FAX + -p tester-audio-T38gateway-T38-FAX + */ + for (i = 0, chain_elements = 0, k = 0; chain_elements < 7; i++) { - switch (optarg[i]) + if (optarg[i] != '-' && optarg[i] != '\0') + continue; + j = optarg[i]; + optarg[i] = '\0'; + if (strcmp(&optarg[k], "FAX") == 0) { - case 'A': - mode[i] = AUDIO_FAX; - break; - case 'G': - mode[i] = T38_GATEWAY_FAX; - break; - case 'T': - mode[i] = T38_TERMINAL_FAX; - break; - default: - fprintf(stderr, "Unknown FAX path element %c\n", optarg[i]); + chain[chain_elements++].node_type = AUDIO_FAX; + } + else if (strcmp(&optarg[k], "T38") == 0) + { + chain[chain_elements++].node_type = T38_FAX; + } + else if (strcmp(&optarg[k], "T31") == 0) + { + chain[chain_elements++].node_type = T31_AUDIO_FAX; + } + else if (strcmp(&optarg[k], "tester") == 0) + { + chain[chain_elements++].node_type = TSB85_AUDIO_FAX; + } + else if (strcmp(&optarg[k], "replay") == 0) + { + chain[chain_elements++].node_type = REPLAY_AUDIO_FAX; + } + else if (strcmp(&optarg[k], "T38gateway") == 0) + { + chain[chain_elements++].node_type = AUDIO_TO_T38_GATEWAY; + } + else if (strcmp(&optarg[k], "passthrough") == 0) + { + chain[chain_elements++].node_type = PASSTHROUGH; + } + else + { + fprintf(stderr, "Unknown FAX path element %s\n", &optarg[k]); exit(2); } + k = i + 1; + if (j == '\0') + break; } - if ((mode[0] == AUDIO_FAX && mode[1] != AUDIO_FAX) +#if 0 + if ((chain[0].node_type == AUDIO_FAX && chain[chain_elements - 1].node_type != AUDIO_FAX) || - (mode[0] != AUDIO_FAX && mode[1] == AUDIO_FAX)) + (chain[0].node_type != AUDIO_FAX && chain[chain_elements - 1].node_type == AUDIO_FAX)) { - fprintf(stderr, "Invalid FAX path %s\n", optarg); + fprintf(stderr, "Invalid FAX path\n"); exit(2); } +#endif + break; + case 'P': + use_polled_mode = true; break; case 's': g1050_speed_pattern_no = atoi(optarg); @@ -692,6 +830,10 @@ int main(int argc, char *argv[]) t38_version = atoi(optarg); break; case 'x': + xml_test_name[xml_step] = optarg; + xml_step ^= 1; + break; + case 'X': xml_file_name = optarg; break; case 'z': @@ -726,336 +868,452 @@ int main(int argc, char *argv[]) memset(silence, 0, sizeof(silence)); srand48(0x1234567); + + memset(t38_amp_hist_a, 0, sizeof(t38_amp_hist_a)); + memset(t38_amp_hist_b, 0, sizeof(t38_amp_hist_b)); + /* Set up the nodes */ - input_wave_handle = NULL; - if (mode[0] == T38_TERMINAL_FAX) + chain[0].peer = chain_elements - 1; + chain[chain_elements - 1].peer = 0; + + for (i = 0; i < chain_elements; i++) { - } - else - { - if (decode_file_name) + chain[i].tag[0] = i + 'A'; + chain[i].tag[1] = '\0'; + + memset(&chain[i].audio_buf[0], 0, sizeof(chain[i].audio_buf[0])); + memset(&chain[i].audio_buf[1], 0, sizeof(chain[i].audio_buf[1])); + memset(&chain[i].expected_rx_info, 0, sizeof(chain[i].expected_rx_info)); + + switch (chain[i].node_type) { - if ((input_wave_handle = sf_open_telephony_read(decode_file_name, 1)) == NULL) - { - fprintf(stderr, " Cannot open audio file '%s'\n", decode_file_name); - exit(2); - } - } - } - - for (i = 0; i < 2; i++) - { - tag = (i == 0) ? "A" : "B"; - - memset(&expected_rx_info[i], 0, sizeof(expected_rx_info[i])); - switch (mode[i]) - { - case T38_TERMINAL_FAX: - if ((t38_state[i] = t38_terminal_init(NULL, (i == 0), tx_packet_handler, (void *) (intptr_t) i)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 terminal instance\n"); - exit(2); - } - t30_state[i] = t38_terminal_get_t30_state(t38_state[i]); - t38_core_state[i] = t38_terminal_get_t38_core_state(t38_state[i]); - - logging = t38_terminal_get_logging_state(t38_state[i]); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); - - logging = t38_core_get_logging_state(t38_core_state[i]); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); - - logging = t30_get_logging_state(t30_state[i]); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); - break; case AUDIO_FAX: - case T38_GATEWAY_FAX: - if ((fax_state[i] = fax_init(NULL, (i == 0))) == NULL) + if ((chain[i].node.fax_state = fax_init(NULL, (i == 0))) == NULL) { - fprintf(stderr, "Cannot start FAX instance\n"); + fprintf(stderr, " Cannot start FAX instance\n"); exit(2); } - t30_state[i] = fax_get_t30_state(fax_state[i]); + chain[i].t30_state = fax_get_t30_state(chain[i].node.fax_state); - logging = fax_get_logging_state(fax_state[i]); + logging = fax_get_logging_state(chain[i].node.fax_state); span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); + span_log_set_tag(logging, chain[i].tag); - logging = fax_modems_get_logging_state(&fax_state[i]->modems); + logging = fax_modems_get_logging_state(&chain[i].node.fax_state->modems); span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); + span_log_set_tag(logging, chain[i].tag); - logging = t30_get_logging_state(t30_state[i]); + logging = t30_get_logging_state(chain[i].t30_state); span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); + span_log_set_tag(logging, chain[i].tag); - if (mode[i] == T38_GATEWAY_FAX) - { - if ((t38_gateway_state[i] = t38_gateway_init(NULL, tx_packet_handler, (void *) (intptr_t) i)) == NULL) - { - fprintf(stderr, "Cannot start the T.38 gateway instance\n"); - exit(2); - } - t38_core_state[i] = t38_gateway_get_t38_core_state(t38_gateway_state[i]); + set_t30_callbacks(chain[i].t30_state, i); - logging = t38_gateway_get_logging_state(t38_gateway_state[i]); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); + chain[i].path.audio_in_buf = &chain[i + ((i == 0) ? 1 : -1)].audio_buf[0]; + chain[i].path.audio_out_buf = &chain[i].audio_buf[0]; - logging = fax_modems_get_logging_state(&t38_gateway_state[i]->audio.modems); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); - - logging = t38_core_get_logging_state(t38_core_state[i]); - span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); - span_log_set_tag(logging, tag); - - fax_rx_buf[i] = t38_amp[i]; - fax_tx_buf[i] = t30_amp[i]; - t38_gateway_rx_buf[i] = t30_amp[i]; - t38_gateway_tx_buf[i] = t38_amp[i]; - } - else - { - fax_rx_buf[i] = t30_amp[i]; - fax_tx_buf[i] = t30_amp[i ^ 1]; - t38_gateway_rx_buf[i] = NULL; - t38_gateway_tx_buf[i] = NULL; - } - awgn_state[i] = NULL; + chain[i].awgn_state = NULL; signal_scaling = 1.0f; if (noise_level > -99) { - awgn_state[i] = awgn_init_dbm0(NULL, 1234567, noise_level); + chain[i].awgn_state = awgn_init_dbm0(NULL, 1234567, noise_level); signal_scaling = powf(10.0f, signal_level/20.0f); printf("Signal scaling %f\n", signal_scaling); } break; + case T38_FAX: + if ((chain[i].node.t38_state = t38_terminal_init(NULL, (i == 0), tx_packet_handler, (void *) (intptr_t) i)) == NULL) + { + fprintf(stderr, " Cannot start the T.38 terminal instance\n"); + exit(2); + } + chain[i].t30_state = t38_terminal_get_t30_state(chain[i].node.t38_state); + chain[i].t38_core_state = t38_terminal_get_t38_core_state(chain[i].node.t38_state); + + logging = t38_terminal_get_logging_state(chain[i].node.t38_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, chain[i].tag); + + logging = t38_core_get_logging_state(chain[i].t38_core_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, chain[i].tag); + + logging = t30_get_logging_state(chain[i].t30_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, chain[i].tag); + + set_t30_callbacks(chain[i].t30_state, i); + + if (i == 0) + { + chain[i].t38_peer = i + 1; + } + else + { + switch (chain[i - 1].node_type) + { + case T38_FAX: + case AUDIO_TO_T38_GATEWAY: + chain[i].t38_peer = i - 1; + break; + default: + chain[i].t38_peer = i + 1; + break; + } + } + break; case T31_AUDIO_FAX: break; - case T31_T38_TERMINAL_FAX: - case T31_T38_GATEWAY_FAX: + case T31_T38_FAX: break; case TSB85_AUDIO_FAX: + case TSB85_T38_FAX: + if ((chain[i].node.faxtester_state = faxtester_init(NULL, xml_file_name, xml_test_name[(i == 0) ? 0 : 1])) == NULL) + { + fprintf(stderr, " Cannot start FAX tester instance\n"); + exit(2); + } + logging = faxtester_get_logging_state(chain[i].node.faxtester_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, chain[i].tag); + + faxtester_set_transmit_on_idle(chain[i].node.faxtester_state, true); + + chain[i].path.audio_in_buf = &chain[i + ((i == 0) ? 1 : -1)].audio_buf[0]; + chain[i].path.audio_out_buf = &chain[i].audio_buf[0]; + + if (i == 0) + { + chain[i].t38_peer = i + 1; + } + else + { + switch (chain[i - 1].node_type) + { + case T38_FAX: + case AUDIO_TO_T38_GATEWAY: + chain[i].t38_peer = i - 1; + break; + default: + chain[i].t38_peer = i + 1; + break; + } + } + + chain[i].awgn_state = NULL; + signal_scaling = 1.0f; + if (noise_level > -99) + { + chain[i].awgn_state = awgn_init_dbm0(NULL, 1234567, noise_level); + signal_scaling = powf(10.0f, signal_level/20.0f); + printf("Signal scaling %f\n", signal_scaling); + } break; - case TSB85_T38_TERMINAL_FAX: - case TSB85_T38_GATEWAY_FAX: + case REPLAY_AUDIO_FAX: + if ((chain[i].node.wave_handle = sf_open_telephony_read(replay_file_name, 1)) == NULL) + { + fprintf(stderr, " Cannot open audio file '%s'\n", replay_file_name); + exit(2); + } + + chain[i].path.audio_in_buf = &chain[i + ((i == 0) ? 1 : -1)].audio_buf[0]; + chain[i].path.audio_out_buf = &chain[i].audio_buf[0]; break; + case AUDIO_TO_T38_GATEWAY: + if ((chain[i].node.t38_gateway_state = t38_gateway_init(NULL, tx_packet_handler, (void *) (intptr_t) i)) == NULL) + { + fprintf(stderr, " Cannot start T.38 gateway instance\n"); + exit(2); + } + chain[i].t38_core_state = t38_gateway_get_t38_core_state(chain[i].node.t38_gateway_state); + + logging = t38_gateway_get_logging_state(chain[i].node.t38_gateway_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, chain[i].tag); + + logging = fax_modems_get_logging_state(&chain[i].node.t38_gateway_state->audio.modems); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, chain[i].tag); + + logging = t38_core_get_logging_state(chain[i].t38_core_state); + span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME); + span_log_set_tag(logging, chain[i].tag); + + t38_gateway_set_transmit_on_idle(chain[i].node.t38_gateway_state, use_transmit_on_idle); + t38_gateway_set_supported_modems(chain[i].node.t38_gateway_state, supported_modems); + //t38_gateway_set_nsx_suppression(chain[i].node.t38_state, NULL, 0, NULL, 0); + t38_gateway_set_fill_bit_removal(chain[i].node.t38_gateway_state, remove_fill_bits); + t38_gateway_set_real_time_frame_handler(chain[i].node.t38_gateway_state, real_time_gateway_frame_handler, (void *) (intptr_t) i); + t38_gateway_set_ecm_capability(chain[i].node.t38_gateway_state, use_ecm); + t38_set_t38_version(chain[i].t38_core_state, t38_version); + + if (i == 0) + { + chain[i].t38_peer = i + 1; + chain[i].path.audio_in_buf = NULL; + } + else + { + switch (chain[i - 1].node_type) + { + case T38_FAX: + case AUDIO_TO_T38_GATEWAY: + chain[i].t38_peer = i - 1; + chain[i].path.audio_in_buf = &chain[i + 1].audio_buf[0]; + break; + default: + chain[i].t38_peer = i + 1; + chain[i].path.audio_in_buf = &chain[i - 1].audio_buf[0]; + break; + } + } + + chain[i].path.audio_out_buf = &chain[i].audio_buf[0]; + + chain[i].awgn_state = NULL; + signal_scaling = 1.0f; + if (noise_level > -99) + { + chain[i].awgn_state = awgn_init_dbm0(NULL, 1234567, noise_level); + signal_scaling = powf(10.0f, signal_level/20.0f); + printf("Signal scaling %f\n", signal_scaling); + } } - set_t30_callbacks(t30_state[i], i); - } - /* Set up the channels */ - for (i = 0; i < 2; i++) - { - if ((g1050_path[i] = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) + if ((chain[i].path.g1050_path = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL) { - fprintf(stderr, "Failed to start IP network path model\n"); + fprintf(stderr, " Failed to start IP network path model\n"); exit(2); } - memset(audio_buffer[2*i], 0, SAMPLES_PER_CHUNK*sizeof(int16_t)); - memset(audio_buffer[2*i + 1], 0, SAMPLES_PER_CHUNK*sizeof(int16_t)); - memset(t30_amp[i], 0, sizeof(t30_amp[i])); - memset(t38_amp[i], 0, sizeof(t38_amp[i])); } - memset(t38_amp_hist_a, 0, sizeof(t38_amp_hist_a)); - memset(t38_amp_hist_b, 0, sizeof(t38_amp_hist_b)); - for (i = 0; i < 2; i++) + for (i = 0; i < chain_elements; i++) { j = i + 1; - sprintf(buf, "%d%d%d%d%d%d%d%d", j, j, j, j, j, j, j, j); - t30_set_tx_ident(t30_state[i], buf); - strcpy(expected_rx_info[i ^ 1].ident, buf); - sprintf(buf, "Sub-address %d", j); - t30_set_tx_sub_address(t30_state[i], buf); - //strcpy(expected_rx_info[i ^ 1].sub_address, buf); - sprintf(buf, "Sender ID %d", j); - t30_set_tx_sender_ident(t30_state[i], buf); - //strcpy(expected_rx_info[i ^ 1].sender_ident, buf); - sprintf(buf, "Password %d", j); - t30_set_tx_password(t30_state[i], buf); - //strcpy(expected_rx_info[i ^ 1].password, buf); - sprintf(buf, "Polled sub-add %d", j); - t30_set_tx_polled_sub_address(t30_state[i], buf); - //strcpy(expected_rx_info[i ^ 1].polled_sub_address, buf); - sprintf(buf, "Select poll add %d", j); - t30_set_tx_selective_polling_address(t30_state[i], buf); - //strcpy(expected_rx_info[i ^ 1].selective_polling_address, buf); - t30_set_tx_page_header_info(t30_state[i], page_header_info); - if (page_header_tz) - t30_set_tx_page_header_tz(t30_state[i], page_header_tz); - - if ((i & 1) == 1) + if (chain[i].t30_state) { - t30_set_tx_nsf(t30_state[i], (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); - expected_rx_info[i ^ 1].nsf = (uint8_t *) "\x50\x00\x00\x00Spandsp\x00"; - expected_rx_info[i ^ 1].nsf_len = 12; + sprintf(buf, "%d%d%d%d%d%d%d%d", j, j, j, j, j, j, j, j); + t30_set_tx_ident(chain[i].t30_state, buf); + strcpy(chain[chain[i].peer].expected_rx_info.ident, buf); + sprintf(buf, "Sub-address %d", j); + t30_set_tx_sub_address(chain[i].t30_state, buf); + //strcpy(chain[chain[i].peer].expected_rx_info.sub_address, buf); + sprintf(buf, "Sender ID %d", j); + t30_set_tx_sender_ident(chain[i].t30_state, buf); + //strcpy(chain[chain[i].peer].expected_rx_info.sender_ident, buf); + sprintf(buf, "Password %d", j); + t30_set_tx_password(chain[i].t30_state, buf); + //strcpy(chain[chain[i].peer].expected_rx_info.password, buf); + sprintf(buf, "Polled sub-add %d", j); + t30_set_tx_polled_sub_address(chain[i].t30_state, buf); + //strcpy(chain[chain[i].peer].expected_rx_info.polled_sub_address, buf); + sprintf(buf, "Select poll add %d", j); + t30_set_tx_selective_polling_address(chain[i].t30_state, buf); + //strcpy(chain[chain[i].peer].expected_rx_info.selective_polling_address, buf); + t30_set_tx_page_header_info(chain[i].t30_state, page_header_info); + if (page_header_tz) + t30_set_tx_page_header_tz(chain[i].t30_state, page_header_tz); + + if (i != 0) + { + t30_set_tx_nsf(chain[i].t30_state, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); + chain[chain[i].peer].expected_rx_info.nsf = (uint8_t *) "\x50\x00\x00\x00Spandsp\x00"; + chain[chain[i].peer].expected_rx_info.nsf_len = 12; + } + + t30_set_supported_modems(chain[i].t30_state, supported_modems); + t30_set_supported_t30_features(chain[i].t30_state, + T30_SUPPORT_IDENTIFICATION + | T30_SUPPORT_SELECTIVE_POLLING + | T30_SUPPORT_SUB_ADDRESSING); + t30_set_supported_image_sizes(chain[i].t30_state, + T4_SUPPORT_WIDTH_215MM + | T4_SUPPORT_WIDTH_255MM + | T4_SUPPORT_WIDTH_303MM + | T4_SUPPORT_LENGTH_US_LETTER + | T4_SUPPORT_LENGTH_US_LEGAL + | T4_SUPPORT_LENGTH_UNLIMITED); + switch (allowed_bilevel_resolutions[(i == 0) ? 0 : 1]) + { + case 0: + /* Allow anything */ + t30_set_supported_bilevel_resolutions(chain[i].t30_state, + T4_RESOLUTION_R8_STANDARD + | T4_RESOLUTION_R8_FINE + | T4_RESOLUTION_R8_SUPERFINE + | T4_RESOLUTION_R16_SUPERFINE + | T4_RESOLUTION_200_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_200_400 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_300_600 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_400_800 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_600_1200 + | T4_RESOLUTION_1200_1200); + break; + case 1: + /* Allow anything metric */ + t30_set_supported_bilevel_resolutions(chain[i].t30_state, + T4_RESOLUTION_R8_STANDARD + | T4_RESOLUTION_R8_FINE + | T4_RESOLUTION_R8_SUPERFINE + | T4_RESOLUTION_R16_SUPERFINE); + break; + case 2: + /* Allow anything inch based */ + t30_set_supported_bilevel_resolutions(chain[i].t30_state, + T4_RESOLUTION_200_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_200_400 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_300_600 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_400_800 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_600_1200 + | T4_RESOLUTION_1200_1200); + break; + case 3: + /* Allow only restricted length resolution */ + t30_set_supported_bilevel_resolutions(chain[i].t30_state, + T4_RESOLUTION_R8_STANDARD + | T4_RESOLUTION_R8_FINE + | T4_RESOLUTION_200_100 + | T4_RESOLUTION_200_200); + break; + case 4: + /* Allow only more restricted length resolution */ + t30_set_supported_bilevel_resolutions(chain[i].t30_state, + T4_RESOLUTION_R8_STANDARD + | T4_RESOLUTION_200_100); + break; + } + if (colour_enabled) + { + t30_set_supported_colour_resolutions(chain[i].t30_state, + T4_RESOLUTION_100_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_400_400 + | T4_RESOLUTION_600_600 + | T4_RESOLUTION_1200_1200); + } + else + { + t30_set_supported_colour_resolutions(chain[i].t30_state, 0); + } + if (t37_like_output) + { + t30_set_supported_output_compressions(chain[i].t30_state, + T4_COMPRESSION_T85 + | T4_COMPRESSION_T85_L0 + | T4_COMPRESSION_T6 + | T4_COMPRESSION_T42_T81); + } + else + { + t30_set_supported_output_compressions(chain[i].t30_state, + T4_COMPRESSION_T6 + | T4_COMPRESSION_JPEG); + } + + t30_set_ecm_capability(chain[i].t30_state, use_ecm); + t30_set_supported_compressions(chain[i].t30_state, + T4_COMPRESSION_T4_1D + | T4_COMPRESSION_T4_2D + | T4_COMPRESSION_T6 + | T4_COMPRESSION_T85 + | T4_COMPRESSION_T85_L0 + //| T4_COMPRESSION_T88 + | T4_COMPRESSION_T43 + | T4_COMPRESSION_T45 + | T4_COMPRESSION_T42_T81 + | T4_COMPRESSION_SYCC_T81 + | T4_COMPRESSION_GRAYSCALE + | T4_COMPRESSION_COLOUR + | T4_COMPRESSION_12BIT + | T4_COMPRESSION_COLOUR_TO_GRAY + | T4_COMPRESSION_GRAY_TO_BILEVEL + | T4_COMPRESSION_COLOUR_TO_BILEVEL + | T4_COMPRESSION_RESCALING + | 0); + t30_set_minimum_scan_line_time(chain[i].t30_state, scan_line_time); } - t30_set_supported_modems(t30_state[i], supported_modems); - t30_set_supported_t30_features(t30_state[i], - T30_SUPPORT_IDENTIFICATION - | T30_SUPPORT_SELECTIVE_POLLING - | T30_SUPPORT_SUB_ADDRESSING); - t30_set_supported_image_sizes(t30_state[i], - T4_SUPPORT_WIDTH_215MM - | T4_SUPPORT_WIDTH_255MM - | T4_SUPPORT_WIDTH_303MM - | T4_SUPPORT_LENGTH_US_LETTER - | T4_SUPPORT_LENGTH_US_LEGAL - | T4_SUPPORT_LENGTH_UNLIMITED); - switch (allowed_bilevel_resolutions[i]) + switch (chain[i].node_type) { - case 0: - /* Allow anything */ - t30_set_supported_bilevel_resolutions(t30_state[i], - T4_RESOLUTION_R8_STANDARD - | T4_RESOLUTION_R8_FINE - | T4_RESOLUTION_R8_SUPERFINE - | T4_RESOLUTION_R16_SUPERFINE - | T4_RESOLUTION_200_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_200_400 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_300_600 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_400_800 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_600_1200 - | T4_RESOLUTION_1200_1200); + case AUDIO_FAX: + fax_set_transmit_on_idle(chain[i].node.fax_state, use_transmit_on_idle); + fax_set_tep_mode(chain[i].node.fax_state, use_tep); break; - case 1: - /* Allow anything metric */ - t30_set_supported_bilevel_resolutions(t30_state[i], - T4_RESOLUTION_R8_STANDARD - | T4_RESOLUTION_R8_FINE - | T4_RESOLUTION_R8_SUPERFINE - | T4_RESOLUTION_R16_SUPERFINE); - break; - case 2: - /* Allow anything inch based */ - t30_set_supported_bilevel_resolutions(t30_state[i], - T4_RESOLUTION_200_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_200_400 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_300_600 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_400_800 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_600_1200 - | T4_RESOLUTION_1200_1200); - break; - case 3: - /* Allow only restricted length resolution */ - t30_set_supported_bilevel_resolutions(t30_state[i], - T4_RESOLUTION_R8_STANDARD - | T4_RESOLUTION_R8_FINE - | T4_RESOLUTION_200_100 - | T4_RESOLUTION_200_200); - break; - case 4: - /* Allow only more restricted length resolution */ - t30_set_supported_bilevel_resolutions(t30_state[i], - T4_RESOLUTION_R8_STANDARD - | T4_RESOLUTION_200_100); - break; - } - if (colour_enabled) - { - t30_set_supported_colour_resolutions(t30_state[i], - T4_RESOLUTION_100_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_1200_1200); - } - else - { - t30_set_supported_colour_resolutions(t30_state[i], 0); - } - if (t37_like_output) - { - t30_set_supported_output_compressions(t30_state[i], - T4_COMPRESSION_T85 - | T4_COMPRESSION_T85_L0 - | T4_COMPRESSION_T6 - | T4_COMPRESSION_T42_T81); - } - else - { - t30_set_supported_output_compressions(t30_state[i], - T4_COMPRESSION_T6 - | T4_COMPRESSION_JPEG); - } - - t30_set_ecm_capability(t30_state[i], use_ecm); - t30_set_supported_compressions(t30_state[i], - T4_COMPRESSION_T4_1D - | T4_COMPRESSION_T4_2D - | T4_COMPRESSION_T6 - | T4_COMPRESSION_T85 - | T4_COMPRESSION_T85_L0 - //| T4_COMPRESSION_T88 - | T4_COMPRESSION_T43 - | T4_COMPRESSION_T45 - | T4_COMPRESSION_T42_T81 - | T4_COMPRESSION_SYCC_T81 - | T4_COMPRESSION_GRAYSCALE - | T4_COMPRESSION_COLOUR - | T4_COMPRESSION_12BIT - | T4_COMPRESSION_COLOUR_TO_GRAY - | T4_COMPRESSION_GRAY_TO_BILEVEL - | T4_COMPRESSION_COLOUR_TO_BILEVEL - | T4_COMPRESSION_RESCALING - | 0); - t30_set_minimum_scan_line_time(t30_state[i], scan_line_time); - - if (mode[i] == T38_GATEWAY_FAX) - { - t38_gateway_set_transmit_on_idle(t38_gateway_state[i], use_transmit_on_idle); - t38_gateway_set_supported_modems(t38_gateway_state[i], supported_modems); - //t38_gateway_set_nsx_suppression(t38_state[i], NULL, 0, NULL, 0); - t38_gateway_set_fill_bit_removal(t38_gateway_state[i], remove_fill_bits); - t38_gateway_set_real_time_frame_handler(t38_gateway_state[i], real_time_gateway_frame_handler, (void *) (intptr_t) i); - t38_gateway_set_ecm_capability(t38_gateway_state[i], use_ecm); - } - if (mode[i] != AUDIO_FAX) - { - t38_set_t38_version(t38_core_state[i], t38_version); - } - - if (mode[i] == T38_TERMINAL_FAX) - { - //t30_set_iaf_mode(t30_state[i], T30_IAF_MODE_NO_FILL_BITS); + case T38_FAX: + t38_set_t38_version(chain[i].t38_core_state, t38_version); + //t30_set_iaf_mode(chain[i].t30_state, T30_IAF_MODE_NO_FILL_BITS); switch (t38_transport) { case T38_TRANSPORT_UDPTL: case T38_TRANSPORT_RTP: - t38_terminal_set_fill_bit_removal(t38_state[i], remove_fill_bits); - t38_terminal_set_tep_mode(t38_state[i], use_tep); + t38_terminal_set_fill_bit_removal(chain[i].node.t38_state, remove_fill_bits); + t38_terminal_set_tep_mode(chain[i].node.t38_state, use_tep); break; case T38_TRANSPORT_TCP: case T38_TRANSPORT_TCP_TPKT: - t38_terminal_set_fill_bit_removal(t38_state[i], true); - t38_terminal_set_config(t38_state[i], T38_TERMINAL_OPTION_NO_PACING | T38_TERMINAL_OPTION_NO_INDICATORS); - t38_terminal_set_tep_mode(t38_state[i], false); + t38_terminal_set_fill_bit_removal(chain[i].node.t38_state, true); + t38_terminal_set_config(chain[i].node.t38_state, T38_TERMINAL_OPTION_NO_PACING | T38_TERMINAL_OPTION_NO_INDICATORS); + t38_terminal_set_tep_mode(chain[i].node.t38_state, false); break; } - } - else - { - fax_set_transmit_on_idle(fax_state[i], use_transmit_on_idle); - fax_set_tep_mode(fax_state[i], use_tep); + break; } } - t30_set_tx_file(t30_state[0], input_tiff_file_name, start_page, end_page); - t30_set_rx_file(t30_state[1], OUTPUT_TIFF_FILE_NAME, -1); + for (i = 0; i < chain_elements; i++) + { + switch (chain[i].node_type) + { + case TSB85_AUDIO_FAX: + case TSB85_T38_FAX: + if (chain[chain[i].peer].node_type == AUDIO_FAX) + chain[i].node.faxtester_state->far_fax = chain[chain[i].peer].node.fax_state; + else + chain[i].node.faxtester_state->far_t38 = chain[chain[i].peer].node.t38_state; + chain[i].node.faxtester_state->far_t30 = chain[chain[i].peer].t30_state; + chain[i].node.faxtester_state->far_tag = chain[i].peer + 'A'; + + while (faxtester_next_step(chain[i].node.faxtester_state) == 0) + /*dummy loop*/; + /*endwhile*/ + break; + case REPLAY_AUDIO_FAX: + break; + case PASSTHROUGH: + if (chain[i - 1].path.audio_in_buf == &chain[i].audio_buf[0]) + chain[i - 1].path.audio_in_buf = &chain[i + 1].audio_buf[0]; + if (chain[i + 1].path.audio_in_buf == &chain[i].audio_buf[0]) + chain[i + 1].path.audio_in_buf = &chain[i - 1].audio_buf[0]; + break; + } + } + + switch (chain[chain_elements - 1].node_type) + { + case AUDIO_FAX: + case T38_FAX: + k = (use_polled_mode) ? (chain_elements - 1) : 0; + if (chain[k].t30_state) + t30_set_tx_file(chain[k].t30_state, input_tiff_file_name, start_page, end_page); + break; + } + switch (chain[0].node_type) + { + case AUDIO_FAX: + case T38_FAX: + k = (use_polled_mode) ? 0 : (chain_elements - 1); + if (chain[k].t30_state) + t30_set_rx_file(chain[k].t30_state, output_tiff_file_name, -1); + break; + } #if defined(ENABLE_GUI) if (use_gui) @@ -1064,144 +1322,225 @@ int main(int argc, char *argv[]) hist_ptr = 0; for (;;) { - memset(out_amp, 0, sizeof(out_amp)); + memset(audio_log, 0, sizeof(audio_log)); - for (i = 0; i < 2; i++) + for (i = 0; i < chain_elements; i++) { /* Update T.30 timing */ - logging = t30_get_logging_state(t30_state[i]); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - - if (mode[i] == T38_TERMINAL_FAX) + switch (chain[i].node_type) { - /* Update T.38 termination timing */ - logging = t38_terminal_get_logging_state(t38_state[i]); + case AUDIO_FAX: + /* Update timing */ + logging = t30_get_logging_state(chain[i].t30_state); span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t38_core_get_logging_state(t38_core_state[i]); + logging = fax_get_logging_state(chain[i].node.fax_state); span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - - completed[i] = t38_terminal_send_timeout(t38_state[i], SAMPLES_PER_CHUNK); - } - else - { - /* Update audio FAX timing */ - logging = fax_get_logging_state(fax_state[i]); + logging = fax_modems_get_logging_state(&chain[i].node.fax_state->modems); span_log_bump_samples(logging, SAMPLES_PER_CHUNK); +#if 0 + /* Probe inside the modems to update their logs */ + span_log_bump_samples(chain[i].node.fax_state->modems.v27ter_rx.logging, len); + span_log_bump_samples(chain[i].node.fax_state->modems.v29_rx.logging, len); + span_log_bump_samples(chain[i].node.fax_state->modems.v17_rx.logging, len); +#endif #if 0 /* Mute the signal */ - vec_zeroi16(fax_rx_buf[i], SAMPLES_PER_CHUNK); + vec_zeroi16(chain[i].path.audio_in_buf->amp, SAMPLES_PER_CHUNK); + chain[i].path.audio_in_buf->len = SAMPLES_PER_CHUNK; #endif - fax_rx(fax_state[i], fax_rx_buf[i], SAMPLES_PER_CHUNK); - if (!t30_call_active(t30_state[i])) + if (log_audio) { - completed[i] = true; + k = (i == 0) ? 0 : 2; + for (j = 0; j < chain[i].path.audio_in_buf->len; j++) + audio_log[4*j + k] = chain[i].path.audio_in_buf->amp[j]; + } + fax_rx(chain[i].node.fax_state, chain[i].path.audio_in_buf->amp, chain[i].path.audio_in_buf->len); + if (!t30_call_active(chain[i].t30_state)) + { + chain[i].completed = true; continue; } - if (i == 0 && input_wave_handle) + chain[i].path.audio_out_buf->len = fax_tx(chain[i].node.fax_state, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK); + if (!use_transmit_on_idle) { - t30_len[i] = sf_readf_short(input_wave_handle, fax_tx_buf[i], SAMPLES_PER_CHUNK); - if (t30_len[i] == 0) - break; + /* The receive side always expects a full block of samples, but the + transmit side may not be sending any when it doesn't need to. We + may need to pad with some silence. */ + if (chain[i].path.audio_out_buf->len < SAMPLES_PER_CHUNK) + { + vec_zeroi16(&chain[i].path.audio_out_buf->amp[chain[i].path.audio_out_buf->len], SAMPLES_PER_CHUNK - chain[i].path.audio_out_buf->len); + chain[i].path.audio_out_buf->len = SAMPLES_PER_CHUNK; + } } - else + if (chain[i].awgn_state) { - t30_len[i] = fax_tx(fax_state[i], fax_tx_buf[i], SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - /* The receive side always expects a full block of samples, but the - transmit side may not be sending any when it doesn't need to. We - may need to pad with some silence. */ - if (t30_len[i] < SAMPLES_PER_CHUNK) - { - memset(t30_amp[i] + t30_len[i], 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len[i])); - t30_len[i] = SAMPLES_PER_CHUNK; - } - } - if (awgn_state[i]) - { - for (j = 0; j < t30_len[i]; j++) - fax_tx_buf[i][j] = ((int16_t) (fax_tx_buf[i][j]*signal_scaling)) + awgn(awgn_state[i]); - } + for (j = 0; j < chain[i].path.audio_out_buf->len; j++) + chain[i].path.audio_out_buf->amp[j] = ((int16_t) (chain[i].path.audio_out_buf->amp[j]*signal_scaling)) + awgn(chain[i].awgn_state); } if (log_audio) { - for (j = 0; j < t30_len[i]; j++) - out_amp[4*j + 2*i] = t30_amp[i][j]; + k = (i == 0) ? 1 : 3; + for (j = 0; j < chain[i].path.audio_out_buf->len; j++) + audio_log[4*j + k] = chain[i].path.audio_out_buf->amp[j]; } if (feedback_audio) { - for (j = 0; j < t30_len[i]; j++) - t30_amp[i][j] += t38_amp_hist_a[hist_ptr][j] >> 1; - memcpy(t38_amp_hist_a[hist_ptr], t38_amp[i], sizeof(int16_t)*SAMPLES_PER_CHUNK); + for (j = 0; j < chain[i].path.audio_out_buf->len; j++) + chain[i].path.audio_out_buf->amp[j] += t38_amp_hist_a[hist_ptr][j] >> 1; + memcpy(t38_amp_hist_a[hist_ptr], chain[i].path.audio_out_buf->amp, sizeof(int16_t)*SAMPLES_PER_CHUNK); } + break; + case T38_FAX: + /* Update timing */ + logging = t30_get_logging_state(chain[i].t30_state); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + logging = t38_terminal_get_logging_state(chain[i].node.t38_state); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + logging = t38_core_get_logging_state(chain[i].t38_core_state); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - if (mode[i] == T38_GATEWAY_FAX) - { - /* Update T.38 gateway timing */ - logging = t38_gateway_get_logging_state(t38_gateway_state[i]); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); - logging = t38_core_get_logging_state(t38_core_state[i]); - span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + chain[i].completed = t38_terminal_send_timeout(chain[i].node.t38_state, SAMPLES_PER_CHUNK); - if (drop_frame_rate && --drop_frame == 0) - { - drop_frame = drop_frame_rate; - if (t38_gateway_rx_fillin(t38_gateway_state[i], SAMPLES_PER_CHUNK)) - break; - } - else - { - if (t38_gateway_rx(t38_gateway_state[i], t38_gateway_rx_buf[i], SAMPLES_PER_CHUNK)) - break; - } - - t38_len[i] = t38_gateway_tx(t38_gateway_state[i], t38_gateway_tx_buf[i], SAMPLES_PER_CHUNK); - if (!use_transmit_on_idle) - { - if (t38_len[i] < SAMPLES_PER_CHUNK) - { - memset(t38_amp[i] + t38_len[i], 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len[i])); - t38_len[i] = SAMPLES_PER_CHUNK; - } - } - if (feedback_audio) - { - for (j = 0; j < t30_len[i]; j++) - t30_amp[i][j] += t38_amp_hist_a[hist_ptr][j] >> 1; - memcpy(t38_amp_hist_a[hist_ptr], t38_amp[i], sizeof(int16_t)*SAMPLES_PER_CHUNK); - } - - if (log_audio) - { - for (j = 0; j < t38_len[i]; j++) - out_amp[4*j + 2*i + 1] = t38_amp[i][j]; - } - } - } - if (mode[i] != AUDIO_FAX) - { - while ((msg_len = g1050_get(g1050_path[i], msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) + while ((msg_len = g1050_get(chain[i].path.g1050_path, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) { #if defined(ENABLE_GUI) if (use_gui) media_monitor_rx(seq_no, tx_when, rx_when); #endif - t38_core_rx_ifp_packet(t38_core_state[i ^ 1], msg, msg_len, seq_no); + t38_core_rx_ifp_packet(chain[chain[i].t38_peer].t38_core_state, msg, msg_len, seq_no); } + break; + case TSB85_AUDIO_FAX: + /* Update timing */ + logging = faxtester_get_logging_state(chain[i].node.faxtester_state); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); +#if 0 + /* Probe inside the modems to update their logs */ + span_log_bump_samples(&chain[i].node.faxtester_state->modems.v27ter_rx.logging, len); + span_log_bump_samples(&chain[i].node.faxtester_state->modems.v29_rx.logging, len); + span_log_bump_samples(&chain[i].node.faxtester_state->modems.v17_rx.logging, len); +#endif + + if (log_audio) + { + k = (i == 0) ? 0 : 2; + for (j = 0; j < chain[i].path.audio_in_buf->len; j++) + audio_log[4*j + k] = chain[i].path.audio_in_buf->amp[j]; + } + faxtester_rx(chain[i].node.faxtester_state, chain[i].path.audio_in_buf->amp, chain[i].path.audio_in_buf->len); + chain[i].path.audio_out_buf->len = faxtester_tx(chain[i].node.faxtester_state, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK); + if (chain[i].path.audio_out_buf->len == 0) + break; + if (log_audio) + { + k = (i == 0) ? 1 : 3; + for (j = 0; j < chain[i].path.audio_out_buf->len; j++) + audio_log[4*j + k] = chain[i].path.audio_out_buf->amp[j]; + } + if (chain[i].node.faxtester_state->test_for_call_clear && !chain[i].node.faxtester_state->far_end_cleared_call) + { + chain[i].node.faxtester_state->call_clear_timer += chain[i].path.audio_out_buf->len; + if (!t30_call_active(chain[i].node.faxtester_state->far_t30)) + { + span_log(faxtester_get_logging_state(chain[i].node.faxtester_state), + SPAN_LOG_FLOW, + "Far end cleared after %dms (limits %dms to %dms)\n", + chain[i].node.faxtester_state->call_clear_timer/8, + chain[i].node.faxtester_state->timein_x, + chain[i].node.faxtester_state->timeout); + if (chain[i].node.faxtester_state->call_clear_timer/8 < chain[i].node.faxtester_state->timein_x || chain[i].node.faxtester_state->call_clear_timer/8 > chain[i].node.faxtester_state->timeout_x) + { + printf("Test failed\n"); + exit(2); + } + span_log(faxtester_get_logging_state(chain[i].node.faxtester_state), SPAN_LOG_FLOW, "Clear time OK\n"); + chain[i].node.faxtester_state->far_end_cleared_call = true; + chain[i].node.faxtester_state->test_for_call_clear = false; + while (faxtester_next_step(chain[i].node.faxtester_state) == 0) + /*dummy loop*/; + /*endwhile*/ + } + /*endif*/ + } + /*endif*/ + break; + case REPLAY_AUDIO_FAX: + chain[i].path.audio_out_buf->len = sf_readf_short(chain[i].node.wave_handle, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK); + if (chain[i].path.audio_out_buf->len == 0) + break; + break; + case AUDIO_TO_T38_GATEWAY: + /* Update timing */ + logging = t38_gateway_get_logging_state(chain[i].node.t38_gateway_state); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); + logging = t38_core_get_logging_state(chain[i].t38_core_state); + span_log_bump_samples(logging, SAMPLES_PER_CHUNK); +#if 0 + /* Probe inside the modems to update their logs */ + span_log_bump_samples(&chain[i].node.t38_gateway_state->modems.v27ter_rx.logging, len); + span_log_bump_samples(&chain[i].node.t38_gateway_state->modems.v29_rx.logging, len); + span_log_bump_samples(&chain[i].node.t38_gateway_state->modems.v17_rx.logging, len); +#endif + + if (drop_frame_rate && --drop_frame == 0) + { + drop_frame = drop_frame_rate; + if (t38_gateway_rx_fillin(chain[i].node.t38_gateway_state, SAMPLES_PER_CHUNK)) + break; + } + else + { + if (t38_gateway_rx(chain[i].node.t38_gateway_state, chain[i].path.audio_in_buf->amp, chain[i].path.audio_in_buf->len)) + break; + } + + chain[i].path.audio_out_buf->len = t38_gateway_tx(chain[i].node.t38_gateway_state, chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK); + if (!use_transmit_on_idle) + { + if (chain[i].path.audio_out_buf->len < SAMPLES_PER_CHUNK) + { + vec_zeroi16(&chain[i].path.audio_out_buf->amp[chain[i].path.audio_out_buf->len], SAMPLES_PER_CHUNK - chain[i].path.audio_out_buf->len); + chain[i].path.audio_out_buf->len = SAMPLES_PER_CHUNK; + } + } + if (feedback_audio) + { + for (j = 0; j < chain[i].path.audio_out_buf->len; j++) + chain[i].path.audio_out_buf->amp[j] += t38_amp_hist_a[hist_ptr][j] >> 1; + vec_movei16(t38_amp_hist_a[hist_ptr], chain[i].path.audio_out_buf->amp, SAMPLES_PER_CHUNK); + } + +#if 0 + if (log_audio) + { + k = (i == 0) ? 1 : 3; + for (j = 0; j < chain[i].path.audio_out_buf->len; j++) + audio_log[4*j + k] = chain[i].path.audio_out_buf->amp[j]; + } +#endif + while ((msg_len = g1050_get(chain[i].path.g1050_path, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0) + { +#if defined(ENABLE_GUI) + if (use_gui) + media_monitor_rx(seq_no, tx_when, rx_when); +#endif + t38_core_rx_ifp_packet(chain[chain[i].t38_peer].t38_core_state, msg, msg_len, seq_no); + } + break; } } if (log_audio) { - outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK); + outframes = sf_writef_short(wave_handle, audio_log, SAMPLES_PER_CHUNK); if (outframes != SAMPLES_PER_CHUNK) break; } when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE; - if (completed[0] && completed[1]) + if (chain[0].completed && chain[chain_elements - 1].completed) break; #if defined(ENABLE_GUI) if (use_gui) @@ -1210,24 +1549,19 @@ int main(int argc, char *argv[]) if (++hist_ptr > 3) hist_ptr = 0; } - for (i = 0; i < 2; i++) + + for (i = 0; i < chain_elements; i++) { - if (mode[i] == T38_GATEWAY_FAX) + switch (chain[i].node_type) { - t38_gateway_get_transfer_statistics(t38_gateway_state[i], &t38_stats); + case AUDIO_TO_T38_GATEWAY: + t38_gateway_get_transfer_statistics(chain[i].node.t38_gateway_state, &t38_stats); printf("%c side exchanged %d pages at %dbps, in %s mode\n", i + 'A', t38_stats.pages_transferred, t38_stats.bit_rate, (t38_stats.error_correcting_mode) ? "ECM" : "non-ECM"); - } - } - if (input_wave_handle) - { - if (sf_close_telephony(input_wave_handle)) - { - fprintf(stderr, " Cannot close audio file '%s'\n", decode_file_name); - exit(2); + break; } } if (log_audio) @@ -1246,14 +1580,16 @@ int main(int argc, char *argv[]) if (start_page >= 0) expected_pages -= start_page; /* Check how many pages were transferred */ - for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) { - if (!phase_e_reached[i]) + i = (j == 0) ? 0 : (chain_elements - 1); + if (!chain[i].phase_e_reached) break; - if (!succeeded[i]) + if (!chain[i].succeeded) break; - t30_get_transfer_statistics(t30_state[i], &t30_stats); - if (i & 1) + + t30_get_transfer_statistics(chain[i].t30_state, &t30_stats); + if ((!use_polled_mode && i != 0) || (use_polled_mode && i == 0)) { if (t30_stats.pages_tx != 0 || t30_stats.pages_rx != expected_pages) break; @@ -1263,23 +1599,45 @@ int main(int argc, char *argv[]) if (t30_stats.pages_tx != expected_pages || t30_stats.pages_rx != 0) break; } - if (mode[i] == T38_TERMINAL_FAX) - t38_terminal_free(t38_state[i]); - else - fax_free(fax_state[i]); - if (mode[i] == T38_GATEWAY_FAX) - t38_gateway_free(t38_gateway_state[i]); - if (g1050_path[i]) + } + for (i = 0; i < chain_elements; i++) + { + switch (chain[i].node_type) { - g1050_free(g1050_path[i]); - g1050_path[i] = NULL; + case AUDIO_FAX: + fax_free(chain[i].node.fax_state); + break; + case T38_FAX: + t38_terminal_free(chain[i].node.t38_state); + break; + case TSB85_AUDIO_FAX: + case TSB85_T38_FAX: + faxtester_free(chain[i].node.faxtester_state); + break; + case REPLAY_AUDIO_FAX: + if (sf_close_telephony(chain[i].node.wave_handle)) + { + fprintf(stderr, " Cannot close audio file '%s'\n", replay_file_name); + exit(2); + } + chain[i].node.wave_handle = NULL; + break; + case AUDIO_TO_T38_GATEWAY: + t38_gateway_free(chain[i].node.t38_gateway_state); + break; + } + if (chain[i].path.g1050_path) + { + g1050_free(chain[i].path.g1050_path); + chain[i].path.g1050_path = NULL; } } - if (i < 2) + if (j < 2) { printf("Tests failed\n"); exit(2); } + t33_tests(); printf("Tests passed\n"); return 0; } diff --git a/libs/spandsp/tests/fax_tests.sh b/libs/spandsp/tests/fax_tests.sh index 0cacdcdd7b..140d8fddf9 100755 --- a/libs/spandsp/tests/fax_tests.sh +++ b/libs/spandsp/tests/fax_tests.sh @@ -94,7 +94,7 @@ LOCALTESTS_DIR=../test-data/local TIFFCMP=tiffcmp # Colour/gray -> bilevel by not allowing ECM -#for OPTS in "-p AA" "-p TT" "-p GG" "-p TG" "-p GT" +#for OPTS in "-p FAX-FAX" "-p T38-T38" "-p FAX-T38gateway-T38gateway-FAX" "-p T38-T38gateway-FAX" "-p FAX-T38gateway-T38" #do # IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif" # OUT_FILE="${LOCALTESTS_DIR}/lenna-colour-bilevel.tif" @@ -118,7 +118,7 @@ TIFFCMP=tiffcmp #done # Colour/gray -> colour/gray -#for OPTS in "-p AA -C -e" "-p TT -C -e" "-p GG -C -e" "-p TG -C -e" "-p GT -C -e" +#for OPTS in "-p FAX-FAX -C -e" "-p T38-T38 -C -e" "-p FAX-T38gateway-T38gateway-FAX -C -e" "-p T38-T38gateway-FAX -C -e" "-p FAX-T38gateway-T38 -C -e" #do # IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif" # OUT_FILE="${LOCALTESTS_DIR}/lenna-colour-out.tif" @@ -142,7 +142,7 @@ TIFFCMP=tiffcmp #done # Bi-level tests with image squashing -for OPTS in "-p AA" "-p AA -e" "-p TT" "-p TT -e" "-p GG" "-p GG -e" "-p TG" "-p TG -e" "-p GT" "-p GT -e" +for OPTS in "-p FAX-FAX" "-p FAX-FAX -e" "-p T38-T38" "-p T38-T38 -e" "-p FAX-T38gateway-T38gateway-FAX" "-p FAX-T38gateway-T38gateway-FAX -e" "-p T38-T38gateway-FAX" "-p T38-T38gateway-FAX -e" "-p FAX-T38gateway-T38" "-p FAX-T38gateway-T38 -e" do IN_FILE="${ITUTESTS_DIR}/bilevel_R8_77_A4.tif" OUT_FILE="${ITUTESTS_DIR}/bilevel_R8_77SQ_A4.tif" @@ -241,7 +241,7 @@ do done # Bi-level tests -for OPTS in "-p AA" "-p AA -e" "-p TT" "-p TT -e" "-p GG" "-p GG -e" "-p TG" "-p TG -e" "-p GT" "-p GT -e" +for OPTS in "-p FAX-FAX" "-p FAX-FAX -e" "-p T38-T38" "-p T38-T38 -e" "-p FAX-T38gateway-T38gateway-FAX" "-p FAX-T38gateway-T38gateway-FAX -e" "-p T38-T38gateway-FAX" "-p T38-T38gateway-FAX -e" "-p FAX-T38gateway-T38" "-p FAX-T38gateway-T38 -e" do FILE="${ITUTESTS_DIR}/itutests.tif" run_fax_test diff --git a/libs/spandsp/tests/pcap_parse.c b/libs/spandsp/tests/pcap_parse.c index 56d8d288e8..bc3805af2a 100644 --- a/libs/spandsp/tests/pcap_parse.c +++ b/libs/spandsp/tests/pcap_parse.c @@ -113,7 +113,7 @@ typedef struct _null_hdr typedef struct _ipv6_hdr { char dontcare[6]; - uint8_t nxt_header; /* we only need the next header, so we can determine, if the next header is UDP or not */ + u_int8_t nxt_header; /* we only need the next header, so we can determine, if the next header is UDP or not */ char dontcare2[33]; } ipv6_hdr; #endif diff --git a/libs/spandsp/tests/tsb85_tests.c b/libs/spandsp/tests/tsb85_tests.c index 624dcb1f6c..5b199491f1 100644 --- a/libs/spandsp/tests/tsb85_tests.c +++ b/libs/spandsp/tests/tsb85_tests.c @@ -71,1179 +71,11 @@ SNDFILE *out_handle; -bool use_receiver_not_ready = false; -bool test_local_interrupt = false; - const char *output_tiff_file_name; bool log_audio = false; -fax_state_t *fax; -faxtester_state_t state; - -uint8_t image[1000000]; - -uint8_t awaited[1000]; -int awaited_len = 0; - -char image_path[1024]; - -t30_exchanged_info_t expected_rx_info; - -char next_tx_file[1000]; - -static int timein_x = -1; -static int timeout_x = -1; - -static int next_step(faxtester_state_t *s); - -static bool test_for_call_clear = false; -static int call_clear_timer = 0; - -static bool far_end_cleared_call = false; - -struct -{ - const char *tag; - int code; -} t30_status[] = -{ - {"OK", T30_ERR_OK}, - {"CEDTONE", T30_ERR_CEDTONE}, - {"T0_EXPIRED", T30_ERR_T0_EXPIRED}, - {"T1_EXPIRED", T30_ERR_T1_EXPIRED}, - {"T3_EXPIRED", T30_ERR_T3_EXPIRED}, - {"HDLC_CARRIER", T30_ERR_HDLC_CARRIER}, - {"CANNOT_TRAIN", T30_ERR_CANNOT_TRAIN}, - {"OPER_INT_FAIL", T30_ERR_OPER_INT_FAIL}, - {"INCOMPATIBLE", T30_ERR_INCOMPATIBLE}, - {"RX_INCAPABLE", T30_ERR_RX_INCAPABLE}, - {"TX_INCAPABLE", T30_ERR_TX_INCAPABLE}, - {"NORESSUPPORT", T30_ERR_NORESSUPPORT}, - {"NOSIZESUPPORT", T30_ERR_NOSIZESUPPORT}, - {"UNEXPECTED", T30_ERR_UNEXPECTED}, - {"TX_BADDCS", T30_ERR_TX_BADDCS}, - {"TX_BADPG", T30_ERR_TX_BADPG}, - {"TX_ECMPHD", T30_ERR_TX_ECMPHD}, - {"TX_GOTDCN", T30_ERR_TX_GOTDCN}, - {"TX_INVALRSP", T30_ERR_TX_INVALRSP}, - {"TX_NODIS", T30_ERR_TX_NODIS}, - {"TX_PHBDEAD", T30_ERR_TX_PHBDEAD}, - {"TX_PHDDEAD", T30_ERR_TX_PHDDEAD}, - {"TX_T5EXP", T30_ERR_TX_T5EXP}, - {"RX_ECMPHD", T30_ERR_RX_ECMPHD}, - {"RX_GOTDCS", T30_ERR_RX_GOTDCS}, - {"RX_INVALCMD", T30_ERR_RX_INVALCMD}, - {"RX_NOCARRIER", T30_ERR_RX_NOCARRIER}, - {"RX_NOEOL", T30_ERR_RX_NOEOL}, - {"RX_NOFAX", T30_ERR_RX_NOFAX}, - {"RX_T2EXPDCN", T30_ERR_RX_T2EXPDCN}, - {"RX_T2EXPD", T30_ERR_RX_T2EXPD}, - {"RX_T2EXPFAX", T30_ERR_RX_T2EXPFAX}, - {"RX_T2EXPMPS", T30_ERR_RX_T2EXPMPS}, - {"RX_T2EXPRR", T30_ERR_RX_T2EXPRR}, - {"RX_T2EXP", T30_ERR_RX_T2EXP}, - {"RX_DCNWHY", T30_ERR_RX_DCNWHY}, - {"RX_DCNDATA", T30_ERR_RX_DCNDATA}, - {"RX_DCNFAX", T30_ERR_RX_DCNFAX}, - {"RX_DCNPHD", T30_ERR_RX_DCNPHD}, - {"RX_DCNRRD", T30_ERR_RX_DCNRRD}, - {"RX_DCNNORTN", T30_ERR_RX_DCNNORTN}, - {"FILEERROR", T30_ERR_FILEERROR}, - {"NOPAGE", T30_ERR_NOPAGE}, - {"BADTIFF", T30_ERR_BADTIFF}, - {"BADPAGE", T30_ERR_BADPAGE}, - {"BADTAG", T30_ERR_BADTAG}, - {"BADTIFFHDR", T30_ERR_BADTIFFHDR}, - {"NOMEM", T30_ERR_NOMEM}, - {"RETRYDCN", T30_ERR_RETRYDCN}, - {"CALLDROPPED", T30_ERR_CALLDROPPED}, - {"NOPOLL", T30_ERR_NOPOLL}, - {"IDENT_UNACCEPTABLE", T30_ERR_IDENT_UNACCEPTABLE}, - {"SUB_UNACCEPTABLE", T30_ERR_SUB_UNACCEPTABLE}, - {"SEP_UNACCEPTABLE", T30_ERR_SEP_UNACCEPTABLE}, - {"PSA_UNACCEPTABLE", T30_ERR_PSA_UNACCEPTABLE}, - {"SID_UNACCEPTABLE", T30_ERR_SID_UNACCEPTABLE}, - {"PWD_UNACCEPTABLE", T30_ERR_PWD_UNACCEPTABLE}, - {"TSA_UNACCEPTABLE", T30_ERR_TSA_UNACCEPTABLE}, - {"IRA_UNACCEPTABLE", T30_ERR_IRA_UNACCEPTABLE}, - {"CIA_UNACCEPTABLE", T30_ERR_CIA_UNACCEPTABLE}, - {"ISP_UNACCEPTABLE", T30_ERR_ISP_UNACCEPTABLE}, - {"CSA_UNACCEPTABLE", T30_ERR_CSA_UNACCEPTABLE}, - {NULL, -1} -}; - -static int phase_b_handler(void *user_data, int result) -{ - int ch; - int status; - t30_state_t *s; - const char *u; - - s = (t30_state_t *) user_data; - ch = 'A'; - status = T30_ERR_OK; - if ((u = t30_get_rx_ident(s))) - { - printf("%c: Phase B: remote ident '%s'\n", ch, u); - if (expected_rx_info.ident[0] && strcmp(expected_rx_info.ident, u)) - { - printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", ch, expected_rx_info.ident); - status = T30_ERR_IDENT_UNACCEPTABLE; - } - } - else - { - if (expected_rx_info.ident[0]) - { - printf("%c: Phase B: remote ident missing!\n", ch); - status = T30_ERR_IDENT_UNACCEPTABLE; - } - } - if ((u = t30_get_rx_sub_address(s))) - { - printf("%c: Phase B: remote sub-address '%s'\n", ch, u); - if (expected_rx_info.sub_address[0] && strcmp(expected_rx_info.sub_address, u)) - { - printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", ch, expected_rx_info.sub_address); - status = T30_ERR_SUB_UNACCEPTABLE; - } - } - else - { - if (expected_rx_info.sub_address[0]) - { - printf("%c: Phase B: remote sub-address missing!\n", ch); - status = T30_ERR_SUB_UNACCEPTABLE; - } - } - if ((u = t30_get_rx_polled_sub_address(s))) - { - printf("%c: Phase B: remote polled sub-address '%s'\n", ch, u); - if (expected_rx_info.polled_sub_address[0] && strcmp(expected_rx_info.polled_sub_address, u)) - { - printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", ch, expected_rx_info.polled_sub_address); - status = T30_ERR_PSA_UNACCEPTABLE; - } - } - else - { - if (expected_rx_info.polled_sub_address[0]) - { - printf("%c: Phase B: remote polled sub-address missing!\n", ch); - status = T30_ERR_PSA_UNACCEPTABLE; - } - } - if ((u = t30_get_rx_selective_polling_address(s))) - { - printf("%c: Phase B: remote selective polling address '%s'\n", ch, u); - if (expected_rx_info.selective_polling_address[0] && strcmp(expected_rx_info.selective_polling_address, u)) - { - printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", ch, expected_rx_info.selective_polling_address); - status = T30_ERR_SEP_UNACCEPTABLE; - } - } - else - { - if (expected_rx_info.selective_polling_address[0]) - { - printf("%c: Phase B: remote selective polling address missing!\n", ch); - status = T30_ERR_SEP_UNACCEPTABLE; - } - } - if ((u = t30_get_rx_sender_ident(s))) - { - printf("%c: Phase B: remote sender ident '%s'\n", ch, u); - if (expected_rx_info.sender_ident[0] && strcmp(expected_rx_info.sender_ident, u)) - { - printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", ch, expected_rx_info.sender_ident); - status = T30_ERR_SID_UNACCEPTABLE; - } - } - else - { - if (expected_rx_info.sender_ident[0]) - { - printf("%c: Phase B: remote sender ident missing!\n", ch); - status = T30_ERR_SID_UNACCEPTABLE; - } - } - if ((u = t30_get_rx_password(s))) - { - printf("%c: Phase B: remote password '%s'\n", ch, u); - if (expected_rx_info.password[0] && strcmp(expected_rx_info.password, u)) - { - printf("%c: Phase B: remote password incorrect! - expected '%s'\n", ch, expected_rx_info.password); - status = T30_ERR_PWD_UNACCEPTABLE; - } - } - else - { - if (expected_rx_info.password[0]) - { - printf("%c: Phase B: remote password missing!\n", ch); - status = T30_ERR_PWD_UNACCEPTABLE; - } - } - printf("%c: Phase B handler on channel %d - (0x%X) %s\n", ch, ch, result, t30_frametype(result)); - return status; -} -/*- End of function --------------------------------------------------------*/ - -static int phase_d_handler(void *user_data, int result) -{ - int i; - int ch; - t30_state_t *s; - char tag[20]; - - i = 0; - s = (t30_state_t *) user_data; - ch = i + 'A'; - snprintf(tag, sizeof(tag), "%c: Phase D", ch); - printf("%c: Phase D handler on channel %c - (0x%X) %s\n", ch, ch, result, t30_frametype(result)); - fax_log_page_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); - - if (use_receiver_not_ready) - t30_set_receiver_not_ready(s, 3); - - if (test_local_interrupt) - { - if (i == 0) - { - printf("%c: Initiating interrupt request\n", ch); - t30_local_interrupt_request(s, true); - } - else - { - switch (result) - { - case T30_PIP: - case T30_PRI_MPS: - case T30_PRI_EOM: - case T30_PRI_EOP: - printf("%c: Accepting interrupt request\n", ch); - t30_local_interrupt_request(s, true); - break; - case T30_PIN: - break; - } - } - } - return T30_ERR_OK; -} -/*- End of function --------------------------------------------------------*/ - -static void phase_e_handler(void *user_data, int result) -{ - int ch; - t30_state_t *s; - char tag[20]; - - ch = 'A'; - s = (t30_state_t *) user_data; - snprintf(tag, sizeof(tag), "%c: Phase E", ch); - printf("%c: Phase E handler on channel %c - (%d) %s\n", ch, ch, result, t30_completion_code_to_str(result)); - fax_log_final_transfer_statistics(s, tag); - fax_log_tx_parameters(s, tag); - fax_log_rx_parameters(s, tag); -} -/*- End of function --------------------------------------------------------*/ - -static void t30_real_time_frame_handler(void *user_data, - bool incoming, - const uint8_t *msg, - int len) -{ - if (msg == NULL) - { - } - else - { - fprintf(stderr, - "T.30: Real time frame handler - %s, %s, length = %d\n", - (incoming) ? "line->T.30" : "T.30->line", - t30_frametype(msg[2]), - len); - } -} -/*- End of function --------------------------------------------------------*/ - -static int document_handler(void *user_data, int event) -{ - int ch; - t30_state_t *s; - - ch = 'A'; - s = (t30_state_t *) user_data; - 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); - next_tx_file[0] = '\0'; - return true; - } - return false; -} -/*- End of function --------------------------------------------------------*/ - -static void faxtester_real_time_frame_handler(faxtester_state_t *s, - void *user_data, - int direction, - const uint8_t *msg, - int len) -{ - if (msg == NULL) - { - while (next_step(s) == 0) - ; - /*endwhile*/ - } - else - { - fprintf(stderr, - "TST: Real time frame handler - %s, %s, length = %d\n", - (direction) ? "line->tester" : "tester->line", - t30_frametype(msg[2]), - len); - if (direction && msg[1] == awaited[1]) - { - if ((awaited_len >= 0 && len != abs(awaited_len)) - || - (awaited_len < 0 && len < abs(awaited_len)) - || - memcmp(msg, awaited, abs(awaited_len)) != 0) - { - span_log_buf(&s->logging, SPAN_LOG_FLOW, "Expected", awaited, abs(awaited_len)); - span_log_buf(&s->logging, SPAN_LOG_FLOW, "Received", msg, len); - printf("Test failed\n"); - exit(2); - } - } - if (msg[1] == awaited[1]) - { - while (next_step(s) == 0) - ; - /*endwhile*/ - } - } -} -/*- End of function --------------------------------------------------------*/ - -static void faxtester_front_end_step_complete_handler(faxtester_state_t *s, void *user_data) -{ - while (next_step(s) == 0) - ; - /*endwhile*/ -} -/*- End of function --------------------------------------------------------*/ - -static void faxtester_front_end_step_timeout_handler(faxtester_state_t *s, void *user_data) -{ - span_log(&s->logging, SPAN_LOG_FLOW, "FAX tester step timed out\n"); - printf("Test failed\n"); - exit(2); -} -/*- End of function --------------------------------------------------------*/ - -static void fax_prepare(void) -{ - t30_state_t *t30; - logging_state_t *logging; - - t30 = fax_get_t30_state(fax); - fax_set_transmit_on_idle(fax, true); - fax_set_tep_mode(fax, true); -#if 0 - t30_set_tx_ident(t30, "1234567890"); - t30_set_tx_sub_address(t30, "Sub-address"); - t30_set_tx_sender_ident(t30, "Sender ID"); - t30_set_tx_password(t30, "Password"); - t30_set_tx_polled_sub_address(t30, "Polled sub-address"); - t30_set_tx_selective_polling_address(t30, "Sel polling address"); -#endif - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSF\x00", 16); - //t30_set_tx_nss(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSS\x00", 16); - t30_set_tx_nsc(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSC\x00", 16); - t30_set_ecm_capability(t30, true); - t30_set_supported_t30_features(t30, - T30_SUPPORT_IDENTIFICATION - | T30_SUPPORT_SELECTIVE_POLLING - | T30_SUPPORT_SUB_ADDRESSING); - t30_set_supported_image_sizes(t30, - T4_SUPPORT_WIDTH_215MM - | T4_SUPPORT_WIDTH_255MM - | T4_SUPPORT_WIDTH_303MM - | T4_SUPPORT_LENGTH_US_LETTER - | T4_SUPPORT_LENGTH_US_LEGAL - | T4_SUPPORT_LENGTH_UNLIMITED); - t30_set_supported_bilevel_resolutions(t30, - T4_RESOLUTION_R8_STANDARD - | T4_RESOLUTION_R8_FINE - | T4_RESOLUTION_R8_SUPERFINE - | T4_RESOLUTION_R16_SUPERFINE - | T4_RESOLUTION_100_100 - | T4_RESOLUTION_200_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_200_400 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_300_600 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_400_800 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_600_1200 - | T4_RESOLUTION_1200_1200); - t30_set_supported_colour_resolutions(t30, 0); - t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17); - t30_set_supported_compressions(t30, T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6); - t30_set_phase_b_handler(t30, phase_b_handler, (void *) t30); - t30_set_phase_d_handler(t30, phase_d_handler, (void *) t30); - t30_set_phase_e_handler(t30, phase_e_handler, (void *) t30); - t30_set_real_time_frame_handler(t30, t30_real_time_frame_handler, (void *) t30); - t30_set_document_handler(t30, document_handler, (void *) t30); - - logging = fax_get_logging_state(fax); - 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); - span_log_set_tag(logging, "A"); - - logging = t30_get_logging_state(t30); - 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); - span_log_set_tag(logging, "A"); - -#if 0 - span_log_set_level(&fax.modems.v27ter_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(&fax.modems.v27ter_rx.logging, "A"); - span_log_set_level(&fax.modems.v29_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(&fax.modems.v29_rx.logging, "A"); - span_log_set_level(&fax.modems.v17_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(&fax.modems.v17_rx.logging, "A"); -#endif -} -/*- End of function --------------------------------------------------------*/ - -static int string_to_msg(uint8_t msg[], uint8_t mask[], const char buf[]) -{ - int i; - int x; - const char *t; - - msg[0] = 0; - mask[0] = 0xFF; - i = 0; - t = (char *) buf; - while (*t) - { - /* Skip white space */ - while (isspace((int) *t)) - t++; - /* If we find ... we allow arbitrary addition info beyond this point in the message */ - if (t[0] == '.' && t[1] == '.' && t[2] == '.') - { - return -i; - } - else if (isxdigit((int) *t)) - { - for ( ; isxdigit((int) *t); t++) - { - x = *t; - if (x >= 'a') - x -= 0x20; - if (x >= 'A') - x -= ('A' - 10); - else - x -= '0'; - msg[i] = (msg[i] << 4) | x; - } - mask[i] = 0xFF; - if (*t == '/') - { - /* There is a mask following the byte */ - mask[i] = 0; - for (t++; isxdigit((int) *t); t++) - { - x = *t; - if (x >= 'a') - x -= 0x20; - if (x >= 'A') - x -= ('A' - 10); - else - x -= '0'; - mask[i] = (mask[i] << 4) | x; - } - } - if (*t && !isspace((int) *t)) - { - /* Bad string */ - return 0; - } - i++; - } - } - return i; -} -/*- End of function --------------------------------------------------------*/ - -#if 0 -static void string_test2(const uint8_t msg[], int len) -{ - int i; - - if (len > 0) - { - for (i = 0; i < len - 1; i++) - printf("%02X ", msg[i]); - printf("%02X", msg[i]); - } -} -/*- End of function --------------------------------------------------------*/ - -static void string_test3(const char buf[]) -{ - uint8_t msg[1000]; - uint8_t mask[1000]; - int len; - int i; - - len = string_to_msg(msg, mask, buf); - printf("Len = %d: ", len); - string_test2(msg, abs(len)); - printf("/"); - string_test2(mask, abs(len)); - printf("\n"); -} -/*- End of function --------------------------------------------------------*/ - -static int string_test(void) -{ - string_test3("FF C8 12 34 56 78"); - string_test3("FF C8 12/55 34 56/aA 78 "); - string_test3("FF C8 12/55 34 56/aA 78 ..."); - string_test3("FF C8 12/55 34 56/aA 78..."); - string_test3("FF C8 12/55 34 56/aA 78 ... 99 88 77"); - exit(0); -} -/*- End of function --------------------------------------------------------*/ -#endif - -static void corrupt_image(faxtester_state_t *s, uint8_t image[], int len, const char *bad_rows) -{ - int i; - int j; - int k; - uint32_t bits; - uint32_t bitsx; - int list[1000]; - int x; - int row; - const char *t; - - /* Form the list of rows to be hit */ - x = 0; - t = bad_rows; - while (*t) - { - while (isspace((int) *t)) - t++; - if (sscanf(t, "%d", &list[x]) < 1) - break; - x++; - while (isdigit((int) *t)) - t++; - if (*t == ',') - t++; - } - - /* Go through the image, and corrupt the first bit of every listed row */ - bits = 0x7FF; - bitsx = 0x7FF; - row = 0; - for (i = 0; i < len; i++) - { - bits ^= (image[i] << 11); - bitsx ^= (image[i] << 11); - for (j = 0; j < 8; j++) - { - if ((bits & 0xFFF) == 0x800) - { - /* We are at an EOL. Is this row in the list of rows to be corrupted? */ - row++; - for (k = 0; k < x; k++) - { - if (list[k] == row) - { - /* Corrupt this row. TSB85 says to hit the first bit after the EOL */ - bitsx ^= 0x1000; - } - } - } - bits >>= 1; - bitsx >>= 1; - } - image[i] = (bitsx >> 3) & 0xFF; - } - span_log(&s->logging, SPAN_LOG_FLOW, "%d rows found. %d corrupted\n", row, x); -} -/*- End of function --------------------------------------------------------*/ - -static int next_step(faxtester_state_t *s) -{ - int delay; - int flags; - xmlChar *dir; - xmlChar *type; - xmlChar *modem; - xmlChar *value; - xmlChar *tag; - xmlChar *bad_rows; - xmlChar *crc_error; - xmlChar *pattern; - xmlChar *timein; - xmlChar *timeout; - xmlChar *min_bits; - xmlChar *frame_size; - xmlChar *block; - xmlChar *compression; - uint8_t buf[1000]; - uint8_t mask[1000]; - char path[1024]; - int i; - int j; - int hdlc; - int short_train; - int min_row_bits; - int ecm_frame_size; - int ecm_block; - int compression_type; - int len; - t4_tx_state_t t4_tx_state; - t30_state_t *t30; - t30_stats_t t30_stats; - - test_for_call_clear = false; - if (s->cur == NULL) - { - if (!s->final_delayed) - { - /* Add a bit of waiting at the end, to ensure everything gets flushed through, - any timers can expire, etc. */ - faxtester_set_timeout(s, -1); - faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); - faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, 120000, false); - s->final_delayed = true; - return 1; - } - /* Finished */ - printf("Test passed\n"); - exit(0); - } - while (s->cur && xmlStrcmp(s->cur->name, (const xmlChar *) "step") != 0) - s->cur = s->cur->next; - if (s->cur == NULL) - { - /* Finished */ - printf("Test passed\n"); - exit(0); - } - - dir = xmlGetProp(s->cur, (const xmlChar *) "dir"); - type = xmlGetProp(s->cur, (const xmlChar *) "type"); - modem = xmlGetProp(s->cur, (const xmlChar *) "modem"); - value = xmlGetProp(s->cur, (const xmlChar *) "value"); - tag = xmlGetProp(s->cur, (const xmlChar *) "tag"); - bad_rows = xmlGetProp(s->cur, (const xmlChar *) "bad_rows"); - crc_error = xmlGetProp(s->cur, (const xmlChar *) "crc_error"); - pattern = xmlGetProp(s->cur, (const xmlChar *) "pattern"); - timein = xmlGetProp(s->cur, (const xmlChar *) "timein"); - timeout = xmlGetProp(s->cur, (const xmlChar *) "timeout"); - min_bits = xmlGetProp(s->cur, (const xmlChar *) "min_bits"); - frame_size = xmlGetProp(s->cur, (const xmlChar *) "frame_size"); - block = xmlGetProp(s->cur, (const xmlChar *) "block"); - compression = xmlGetProp(s->cur, (const xmlChar *) "compression"); - - s->cur = s->cur->next; - - span_log(&s->logging, - SPAN_LOG_FLOW, - "Dir - %s, type - %s, modem - %s, value - %s, timein - %s, timeout - %s, tag - %s\n", - (dir) ? (const char *) dir : "", - (type) ? (const char *) type : "", - (modem) ? (const char *) modem : "", - (value) ? (const char *) value : "", - (timein) ? (const char *) timein : "", - (timeout) ? (const char *) timeout : "", - (tag) ? (const char *) tag : ""); - if (type == NULL) - return 1; - if (timein) - timein_x = atoi((const char *) timein); - else - timein_x = -1; - if (timeout) - timeout_x = atoi((const char *) timeout); - else - timeout_x = -1; - - if (dir && strcasecmp((const char *) dir, "R") == 0) - { - /* Receive always has a timeout applied. */ - if (timeout_x < 0) - timeout_x = 7000; - faxtester_set_timeout(s, timeout_x); - if (modem) - { - hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0); - short_train = (strcasecmp((const char *) type, "TCF") != 0); - faxtester_set_tx_type(s, T30_MODEM_NONE, 0, false, false); - if (strcasecmp((const char *) modem, "V.21") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V21, 300, false, true); - } - else if (strcasecmp((const char *) modem, "V.17/14400") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V17, 14400, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.17/12000") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V17, 12000, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.17/9600") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V17, 9600, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.17/7200") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V17, 7200, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.29/9600") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V29, 9600, false, hdlc); - } - else if (strcasecmp((const char *) modem, "V.29/7200") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V29, 7200, false, hdlc); - } - else if (strcasecmp((const char *) modem, "V.27ter/4800") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V27TER, 4800, false, hdlc); - } - else if (strcasecmp((const char *) modem, "V.27ter/2400") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_V27TER, 2400, false, hdlc); - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n"); - } - } - - if (strcasecmp((const char *) type, "SET") == 0) - { - if (strcasecmp((const char *) tag, "IDENT") == 0) - strcpy(expected_rx_info.ident, (const char *) value); - else if (strcasecmp((const char *) tag, "SUB") == 0) - strcpy(expected_rx_info.sub_address, (const char *) value); - else if (strcasecmp((const char *) tag, "SEP") == 0) - strcpy(expected_rx_info.selective_polling_address, (const char *) value); - else if (strcasecmp((const char *) tag, "PSA") == 0) - strcpy(expected_rx_info.polled_sub_address, (const char *) value); - else if (strcasecmp((const char *) tag, "SID") == 0) - strcpy(expected_rx_info.sender_ident, (const char *) value); - else if (strcasecmp((const char *) tag, "PWD") == 0) - strcpy(expected_rx_info.password, (const char *) value); - return 0; - } - else if (strcasecmp((const char *) type, "CNG") == 0) - { - /* Look for CNG */ - faxtester_set_rx_type(s, T30_MODEM_CNG, 0, false, false); - faxtester_set_tx_type(s, T30_MODEM_NONE, 0, false, false); - } - else if (strcasecmp((const char *) type, "CED") == 0) - { - /* Look for CED */ - faxtester_set_rx_type(s, T30_MODEM_CED, 0, false, false); - faxtester_set_tx_type(s, T30_MODEM_NONE, 0, false, false); - } - else if (strcasecmp((const char *) type, "HDLC") == 0) - { - i = string_to_msg(buf, mask, (const char *) value); - bit_reverse(awaited, buf, abs(i)); - awaited_len = i; - } - else if (strcasecmp((const char *) type, "TCF") == 0) - { - } - else if (strcasecmp((const char *) type, "MSG") == 0) - { - } - else if (strcasecmp((const char *) type, "PP") == 0) - { - } - else if (strcasecmp((const char *) type, "SILENCE") == 0) - { - faxtest_set_rx_silence(s); - } - else if (strcasecmp((const char *) type, "CLEAR") == 0) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Far end should drop the call\n"); - test_for_call_clear = true; - call_clear_timer = 0; - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised type '%s'\n", (const char *) type); - return 0; - } - } - else - { - faxtester_set_timeout(s, timeout_x); - if (modem) - { - hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0); - short_train = (strcasecmp((const char *) type, "TCF") != 0); - faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); - if (strcasecmp((const char *) modem, "V.21") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V21, 300, false, true); - } - else if (strcasecmp((const char *) modem, "V.17/14400") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V17, 14400, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.17/12000") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V17, 12000, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.17/9600") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V17, 9600, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.17/7200") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V17, 7200, short_train, hdlc); - } - else if (strcasecmp((const char *) modem, "V.29/9600") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V29, 9600, false, hdlc); - } - else if (strcasecmp((const char *) modem, "V.29/7200") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V29, 7200, false, hdlc); - } - else if (strcasecmp((const char *) modem, "V.27ter/4800") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V27TER, 4800, false, hdlc); - } - else if (strcasecmp((const char *) modem, "V.27ter/2400") == 0) - { - faxtester_set_tx_type(s, T30_MODEM_V27TER, 2400, false, hdlc); - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n"); - } - } - - if (strcasecmp((const char *) type, "SET") == 0) - { - t30 = fax_get_t30_state(fax); - if (strcasecmp((const char *) tag, "IDENT") == 0) - t30_set_tx_ident(t30, (const char *) value); - else if (strcasecmp((const char *) tag, "SUB") == 0) - t30_set_tx_sub_address(t30, (const char *) value); - else if (strcasecmp((const char *) tag, "SEP") == 0) - t30_set_tx_selective_polling_address(t30, (const char *) value); - else if (strcasecmp((const char *) tag, "PSA") == 0) - t30_set_tx_polled_sub_address(t30, (const char *) value); - else if (strcasecmp((const char *) tag, "SID") == 0) - t30_set_tx_sender_ident(t30, (const char *) value); - else if (strcasecmp((const char *) tag, "PWD") == 0) - t30_set_tx_password(t30, (const char *) value); - else if (strcasecmp((const char *) tag, "RXFILE") == 0) - { - if (value) - t30_set_rx_file(t30, (const char *) value, -1); - else - t30_set_rx_file(t30, output_tiff_file_name, -1); - } - else if (strcasecmp((const char *) tag, "TXFILE") == 0) - { - sprintf(next_tx_file, "%s/%s", image_path, (const char *) value); - printf("Push '%s'\n", next_tx_file); - } - return 0; - } - else if (strcasecmp((const char *) type, "CALL") == 0) - { - fax = fax_init(NULL, false); - fax_prepare(); - next_tx_file[0] = '\0'; - t30 = fax_get_t30_state(fax); - t30_set_rx_file(t30, output_tiff_file_name, -1); - /* Avoid libtiff 3.8.2 and earlier bug on complex 2D lines. */ - t30_set_supported_output_compressions(t30, T4_COMPRESSION_T4_1D); - if (value) - { - sprintf(path, "%s/%s", image_path, (const char *) value); - t30_set_tx_file(t30, path, -1, -1); - } - return 0; - } - else if (strcasecmp((const char *) type, "ANSWER") == 0) - { - fax = fax_init(NULL, true); - fax_prepare(); - next_tx_file[0] = '\0'; - t30 = fax_get_t30_state(fax); - /* Avoid libtiff 3.8.2 and earlier bug on complex 2D lines. */ - t30_set_supported_output_compressions(t30, T4_COMPRESSION_T4_1D); - if (value) - { - sprintf(path, "%s/%s", image_path, (const char *) value); - t30_set_tx_file(t30, path, -1, -1); - } - return 0; - } - else if (strcasecmp((const char *) type, "CNG") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); - faxtester_set_tx_type(s, T30_MODEM_CNG, 0, false, false); - } - else if (strcasecmp((const char *) type, "CED") == 0) - { - faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); - faxtester_set_tx_type(s, T30_MODEM_CED, 0, false, false); - } - else if (strcasecmp((const char *) type, "WAIT") == 0) - { - delay = (value) ? atoi((const char *) value) : 1; - faxtester_set_rx_type(s, T30_MODEM_NONE, 0, false, false); - faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, delay, false); - } - else if (strcasecmp((const char *) type, "PREAMBLE") == 0) - { - flags = (value) ? atoi((const char *) value) : 37; - faxtester_send_hdlc_flags(s, flags); - } - else if (strcasecmp((const char *) type, "POSTAMBLE") == 0) - { - flags = (value) ? atoi((const char *) value) : 5; - faxtester_send_hdlc_flags(s, flags); - } - else if (strcasecmp((const char *) type, "HDLC") == 0) - { - i = string_to_msg(buf, mask, (const char *) value); - bit_reverse(buf, buf, abs(i)); - if (crc_error && strcasecmp((const char *) crc_error, "0") == 0) - faxtester_send_hdlc_msg(s, buf, abs(i), false); - else - faxtester_send_hdlc_msg(s, buf, abs(i), true); - } - else if (strcasecmp((const char *) type, "TCF") == 0) - { - if (value) - i = atoi((const char *) value); - else - i = 450; - if (pattern) - { - /* TODO: implement proper patterns */ - j = atoi((const char *) pattern); - memset(image, 0x55, j); - if (i > j) - memset(image + j, 0, i - j); - } - else - { - memset(image, 0, i); - } - faxtester_set_non_ecm_image_buffer(s, image, i); - } - else if (strcasecmp((const char *) type, "MSG") == 0) - { - /* A non-ECM page */ - min_row_bits = (min_bits) ? atoi((const char *) min_bits) : 0; - sprintf(path, "%s/%s", image_path, (const char *) value); - if (t4_tx_init(&t4_tx_state, path, -1, -1) == NULL) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Failed to init T.4 send\n"); - printf("Test failed\n"); - exit(2); - } - t4_tx_set_header_info(&t4_tx_state, NULL); - compression_type = T4_COMPRESSION_T4_1D; - if (compression) - { - if (strcasecmp((const char *) compression, "T.4 2D") == 0) - compression_type = T4_COMPRESSION_T4_2D; - else if (strcasecmp((const char *) compression, "T.6") == 0) - compression_type = T4_COMPRESSION_T6; - } - if (t4_tx_set_tx_image_format(&t4_tx_state, - compression_type, - T4_SUPPORT_WIDTH_215MM - | T4_SUPPORT_LENGTH_US_LETTER - | T4_SUPPORT_LENGTH_US_LEGAL - | T4_SUPPORT_LENGTH_UNLIMITED, - T4_RESOLUTION_R8_STANDARD - | T4_RESOLUTION_R8_FINE - | T4_RESOLUTION_R8_SUPERFINE - | T4_RESOLUTION_R16_SUPERFINE - | T4_RESOLUTION_200_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_200_400 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_300_600 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_400_800 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_600_1200 - | T4_RESOLUTION_1200_1200, - T4_RESOLUTION_100_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_1200_1200) < 0) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Failed to set T.4 compression\n"); - printf("Test failed\n"); - exit(2); - } - t4_tx_set_min_bits_per_row(&t4_tx_state, min_row_bits); - if (t4_tx_start_page(&t4_tx_state)) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Failed to start T.4 send\n"); - printf("Test failed\n"); - exit(2); - } - len = t4_tx_get(&t4_tx_state, image, sizeof(image)); - if (bad_rows) - { - span_log(&s->logging, SPAN_LOG_FLOW, "We need to corrupt the image\n"); - corrupt_image(s, image, len, (const char *) bad_rows); - } - t4_tx_release(&t4_tx_state); - span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM image is %d bytes (min row bits %d)\n", len, min_row_bits); - faxtester_set_non_ecm_image_buffer(s, image, len); - } - else if (strcasecmp((const char *) type, "PP") == 0) - { - min_row_bits = (min_bits) ? atoi((const char *) min_bits) : 0; - ecm_block = (block) ? atoi((const char *) block) : 0; - ecm_frame_size = (frame_size) ? atoi((const char *) frame_size) : 64; - i = (crc_error) ? atoi((const char *) crc_error) : -1; - sprintf(path, "%s/%s", image_path, (const char *) value); - if (t4_tx_init(&t4_tx_state, path, -1, -1) == NULL) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Failed to init T.4 send\n"); - printf("Test failed\n"); - exit(2); - } - t4_tx_set_header_info(&t4_tx_state, NULL); - compression_type = T4_COMPRESSION_T4_1D; - if (compression) - { - if (strcasecmp((const char *) compression, "T.4 2D") == 0) - compression_type = T4_COMPRESSION_T4_2D; - else if (strcasecmp((const char *) compression, "T.6") == 0) - compression_type = T4_COMPRESSION_T6; - } - if (t4_tx_set_tx_image_format(&t4_tx_state, - compression_type, - T4_SUPPORT_WIDTH_215MM - | T4_SUPPORT_LENGTH_US_LETTER - | T4_SUPPORT_LENGTH_US_LEGAL - | T4_SUPPORT_LENGTH_UNLIMITED, - T4_RESOLUTION_R8_STANDARD - | T4_RESOLUTION_R8_FINE - | T4_RESOLUTION_R8_SUPERFINE - | T4_RESOLUTION_R16_SUPERFINE - | T4_RESOLUTION_200_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_200_400 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_300_600 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_400_800 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_600_1200 - | T4_RESOLUTION_1200_1200, - T4_RESOLUTION_100_100 - | T4_RESOLUTION_200_200 - | T4_RESOLUTION_300_300 - | T4_RESOLUTION_400_400 - | T4_RESOLUTION_600_600 - | T4_RESOLUTION_1200_1200) < 0) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Failed to set T.4 compression\n"); - printf("Test failed\n"); - exit(2); - } - t4_tx_set_min_bits_per_row(&t4_tx_state, min_row_bits); - if (t4_tx_start_page(&t4_tx_state)) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Failed to start T.4 send\n"); - printf("Test failed\n"); - exit(2); - } - /*endif*/ - len = t4_tx_get(&t4_tx_state, image, sizeof(image)); - if (bad_rows) - { - span_log(&s->logging, SPAN_LOG_FLOW, "We need to corrupt the image\n"); - corrupt_image(s, image, len, (const char *) bad_rows); - } - /*endif*/ - t4_tx_release(&t4_tx_state); - span_log(&s->logging, SPAN_LOG_FLOW, "ECM image is %d bytes (min row bits %d)\n", len, min_row_bits); - faxtester_set_ecm_image_buffer(s, image, len, ecm_block, ecm_frame_size, i); - } - else if (strcasecmp((const char *) type, "CLEAR") == 0) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Time to drop the call\n"); - t30 = fax_get_t30_state(fax); - t30_terminate(t30); - return 0; - } - else if (strcasecmp((const char *) type, "STATUS") == 0) - { - if (value) - { - for (i = 0; t30_status[i].code >= 0; i++) - { - if (strcmp(t30_status[i].tag, (const char *) value) == 0) - break; - } - if (t30_status[i].code >= 0) - delay = t30_status[i].code; - else - delay = atoi((const char *) value); - t30 = fax_get_t30_state(fax); - t30_get_transfer_statistics(t30, &t30_stats); - span_log(&s->logging, SPAN_LOG_FLOW, "Expect status %d. Got %d\n", delay, t30_stats.current_status); - if (delay != t30_stats.current_status) - { - printf("Test failed\n"); - exit(2); - } - } - return 0; - } - else - { - span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised type '%s'\n", (const char *) type); - return 0; - } - /*endif*/ - } - /*endif*/ - return 1; -} -/*- End of function --------------------------------------------------------*/ +faxtester_state_t *state; static void exchange(faxtester_state_t *s) { @@ -1270,21 +102,37 @@ static void exchange(faxtester_state_t *s) total_audio_time = 0; - faxtester_set_transmit_on_idle(&state, true); - faxtester_set_real_time_frame_handler(&state, faxtester_real_time_frame_handler, NULL); - faxtester_set_front_end_step_complete_handler(&state, faxtester_front_end_step_complete_handler, NULL); - faxtester_set_front_end_step_timeout_handler(&state, faxtester_front_end_step_timeout_handler, NULL); + faxtester_set_transmit_on_idle(s, true); - fax = fax_init(NULL, false); - fax_prepare(); - next_tx_file[0] = '\0'; + s->far_fax = fax_init(NULL, false); + s->far_t30 = fax_get_t30_state(s->far_fax); + s->far_tag = 'A'; - while (next_step(s) == 0) + if (s->far_fax) + logging = fax_get_logging_state(s->far_fax); + else + logging = t38_terminal_get_logging_state(s->far_t38); + 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); + span_log_set_tag(logging, "A"); + + logging = t30_get_logging_state(s->far_t30); + 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); + span_log_set_tag(logging, "A"); + +#if 0 + span_log_set_level(&fax.modems.v27ter_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); + span_log_set_tag(&fax.modems.v27ter_rx.logging, "A"); + span_log_set_level(&fax.modems.v29_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); + span_log_set_tag(&fax.modems.v29_rx.logging, "A"); + span_log_set_level(&fax.modems.v17_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); + span_log_set_tag(&fax.modems.v17_rx.logging, "A"); +#endif + while (faxtester_next_step(s) == 0) ; /*endwhile*/ for (;;) { - len = fax_tx(fax, amp, SAMPLES_PER_CHUNK); + len = fax_tx(s->far_fax, amp, SAMPLES_PER_CHUNK); faxtester_rx(s, amp, len); if (log_audio) { @@ -1296,20 +144,21 @@ static void exchange(faxtester_state_t *s) total_audio_time += SAMPLES_PER_CHUNK; - logging = t30_get_logging_state(fax_get_t30_state(fax)); + logging = t30_get_logging_state(s->far_t30); span_log_bump_samples(logging, len); #if 0 span_log_bump_samples(&fax.modems.v27ter_rx.logging, len); span_log_bump_samples(&fax.modems.v29_rx.logging, len); span_log_bump_samples(&fax.modems.v17_rx.logging, len); #endif - logging = fax_get_logging_state(fax); + logging = fax_get_logging_state(s->far_fax); span_log_bump_samples(logging, len); - span_log_bump_samples(&s->logging, len); + logging = faxtester_get_logging_state(s); + span_log_bump_samples(logging, len); len = faxtester_tx(s, amp, SAMPLES_PER_CHUNK); - if (fax_rx(fax, amp, len)) + if (fax_rx(s->far_fax, amp, len)) break; /*endif*/ if (log_audio) @@ -1322,21 +171,21 @@ static void exchange(faxtester_state_t *s) /*endif*/ } /*endif*/ - if (test_for_call_clear && !far_end_cleared_call) + if (s->test_for_call_clear && !s->far_end_cleared_call) { - call_clear_timer += len; - if (!t30_call_active(fax_get_t30_state(fax))) + s->call_clear_timer += len; + if (!t30_call_active(s->far_t30)) { - span_log(&s->logging, SPAN_LOG_FLOW, "Far end cleared after %dms (limits %dms to %dms)\n", call_clear_timer/8, timein_x, timeout_x); - if (call_clear_timer/8 < timein_x || call_clear_timer/8 > timeout_x) + span_log(faxtester_get_logging_state(s), SPAN_LOG_FLOW, "Far end cleared after %dms (limits %dms to %dms)\n", s->call_clear_timer/8, s->timein_x, s->timeout); + if (s->call_clear_timer/8 < s->timein_x || s->call_clear_timer/8 > s->timeout_x) { printf("Test failed\n"); exit(2); } - span_log(&s->logging, SPAN_LOG_FLOW, "Clear time OK\n"); - far_end_cleared_call = true; - test_for_call_clear = false; - while (next_step(s) == 0) + span_log(faxtester_get_logging_state(s), SPAN_LOG_FLOW, "Clear time OK\n"); + s->far_end_cleared_call = true; + s->test_for_call_clear = false; + while (faxtester_next_step(s) == 0) ; /*endwhile*/ } @@ -1359,154 +208,11 @@ static void exchange(faxtester_state_t *s) } /*- End of function --------------------------------------------------------*/ -static int parse_config(faxtester_state_t *s, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) -{ - xmlChar *x; - xmlChar *y; - - while (cur) - { - if (xmlStrcmp(cur->name, (const xmlChar *) "path") == 0) - { - if ((x = xmlGetProp(cur, (const xmlChar *) "type")) - && - (y = xmlGetProp(cur, (const xmlChar *) "value"))) - { - if (strcasecmp((const char *) x, "IMAGE") == 0) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Found '%s' '%s'\n", (char *) x, (char *) y); - strcpy(image_path, (const char *) y); - } - /*endif*/ - } - /*endif*/ - } - /*endif*/ - cur = cur->next; - } - /*endwhile*/ - return -1; -} -/*- End of function --------------------------------------------------------*/ - -static int parse_test_group(faxtester_state_t *s, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, const char *test) -{ - xmlChar *x; - - while (cur) - { - if (xmlStrcmp(cur->name, (const xmlChar *) "test") == 0) - { - if ((x = xmlGetProp(cur, (const xmlChar *) "name"))) - { - if (xmlStrcmp(x, (const xmlChar *) test) == 0) - { - span_log(&s->logging, SPAN_LOG_FLOW, "Found '%s'\n", (char *) x); - s->cur = cur->xmlChildrenNode; - return 0; - } - /*endif*/ - } - /*endif*/ - } - /*endif*/ - cur = cur->next; - } - /*endwhile*/ - return -1; -} -/*- End of function --------------------------------------------------------*/ - -static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test) -{ - xmlParserCtxtPtr ctxt; - xmlNsPtr ns; - xmlNodePtr cur; - - ns = NULL; - xmlKeepBlanksDefault(0); - xmlCleanupParser(); - - if ((ctxt = xmlNewParserCtxt()) == NULL) - { - fprintf(stderr, "Failed to allocate parser context\n"); - printf("Test failed\n"); - exit(2); - } - /* parse the file, activating the DTD validation option */ - 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"); - exit(2); - } - if (ctxt->valid == 0) - { - fprintf(stderr, "Failed to validate the XML document\n"); - xmlFreeDoc(s->doc); - xmlFreeParserCtxt(ctxt); - printf("Test failed\n"); - exit(2); - } - xmlFreeParserCtxt(ctxt); - - /* Check the document is of the right kind */ - if ((cur = xmlDocGetRootElement(s->doc)) == NULL) - { - xmlFreeDoc(s->doc); - fprintf(stderr, "Empty document\n"); - printf("Test failed\n"); - exit(2); - } - /*endif*/ - if (xmlStrcmp(cur->name, (const xmlChar *) "fax-tests")) - { - xmlFreeDoc(s->doc); - fprintf(stderr, "Document of the wrong type, root node != fax-tests"); - printf("Test failed\n"); - exit(2); - } - /*endif*/ - cur = cur->xmlChildrenNode; - while (cur && xmlIsBlankNode(cur)) - cur = cur->next; - /*endwhile*/ - if (cur == NULL) - { - printf("Test failed\n"); - exit(2); - } - /*endif*/ - while (cur) - { - if (xmlStrcmp(cur->name, (const xmlChar *) "config") == 0) - { - parse_config(s, s->doc, ns, cur->xmlChildrenNode); - } - /*endif*/ - if (xmlStrcmp(cur->name, (const xmlChar *) "test-group") == 0) - { - if (parse_test_group(s, s->doc, ns, cur->xmlChildrenNode, test) == 0) - { - /* We found the test we want, so run it. */ - exchange(s); - break; - } - /*endif*/ - } - /*endif*/ - cur = cur->next; - } - /*endwhile*/ - xmlFreeDoc(s->doc); - return 0; -} -/*- End of function --------------------------------------------------------*/ - int main(int argc, char *argv[]) { const char *xml_file_name; const char *test_name; + logging_state_t *logging; int opt; #if 0 @@ -1537,13 +243,18 @@ int main(int argc, char *argv[]) if (argc > 0) test_name = argv[0]; - strcpy(image_path, "."); - faxtester_init(&state, true); - memset(&expected_rx_info, 0, sizeof(expected_rx_info)); - span_log_set_level(&state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); - span_log_set_tag(&state.logging, "B"); - get_test_set(&state, xml_file_name, test_name); - faxtester_release(&state); + if ((state = faxtester_init(NULL, xml_file_name, test_name)) == NULL) + { + fprintf(stderr, "Cannot start FAX tester instance\n"); + printf("Test failed\n"); + exit(2); + } + logging = faxtester_get_logging_state(state); + 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); + span_log_set_tag(logging, "B"); + /* We found the test we want, so run it. */ + exchange(state); + faxtester_free(state); printf("Done\n"); return 0; } diff --git a/src/mod/endpoints/mod_gsmopen/mobigater b/src/mod/endpoints/mod_gsmopen/mobigater deleted file mode 120000 index cfea4c01b2..0000000000 --- a/src/mod/endpoints/mod_gsmopen/mobigater +++ /dev/null @@ -1 +0,0 @@ -alsa_nogsmlib_nocplusplus \ No newline at end of file