mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-24 13:12:03 +00:00
update to spandsp-20091222 snapshot
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16035 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: line_model.h,v 1.7 2009/09/23 16:02:59 steveu Exp $
|
||||
* $Id: line_model.h,v 1.7.4.1 2009/12/19 10:16:44 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -70,7 +70,7 @@ typedef struct
|
||||
codec_munge_state_t *munge;
|
||||
|
||||
/*! The coefficients for the near end analogue section simulation filter */
|
||||
float *near_filter;
|
||||
const float *near_filter;
|
||||
/*! The number of coefficients for the near end analogue section simulation filter */
|
||||
int near_filter_len;
|
||||
/*! Last transmitted samples (ring buffer, used by the line filter) */
|
||||
@@ -88,7 +88,7 @@ typedef struct
|
||||
int16_t bulk_delay_buf[8000];
|
||||
|
||||
/*! The coefficients for the far end analogue section simulation filter */
|
||||
float *far_filter;
|
||||
const float *far_filter;
|
||||
/*! The number of coefficients for the far end analogue section simulation filter */
|
||||
int far_filter_len;
|
||||
/*! Last transmitted samples (ring buffer, used by the line filter) */
|
||||
|
||||
@@ -16,13 +16,37 @@
|
||||
## License along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
##
|
||||
## $Id: Makefile.am,v 1.137 2009/09/22 14:52:31 steveu Exp $
|
||||
## $Id: Makefile.am,v 1.138.4.3 2009/12/19 10:30:10 steveu Exp $
|
||||
|
||||
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
||||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
DISTCLEANFILES = $(srcdir)/at_interpreter_dictionary.h \
|
||||
$(srcdir)/v17_v32bis_rx_fixed_rrc.h \
|
||||
$(srcdir)/v17_v32bis_rx_floating_rrc.h \
|
||||
$(srcdir)/v17_v32bis_tx_fixed_rrc.h \
|
||||
$(srcdir)/v17_v32bis_tx_floating_rrc.h \
|
||||
$(srcdir)/v22bis_rx_1200_fixed_rrc.h \
|
||||
$(srcdir)/v22bis_rx_2400_fixed_rrc.h \
|
||||
$(srcdir)/v22bis_rx_1200_floating_rrc.h \
|
||||
$(srcdir)/v22bis_rx_2400_floating_rrc.h \
|
||||
$(srcdir)/v22bis_tx_fixed_rrc.h \
|
||||
$(srcdir)/v22bis_tx_floating_rrc.h \
|
||||
$(srcdir)/v27ter_rx_2400_fixed_rrc.h \
|
||||
$(srcdir)/v27ter_rx_4800_fixed_rrc.h \
|
||||
$(srcdir)/v27ter_rx_2400_floating_rrc.h \
|
||||
$(srcdir)/v27ter_rx_4800_floating_rrc.h \
|
||||
$(srcdir)/v27ter_tx_2400_fixed_rrc.h \
|
||||
$(srcdir)/v27ter_tx_4800_fixed_rrc.h \
|
||||
$(srcdir)/v27ter_tx_2400_floating_rrc.h \
|
||||
$(srcdir)/v27ter_tx_4800_floating_rrc.h \
|
||||
$(srcdir)/v29rx_fixed_rrc.h \
|
||||
$(srcdir)/v29rx_floating_rrc.h \
|
||||
$(srcdir)/v29tx_fixed_rrc.h \
|
||||
$(srcdir)/v29tx_floating_rrc.h
|
||||
|
||||
EXTRA_DIST = floating_fudge.h \
|
||||
libspandsp.dsp \
|
||||
libspandsp.2005.sln \
|
||||
@@ -31,6 +55,9 @@ EXTRA_DIST = floating_fudge.h \
|
||||
libspandsp.2008.vcproj \
|
||||
libtiff.2005.vcproj \
|
||||
libtiff.2008.vcproj \
|
||||
filter_tools.c \
|
||||
make_at_dictionary.c \
|
||||
make_modem_filter.c \
|
||||
msvc/config.h \
|
||||
msvc/Download_TIFF.2005.vcproj \
|
||||
msvc/Download_TIFF.2008.vcproj \
|
||||
@@ -111,7 +138,8 @@ libspandsp_la_SOURCES = adsi.c \
|
||||
super_tone_rx.c \
|
||||
super_tone_tx.c \
|
||||
swept_tone.c \
|
||||
t4.c \
|
||||
t4_rx.c \
|
||||
t4_tx.c \
|
||||
t30.c \
|
||||
t30_api.c \
|
||||
t30_logging.c \
|
||||
@@ -190,7 +218,8 @@ nobase_include_HEADERS = spandsp/adsi.h \
|
||||
spandsp/super_tone_rx.h \
|
||||
spandsp/super_tone_tx.h \
|
||||
spandsp/swept_tone.h \
|
||||
spandsp/t4.h \
|
||||
spandsp/t4_rx.h \
|
||||
spandsp/t4_tx.h \
|
||||
spandsp/t30.h \
|
||||
spandsp/t30_api.h \
|
||||
spandsp/t30_fcf.h \
|
||||
@@ -252,12 +281,14 @@ nobase_include_HEADERS = spandsp/adsi.h \
|
||||
spandsp/private/super_tone_tx.h \
|
||||
spandsp/private/swept_tone.h \
|
||||
spandsp/private/t30.h \
|
||||
spandsp/private/t30_dis_dtc_dcs_bits.h \
|
||||
spandsp/private/t31.h \
|
||||
spandsp/private/t38_core.h \
|
||||
spandsp/private/t38_gateway.h \
|
||||
spandsp/private/t38_non_ecm_buffer.h \
|
||||
spandsp/private/t38_terminal.h \
|
||||
spandsp/private/t4.h \
|
||||
spandsp/private/t4_rx.h \
|
||||
spandsp/private/t4_tx.h \
|
||||
spandsp/private/time_scale.h \
|
||||
spandsp/private/tone_detect.h \
|
||||
spandsp/private/tone_generate.h \
|
||||
@@ -282,7 +313,7 @@ noinst_HEADERS = faxfont.h \
|
||||
lpc10_encdecs.h \
|
||||
mmx_sse_decs.h \
|
||||
t30_local.h \
|
||||
t4_states.h \
|
||||
t4_t6_decode_states.h \
|
||||
v17_v32bis_rx_constellation_maps.h \
|
||||
v17_v32bis_tx_constellation_maps.h \
|
||||
v29tx_constellation_maps.h
|
||||
@@ -290,7 +321,7 @@ noinst_HEADERS = faxfont.h \
|
||||
make_at_dictionary$(EXEEXT): $(top_srcdir)/src/make_at_dictionary.c
|
||||
$(CC_FOR_BUILD) -o make_at_dictionary$(EXEEXT) $(top_srcdir)/src/make_at_dictionary.c -DHAVE_CONFIG_H -I$(top_builddir)/src
|
||||
|
||||
make_modem_filter$(EXEEXT): $(top_srcdir)/src/make_modem_filter.c $(top_srcdir)/src/filter_tools.c
|
||||
make_modem_filter$(EXEEXT): $(top_srcdir)/src/make_modem_filter.c $(top_srcdir)/src/filter_tools.c
|
||||
$(CC_FOR_BUILD) -o make_modem_filter$(EXEEXT) $(top_srcdir)/src/make_modem_filter.c $(top_srcdir)/src/filter_tools.c -DHAVE_CONFIG_H -I$(top_builddir)/src -lm
|
||||
|
||||
# We need to run make_at_dictionary, so it generates the
|
||||
@@ -489,13 +520,10 @@ $(srcdir)/msvc/spandsp.h: spandsp.h.in
|
||||
-e "s/\@INSERT_MATH_HEADER\@/#include <math.h>/" $(srcdir)/spandsp.h.in > $(srcdir)/msvc/spandsp.h
|
||||
|
||||
spandsp/version.h:
|
||||
mkdir -p $(@D)
|
||||
NOWDATE=`date --utc +"%Y%m%d"` ; \
|
||||
NOWTIME=`date --utc +"%H%M%S"` ; \
|
||||
sed 's/$$SPANDSP_RELEASE_DATE/'$$NOWDATE'/;s/$$SPANDSP_RELEASE_TIME/'$$NOWTIME'/' \
|
||||
<spandsp/version.h.in >spandsp/version.h
|
||||
<$(srcdir)/spandsp/version.h.in >$@
|
||||
|
||||
dist-hook:
|
||||
NOWDATE=`date --utc +"%Y%m%d"` ; \
|
||||
NOWTIME=`date --utc +"%H%M%S"` ; \
|
||||
sed 's/$$SPANDSP_RELEASE_DATE/'$$NOWDATE'/;s/$$SPANDSP_RELEASE_TIME/'$$NOWTIME'/' \
|
||||
<spandsp/version.h.in >spandsp/version.h
|
||||
dist-hook: spandsp/version.h
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: adsi.c,v 1.76 2009/04/12 09:12:10 steveu Exp $
|
||||
* $Id: adsi.c,v 1.77 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -431,12 +431,12 @@ SPAN_DECLARE(adsi_rx_state_t *) adsi_rx_init(adsi_rx_state_t *s,
|
||||
switch (standard)
|
||||
{
|
||||
case ADSI_STANDARD_CLASS:
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_BELL202], FALSE, adsi_rx_put_bit, s);
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_BELL202], FSK_FRAME_MODE_ASYNC, adsi_rx_put_bit, s);
|
||||
break;
|
||||
case ADSI_STANDARD_CLIP:
|
||||
case ADSI_STANDARD_ACLIP:
|
||||
case ADSI_STANDARD_JCLIP:
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_V23CH1], FALSE, adsi_rx_put_bit, s);
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_V23CH1], FSK_FRAME_MODE_ASYNC, adsi_rx_put_bit, s);
|
||||
break;
|
||||
case ADSI_STANDARD_CLIP_DTMF:
|
||||
dtmf_rx_init(&(s->dtmfrx), adsi_rx_dtmf, s);
|
||||
@@ -444,7 +444,7 @@ SPAN_DECLARE(adsi_rx_state_t *) adsi_rx_init(adsi_rx_state_t *s,
|
||||
case ADSI_STANDARD_TDD:
|
||||
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
|
||||
ride over the fraction. */
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_WEITBRECHT], 7, adsi_tdd_put_async_byte, s);
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, adsi_tdd_put_async_byte, s);
|
||||
break;
|
||||
}
|
||||
s->standard = standard;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: at_interpreter.c,v 1.41 2009/10/03 04:37:25 steveu Exp $
|
||||
* $Id: at_interpreter.c,v 1.42 2009/10/09 14:53:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -3358,9 +3358,30 @@ static const char *at_cmd_plus_EWIND(at_state_t *s, const char *t)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static const char *at_cmd_plus_F34(at_state_t *s, const char *t)
|
||||
{
|
||||
static const int maxes[5] =
|
||||
{
|
||||
14, 14, 2, 14, 14
|
||||
};
|
||||
int *locations[5];
|
||||
int i;
|
||||
|
||||
/* T.31 B.6.1 - Initial V.34 rate controls for FAX */
|
||||
/* Syntax: +F34=[<maxp>][,[<minp>][,<prefc>][,<maxp2>][,<minp2]] */
|
||||
/* TODO */
|
||||
t += 4;
|
||||
for (i = 0; i < 5; i++)
|
||||
locations[i] = NULL;
|
||||
if (!parse_n_out(s, &t, locations, maxes, 5, "+F34:", "(0-14),(0-14),(0-2),(0-14),(0-14)"))
|
||||
return NULL;
|
||||
return t;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static const char *at_cmd_plus_FAA(at_state_t *s, const char *t)
|
||||
{
|
||||
/* T.32 8.5.2.5 - Adaptive Answer parameter */
|
||||
/* T.32 8.5.2.5 - Adaptive answer parameter */
|
||||
/* TODO */
|
||||
t += 4;
|
||||
return t;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax.c,v 1.94 2009/09/04 14:38:46 steveu Exp $
|
||||
* $Id: fax.c,v 1.96.4.1 2009/12/19 10:44:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -71,7 +71,8 @@
|
||||
#include "spandsp/v17rx.h"
|
||||
#include "spandsp/super_tone_rx.h"
|
||||
#include "spandsp/modem_connect_tones.h"
|
||||
#include "spandsp/t4.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
|
||||
#include "spandsp/t30_fcf.h"
|
||||
#include "spandsp/t35.h"
|
||||
@@ -94,7 +95,8 @@
|
||||
#include "spandsp/private/modem_connect_tones.h"
|
||||
#include "spandsp/private/hdlc.h"
|
||||
#include "spandsp/private/fax_modems.h"
|
||||
#include "spandsp/private/t4.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
#include "spandsp/private/fax.h"
|
||||
|
||||
@@ -110,12 +112,12 @@ static void fax_send_hdlc(void *user_data, const uint8_t *msg, int len)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void tone_detected(void *user_data, int on, int level, int delay)
|
||||
static void tone_detected(void *user_data, int tone, int level, int delay)
|
||||
{
|
||||
t30_state_t *s;
|
||||
|
||||
s = (t30_state_t *) user_data;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "FAX tone declared %s (%ddBm0)\n", (on) ? "on" : "off", level);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s detected (%ddBm0)\n", modem_connect_tone_to_str(tone), level);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@@ -423,7 +425,7 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t
|
||||
switch (type)
|
||||
{
|
||||
case T30_MODEM_V21:
|
||||
fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data);
|
||||
fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data);
|
||||
fsk_rx_signal_cutoff(&t->v21_rx, -45.5f);
|
||||
set_rx_handler(s, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &t->v21_rx);
|
||||
break;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax_modems.c,v 1.7 2009/10/05 16:33:25 steveu Exp $
|
||||
* $Id: fax_modems.c,v 1.8 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -45,6 +45,9 @@
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#if defined(LOG_FAX_AUDIO)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "spandsp/telephony.h"
|
||||
#include "spandsp/logging.h"
|
||||
@@ -280,7 +283,7 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
|
||||
|
||||
hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data);
|
||||
hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, user_data);
|
||||
fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx);
|
||||
fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx);
|
||||
fsk_rx_signal_cutoff(&s->v21_rx, -39.09f);
|
||||
fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);
|
||||
v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data);
|
||||
|
||||
+42
-28
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fsk.c,v 1.59 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: fsk.c,v 1.60 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -128,6 +128,22 @@ const fsk_spec_t preset_fsk_specs[] =
|
||||
}
|
||||
};
|
||||
|
||||
SPAN_DECLARE(int) fsk_tx_restart(fsk_tx_state_t *s, const fsk_spec_t *spec)
|
||||
{
|
||||
s->baud_rate = spec->baud_rate;
|
||||
s->phase_rates[0] = dds_phase_rate((float) spec->freq_zero);
|
||||
s->phase_rates[1] = dds_phase_rate((float) spec->freq_one);
|
||||
s->scaling = dds_scaling_dbm0((float) spec->tx_level);
|
||||
/* Initialise fractional sample baud generation. */
|
||||
s->phase_acc = 0;
|
||||
s->baud_frac = 0;
|
||||
s->current_phase_rate = s->phase_rates[1];
|
||||
|
||||
s->shutdown = FALSE;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(fsk_tx_state_t *) fsk_tx_init(fsk_tx_state_t *s,
|
||||
const fsk_spec_t *spec,
|
||||
get_bit_func_t get_bit,
|
||||
@@ -138,20 +154,11 @@ SPAN_DECLARE(fsk_tx_state_t *) fsk_tx_init(fsk_tx_state_t *s,
|
||||
if ((s = (fsk_tx_state_t *) malloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->baud_rate = spec->baud_rate;
|
||||
s->get_bit = get_bit;
|
||||
s->get_bit_user_data = user_data;
|
||||
|
||||
s->phase_rates[0] = dds_phase_rate((float) spec->freq_zero);
|
||||
s->phase_rates[1] = dds_phase_rate((float) spec->freq_one);
|
||||
s->scaling = dds_scaling_dbm0((float) spec->tx_level);
|
||||
/* Initialise fractional sample baud generation. */
|
||||
s->phase_acc = 0;
|
||||
s->baud_frac = 0;
|
||||
s->current_phase_rate = s->phase_rates[1];
|
||||
|
||||
s->shutdown = FALSE;
|
||||
fsk_tx_restart(s, spec);
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -250,26 +257,13 @@ SPAN_DECLARE(void) fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, modem_tx_s
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(fsk_rx_state_t *) fsk_rx_init(fsk_rx_state_t *s,
|
||||
const fsk_spec_t *spec,
|
||||
int framing_mode,
|
||||
put_bit_func_t put_bit,
|
||||
void *user_data)
|
||||
SPAN_DECLARE(int) fsk_rx_restart(fsk_rx_state_t *s, const fsk_spec_t *spec, int framing_mode)
|
||||
{
|
||||
int chop;
|
||||
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (fsk_rx_state_t *) malloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->baud_rate = spec->baud_rate;
|
||||
s->framing_mode = framing_mode;
|
||||
fsk_rx_signal_cutoff(s, (float) spec->min_level);
|
||||
s->put_bit = put_bit;
|
||||
s->put_bit_user_data = user_data;
|
||||
|
||||
/* Detect by correlating against the tones we want, over a period
|
||||
of one baud. The correlation must be quadrature. */
|
||||
@@ -307,6 +301,26 @@ SPAN_DECLARE(fsk_rx_state_t *) fsk_rx_init(fsk_rx_state_t *s,
|
||||
/* Initialise a power detector, so sense when a signal is present. */
|
||||
power_meter_init(&(s->power), 4);
|
||||
s->signal_present = 0;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(fsk_rx_state_t *) fsk_rx_init(fsk_rx_state_t *s,
|
||||
const fsk_spec_t *spec,
|
||||
int framing_mode,
|
||||
put_bit_func_t put_bit,
|
||||
void *user_data)
|
||||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (fsk_rx_state_t *) malloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->put_bit = put_bit;
|
||||
s->put_bit_user_data = user_data;
|
||||
fsk_rx_restart(s, spec, framing_mode);
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -421,7 +435,7 @@ SPAN_DECLARE_NONSTD(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len)
|
||||
baudstate = (sum[0] < sum[1]);
|
||||
switch (s->framing_mode)
|
||||
{
|
||||
case 1:
|
||||
case FSK_FRAME_MODE_SYNC:
|
||||
/* Synchronous serial operation - e.g. for HDLC */
|
||||
if (s->last_bit != baudstate)
|
||||
{
|
||||
@@ -442,7 +456,7 @@ SPAN_DECLARE_NONSTD(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len)
|
||||
s->put_bit(s->put_bit_user_data, baudstate);
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case FSK_FRAME_MODE_ASYNC:
|
||||
/* Fully asynchronous mode */
|
||||
if (s->last_bit != baudstate)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* This code is based on the widely used GSM 06.10 code available from
|
||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||
*
|
||||
* $Id: gsm0610_rpe.c,v 1.25 2009/02/03 16:28:39 steveu Exp $
|
||||
* $Id: gsm0610_rpe.c,v 1.25.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -87,13 +87,13 @@ static void weighting_filter(const int16_t *e, // signal [-5..0.39.44] IN
|
||||
" emms;\n"
|
||||
" addl $-10,%%ecx;\n"
|
||||
" movl $0x1000,%%eax;\n"
|
||||
" movd %%eax,%%mm5;\n" /* for rounding */
|
||||
" movd %%eax,%%mm5;\n" /* For rounding */
|
||||
" movq %[gsm_H],%%mm1;\n"
|
||||
" movq %[gsm_H8],%%mm2;\n"
|
||||
" movq %[gsm_H16],%%mm3;\n"
|
||||
" xorl %%esi,%%esi;\n"
|
||||
" .p2align 2;\n"
|
||||
"1:;\n"
|
||||
"1:\n"
|
||||
" movq (%%ecx,%%esi,2),%%mm0;\n"
|
||||
" pmaddwd %%mm1,%%mm0;\n"
|
||||
|
||||
|
||||
@@ -143,7 +143,8 @@
|
||||
<File RelativePath="super_tone_rx.c"></File>
|
||||
<File RelativePath="super_tone_tx.c"></File>
|
||||
<File RelativePath="swept_tone.c"></File>
|
||||
<File RelativePath="t4.c"></File>
|
||||
<File RelativePath="t4_rx.c"></File>
|
||||
<File RelativePath="t4_tx.c"></File>
|
||||
<File RelativePath="t30.c"></File>
|
||||
<File RelativePath="t30_api.c"></File>
|
||||
<File RelativePath="t30_logging.c"></File>
|
||||
@@ -221,7 +222,8 @@
|
||||
<File RelativePath="spandsp/super_tone_rx.h"></File>
|
||||
<File RelativePath="spandsp/super_tone_tx.h"></File>
|
||||
<File RelativePath="spandsp/swept_tone.h"></File>
|
||||
<File RelativePath="spandsp/t4.h"></File>
|
||||
<File RelativePath="spandsp/t4_rx.h"></File>
|
||||
<File RelativePath="spandsp/t4_tx.h"></File>
|
||||
<File RelativePath="spandsp/t30.h"></File>
|
||||
<File RelativePath="spandsp/t30_api.h"></File>
|
||||
<File RelativePath="spandsp/t30_fcf.h"></File>
|
||||
@@ -283,12 +285,14 @@
|
||||
<File RelativePath="spandsp/private/super_tone_tx.h"></File>
|
||||
<File RelativePath="spandsp/private/swept_tone.h"></File>
|
||||
<File RelativePath="spandsp/private/t30.h"></File>
|
||||
<File RelativePath="spandsp/private/t30_dis_dtc_dcs_bits.h"></File>
|
||||
<File RelativePath="spandsp/private/t31.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_core.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_gateway.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_non_ecm_buffer.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_terminal.h"></File>
|
||||
<File RelativePath="spandsp/private/t4.h"></File>
|
||||
<File RelativePath="spandsp/private/t4_rx.h"></File>
|
||||
<File RelativePath="spandsp/private/t4_tx.h"></File>
|
||||
<File RelativePath="spandsp/private/time_scale.h"></File>
|
||||
<File RelativePath="spandsp/private/tone_detect.h"></File>
|
||||
<File RelativePath="spandsp/private/tone_generate.h"></File>
|
||||
|
||||
@@ -213,7 +213,8 @@
|
||||
<File RelativePath="super_tone_rx.c"></File>
|
||||
<File RelativePath="super_tone_tx.c"></File>
|
||||
<File RelativePath="swept_tone.c"></File>
|
||||
<File RelativePath="t4.c"></File>
|
||||
<File RelativePath="t4_rx.c"></File>
|
||||
<File RelativePath="t4_tx.c"></File>
|
||||
<File RelativePath="t30.c"></File>
|
||||
<File RelativePath="t30_api.c"></File>
|
||||
<File RelativePath="t30_logging.c"></File>
|
||||
@@ -291,7 +292,8 @@
|
||||
<File RelativePath="spandsp/super_tone_rx.h"></File>
|
||||
<File RelativePath="spandsp/super_tone_tx.h"></File>
|
||||
<File RelativePath="spandsp/swept_tone.h"></File>
|
||||
<File RelativePath="spandsp/t4.h"></File>
|
||||
<File RelativePath="spandsp/t4_rx.h"></File>
|
||||
<File RelativePath="spandsp/t4_tx.h"></File>
|
||||
<File RelativePath="spandsp/t30.h"></File>
|
||||
<File RelativePath="spandsp/t30_api.h"></File>
|
||||
<File RelativePath="spandsp/t30_fcf.h"></File>
|
||||
@@ -353,12 +355,14 @@
|
||||
<File RelativePath="spandsp/private/super_tone_tx.h"></File>
|
||||
<File RelativePath="spandsp/private/swept_tone.h"></File>
|
||||
<File RelativePath="spandsp/private/t30.h"></File>
|
||||
<File RelativePath="spandsp/private/t30_dis_dtc_dcs_bits.h"></File>
|
||||
<File RelativePath="spandsp/private/t31.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_core.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_gateway.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_non_ecm_buffer.h"></File>
|
||||
<File RelativePath="spandsp/private/t38_terminal.h"></File>
|
||||
<File RelativePath="spandsp/private/t4.h"></File>
|
||||
<File RelativePath="spandsp/private/t4_rx.h"></File>
|
||||
<File RelativePath="spandsp/private/t4_tx.h"></File>
|
||||
<File RelativePath="spandsp/private/time_scale.h"></File>
|
||||
<File RelativePath="spandsp/private/tone_detect.h"></File>
|
||||
<File RelativePath="spandsp/private/tone_generate.h"></File>
|
||||
|
||||
@@ -297,7 +297,11 @@ SOURCE=.\swept_tone.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\t4.c
|
||||
SOURCE=.\t4_rx.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\t4_tx.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -607,7 +611,11 @@ SOURCE=.\spandsp/swept_tone.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/t4.h
|
||||
SOURCE=.\spandsp/t4_rx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/t4_tx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -855,6 +863,10 @@ SOURCE=.\spandsp/private/t30.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/private/t30_dis_dtc_dcs_bits.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/private/t31.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -875,7 +887,11 @@ SOURCE=.\spandsp/private/t38_terminal.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/private/t4.h
|
||||
SOURCE=.\spandsp/private/t4_rx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/private/t4_tx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: make_at_dictionary.c,v 1.5 2009/10/05 16:36:42 steveu Exp $
|
||||
* $Id: make_at_dictionary.c,v 1.6 2009/10/09 14:53:57 steveu Exp $
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
@@ -231,6 +231,7 @@ const char *wordlist[] =
|
||||
"+ESR", /* V.250 6.5.3 - Selective repeat */
|
||||
"+ETBM", /* V.250 6.5.6 - Call termination buffer management */
|
||||
"+EWIND", /* V.250 6.5.7 - Window size */
|
||||
"+F34", /* T.31 B.6.1 - Initial V.34 rate controls for FAX */
|
||||
"+FAA", /* T.32 8.5.2.5 - Adaptive Answer parameter */
|
||||
"+FAP", /* T.32 8.5.1.12 - Addressing and polling capabilities parameter */
|
||||
"+FAR", /* T.31 8.5.1 - Adaptive reception control */
|
||||
|
||||
@@ -23,11 +23,23 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: modem_connect_tones.c,v 1.37 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: modem_connect_tones.c,v 1.41 2009/11/06 19:21:33 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
/* CNG is 0.5s+-15% of 1100+-38Hz, 3s+-15% off, repeating.
|
||||
|
||||
CED is 0.2s silence, 3.3+-0.7s of 2100+-15Hz, and 75+-20ms of silence.
|
||||
|
||||
ANS is 3.3+-0.7s of 2100+-15Hz.
|
||||
|
||||
ANS/ is 3.3+-0.7s of 2100+-15Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms.
|
||||
|
||||
ANSam/ is 2100+-1Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms, and AM with a sinewave of 15+-0.1Hz.
|
||||
The modulated envelope ranges in amplitude between (0.8+-0.01) and (1.2+-0.01) times its average
|
||||
amplitude. It lasts up to 5s, but will be stopped early if the V.8 protocol proceeds. */
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
#endif
|
||||
@@ -158,9 +170,9 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *
|
||||
case MODEM_CONNECT_TONES_ANSAM:
|
||||
if (s->duration_timer < len)
|
||||
len = s->duration_timer;
|
||||
if (s->duration_timer > ms_to_samples(3300))
|
||||
if (s->duration_timer > ms_to_samples(5000))
|
||||
{
|
||||
if ((i = s->duration_timer - ms_to_samples(3300)) > len)
|
||||
if ((i = s->duration_timer - ms_to_samples(5000)) > len)
|
||||
i = len;
|
||||
memset(amp, 0, sizeof(int16_t)*i);
|
||||
}
|
||||
@@ -174,9 +186,9 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *
|
||||
case MODEM_CONNECT_TONES_ANSAM_PR:
|
||||
if (s->duration_timer < len)
|
||||
len = s->duration_timer;
|
||||
if (s->duration_timer > ms_to_samples(3300))
|
||||
if (s->duration_timer > ms_to_samples(5000))
|
||||
{
|
||||
if ((i = s->duration_timer - ms_to_samples(3300)) > len)
|
||||
if ((i = s->duration_timer - ms_to_samples(5000)) > len)
|
||||
i = len;
|
||||
memset(amp, 0, sizeof(int16_t)*i);
|
||||
}
|
||||
@@ -221,28 +233,48 @@ SPAN_DECLARE(modem_connect_tones_tx_state_t *) modem_connect_tones_tx_init(modem
|
||||
s->tone_phase = 0;
|
||||
s->mod_phase = 0;
|
||||
s->mod_level = 0;
|
||||
s->hop_timer = 0;
|
||||
break;
|
||||
case MODEM_CONNECT_TONES_ANS:
|
||||
case MODEM_CONNECT_TONES_ANSAM:
|
||||
/* 0.2s of silence, then 2.6s to 4s of 2100Hz+-15Hz tone, then 75ms of silence. */
|
||||
s->tone_phase_rate = dds_phase_rate(2100.0);
|
||||
s->level = dds_scaling_dbm0(-11);
|
||||
s->duration_timer = ms_to_samples(200 + 2600);
|
||||
s->mod_phase_rate = dds_phase_rate(15.0);
|
||||
if (s->tone_type == MODEM_CONNECT_TONES_ANSAM)
|
||||
{
|
||||
s->mod_phase_rate = dds_phase_rate(15.0);
|
||||
s->mod_level = s->level/5;
|
||||
s->duration_timer = ms_to_samples(200 + 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->mod_phase_rate = 0;
|
||||
s->mod_level = 0;
|
||||
s->duration_timer = ms_to_samples(200 + 2600);
|
||||
}
|
||||
s->tone_phase = 0;
|
||||
s->mod_phase = 0;
|
||||
s->mod_level = (s->tone_type == MODEM_CONNECT_TONES_ANSAM) ? s->level/5 : 0;
|
||||
s->hop_timer = 0;
|
||||
break;
|
||||
case MODEM_CONNECT_TONES_ANS_PR:
|
||||
case MODEM_CONNECT_TONES_ANSAM_PR:
|
||||
s->tone_phase_rate = dds_phase_rate(2100.0);
|
||||
s->level = dds_scaling_dbm0(-12);
|
||||
s->duration_timer = ms_to_samples(200 + 3300);
|
||||
s->mod_phase_rate = dds_phase_rate(15.0);
|
||||
if (s->tone_type == MODEM_CONNECT_TONES_ANSAM_PR)
|
||||
{
|
||||
s->mod_phase_rate = dds_phase_rate(15.0);
|
||||
s->mod_level = s->level/5;
|
||||
s->duration_timer = ms_to_samples(200 + 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->mod_phase_rate = 0;
|
||||
s->mod_level = 0;
|
||||
s->duration_timer = ms_to_samples(200 + 3300);
|
||||
}
|
||||
s->tone_phase = 0;
|
||||
s->mod_phase = 0;
|
||||
s->hop_timer = ms_to_samples(450);
|
||||
s->mod_level = (s->tone_type == MODEM_CONNECT_TONES_ANSAM_PR) ? s->level/5 : 0;
|
||||
break;
|
||||
default:
|
||||
if (alloced)
|
||||
@@ -362,19 +394,20 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
||||
int16_t notched;
|
||||
float v1;
|
||||
float famp;
|
||||
|
||||
float filtered;
|
||||
|
||||
switch (s->tone_type)
|
||||
{
|
||||
case MODEM_CONNECT_TONES_FAX_CNG:
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
famp = amp[i];
|
||||
/* A Cauer notch at 1100Hz, spread just wide enough to meet our detection bandwidth
|
||||
criteria. */
|
||||
famp = amp[i];
|
||||
v1 = 0.792928f*famp + 1.0018744927985f*s->z1 - 0.54196833412465f*s->z2;
|
||||
famp = v1 - 1.2994747954630f*s->z1 + s->z2;
|
||||
s->z2 = s->z1;
|
||||
s->z1 = v1;
|
||||
v1 = 0.792928f*famp + 1.0018744927985f*s->znotch_1 - 0.54196833412465f*s->znotch_2;
|
||||
famp = v1 - 1.2994747954630f*s->znotch_1 + s->znotch_2;
|
||||
s->znotch_2 = s->znotch_1;
|
||||
s->znotch_1 = v1;
|
||||
notched = (int16_t) lfastrintf(famp);
|
||||
|
||||
/* Estimate the overall energy in the channel, and the energy in
|
||||
@@ -413,22 +446,29 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
||||
case MODEM_CONNECT_TONES_ANS:
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
famp = amp[i];
|
||||
/* A Cauer bandpass at 15Hz, with which we demodulate the AM signal. */
|
||||
v1 = fabs(famp) + 1.996667f*s->z15hz_1 - 0.9968004f*s->z15hz_2;
|
||||
filtered = 0.001599787f*(v1 - s->z15hz_2);
|
||||
s->z15hz_2 = s->z15hz_1;
|
||||
s->z15hz_1 = v1;
|
||||
s->am_level += abs(lfastrintf(filtered)) - (s->am_level >> 8);
|
||||
//printf("%9.1f %10.4f %9d %9d\n", famp, filtered, s->am_level, s->channel_level);
|
||||
/* A Cauer notch at 2100Hz, spread just wide enough to meet our detection bandwidth
|
||||
criteria. */
|
||||
/* This is actually centred at 2095Hz, but gets the balance we want, due
|
||||
to the asymmetric walls of the notch */
|
||||
famp = amp[i];
|
||||
v1 = 0.76000f*famp - 0.1183852f*s->z1 - 0.5104039f*s->z2;
|
||||
famp = v1 + 0.1567596f*s->z1 + s->z2;
|
||||
s->z2 = s->z1;
|
||||
s->z1 = v1;
|
||||
v1 = 0.76000f*famp - 0.1183852f*s->znotch_1 - 0.5104039f*s->znotch_2;
|
||||
famp = v1 + 0.1567596f*s->znotch_1 + s->znotch_2;
|
||||
s->znotch_2 = s->znotch_1;
|
||||
s->znotch_1 = v1;
|
||||
notched = (int16_t) lfastrintf(famp);
|
||||
/* Estimate the overall energy in the channel, and the energy in
|
||||
the notch (i.e. overall channel energy - tone energy => noise).
|
||||
Use abs instead of multiply for speed (is it really faster?).
|
||||
Damp the overall energy a little more for a stable result.
|
||||
Damp the notch energy a little less, so we don't damp out the
|
||||
blip every time the phase reverses */
|
||||
blip every time the phase reverses. */
|
||||
s->channel_level += ((abs(amp[i]) - s->channel_level) >> 5);
|
||||
s->notch_level += ((abs(notched) - s->notch_level) >> 4);
|
||||
/* This should cut off at about -43dBm0 */
|
||||
@@ -455,7 +495,11 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
||||
if (s->tone_cycle_duration >= ms_to_samples(450 - 25))
|
||||
{
|
||||
if (++s->good_cycles == 3)
|
||||
report_tone_state(s, MODEM_CONNECT_TONES_ANS_PR, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
|
||||
{
|
||||
report_tone_state(s,
|
||||
(s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM_PR : MODEM_CONNECT_TONES_ANS_PR,
|
||||
lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -466,17 +510,21 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->tone_cycle_duration >= ms_to_samples(550))
|
||||
if (s->tone_cycle_duration >= ms_to_samples(450 + 100))
|
||||
{
|
||||
if (s->tone_present == MODEM_CONNECT_TONES_NONE)
|
||||
report_tone_state(s, MODEM_CONNECT_TONES_ANS, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
|
||||
{
|
||||
report_tone_state(s,
|
||||
(s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM : MODEM_CONNECT_TONES_ANS,
|
||||
lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
|
||||
}
|
||||
s->good_cycles = 0;
|
||||
s->tone_cycle_duration = ms_to_samples(550);
|
||||
s->tone_cycle_duration = ms_to_samples(450 + 100);
|
||||
}
|
||||
}
|
||||
s->tone_on = TRUE;
|
||||
}
|
||||
else
|
||||
else if (s->notch_level*5 > s->channel_level)
|
||||
{
|
||||
if (s->tone_present == MODEM_CONNECT_TONES_ANS)
|
||||
{
|
||||
@@ -528,7 +576,7 @@ SPAN_DECLARE(modem_connect_tones_rx_state_t *) modem_connect_tones_rx_init(modem
|
||||
{
|
||||
case MODEM_CONNECT_TONES_FAX_PREAMBLE:
|
||||
case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE:
|
||||
fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], TRUE, v21_put_bit, s);
|
||||
fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, v21_put_bit, s);
|
||||
fsk_rx_signal_cutoff(&(s->v21rx), -45.5f);
|
||||
break;
|
||||
case MODEM_CONNECT_TONES_ANS_PR:
|
||||
@@ -540,6 +588,7 @@ SPAN_DECLARE(modem_connect_tones_rx_state_t *) modem_connect_tones_rx_init(modem
|
||||
}
|
||||
s->channel_level = 0;
|
||||
s->notch_level = 0;
|
||||
s->am_level = 0;
|
||||
s->tone_present = MODEM_CONNECT_TONES_NONE;
|
||||
s->tone_cycle_duration = 0;
|
||||
s->good_cycles = 0;
|
||||
@@ -547,8 +596,10 @@ SPAN_DECLARE(modem_connect_tones_rx_state_t *) modem_connect_tones_rx_init(modem
|
||||
s->tone_on = FALSE;
|
||||
s->tone_callback = tone_callback;
|
||||
s->callback_data = user_data;
|
||||
s->z1 = 0.0f;
|
||||
s->z2 = 0.0f;
|
||||
s->znotch_1 = 0.0f;
|
||||
s->znotch_2 = 0.0f;
|
||||
s->z15hz_1 = 0.0f;
|
||||
s->z15hz_2 = 0.0f;
|
||||
s->num_bits = 0;
|
||||
s->flags_seen = 0;
|
||||
s->framing_ok_announced = FALSE;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: spandsp.h.in,v 1.19 2009/09/22 13:11:04 steveu Exp $
|
||||
* $Id: spandsp.h.in,v 1.19.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -99,7 +99,8 @@
|
||||
#include <spandsp/v18.h>
|
||||
#include <spandsp/v42.h>
|
||||
#include <spandsp/v42bis.h>
|
||||
#include <spandsp/t4.h>
|
||||
#include <spandsp/t4_rx.h>
|
||||
#include <spandsp/t4_tx.h>
|
||||
#include <spandsp/t30.h>
|
||||
#include <spandsp/t30_api.h>
|
||||
#include <spandsp/t30_fcf.h>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: spandsp.h.in,v 1.19 2009/09/22 13:11:04 steveu Exp $
|
||||
* $Id: spandsp.h.in,v 1.19.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -96,7 +96,8 @@
|
||||
#include <spandsp/v18.h>
|
||||
#include <spandsp/v42.h>
|
||||
#include <spandsp/v42bis.h>
|
||||
#include <spandsp/t4.h>
|
||||
#include <spandsp/t4_rx.h>
|
||||
#include <spandsp/t4_tx.h>
|
||||
#include <spandsp/t30.h>
|
||||
#include <spandsp/t30_api.h>
|
||||
#include <spandsp/t30_fcf.h>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: expose.h,v 1.14 2009/09/22 13:11:04 steveu Exp $
|
||||
* $Id: expose.h,v 1.14.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -71,7 +71,8 @@
|
||||
#include <spandsp/private/modem_connect_tones.h>
|
||||
#include <spandsp/private/at_interpreter.h>
|
||||
#include <spandsp/private/fax_modems.h>
|
||||
#include <spandsp/private/t4.h>
|
||||
#include <spandsp/private/t4_rx.h>
|
||||
#include <spandsp/private/t4_tx.h>
|
||||
#include <spandsp/private/t30.h>
|
||||
#include <spandsp/private/fax.h>
|
||||
#include <spandsp/private/t38_core.h>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fsk.h,v 1.40 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: fsk.h,v 1.41 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -115,6 +115,15 @@ enum
|
||||
FSK_WEITBRECHT50 /* 50 baud version, used for TDD (Telecom Device for the Deaf) */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FSK_FRAME_MODE_ASYNC = 0,
|
||||
FSK_FRAME_MODE_SYNC = 1,
|
||||
FSK_FRAME_MODE_5N1_FRAMES = 7, /* 5 bits of data + start bit + stop bit */
|
||||
FSK_FRAME_MODE_7N1_FRAMES = 9, /* 7 bits of data + start bit + stop bit */
|
||||
FSK_FRAME_MODE_8N1_FRAMES = 10 /* 8 bits of data + start bit + stop bit */
|
||||
};
|
||||
|
||||
SPAN_DECLARE_DATA extern const fsk_spec_t preset_fsk_specs[];
|
||||
|
||||
/*!
|
||||
@@ -149,6 +158,8 @@ SPAN_DECLARE(fsk_tx_state_t *) fsk_tx_init(fsk_tx_state_t *s,
|
||||
get_bit_func_t get_bit,
|
||||
void *user_data);
|
||||
|
||||
SPAN_DECLARE(int) fsk_tx_restart(fsk_tx_state_t *s, const fsk_spec_t *spec);
|
||||
|
||||
SPAN_DECLARE(int) fsk_tx_release(fsk_tx_state_t *s);
|
||||
|
||||
SPAN_DECLARE(int) fsk_tx_free(fsk_tx_state_t *s);
|
||||
@@ -203,6 +214,8 @@ SPAN_DECLARE(fsk_rx_state_t *) fsk_rx_init(fsk_rx_state_t *s,
|
||||
put_bit_func_t put_bit,
|
||||
void *user_data);
|
||||
|
||||
SPAN_DECLARE(int) fsk_rx_restart(fsk_rx_state_t *s, const fsk_spec_t *spec, int framing_mode);
|
||||
|
||||
SPAN_DECLARE(int) fsk_rx_release(fsk_rx_state_t *s);
|
||||
|
||||
SPAN_DECLARE(int) fsk_rx_free(fsk_rx_state_t *s);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: modem_connect_tones.h,v 1.2 2009/01/29 18:30:14 steveu Exp $
|
||||
* $Id: modem_connect_tones.h,v 1.3 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -66,12 +66,17 @@ struct modem_connect_tones_rx_state_s
|
||||
void *callback_data;
|
||||
|
||||
/*! \brief The notch filter state. */
|
||||
float z1;
|
||||
float z2;
|
||||
float znotch_1;
|
||||
float znotch_2;
|
||||
/*! \brief The 15Hz AM filter state. */
|
||||
float z15hz_1;
|
||||
float z15hz_2;
|
||||
/*! \brief The in notch power estimate */
|
||||
int notch_level;
|
||||
int32_t notch_level;
|
||||
/*! \brief The total channel power estimate */
|
||||
int channel_level;
|
||||
int32_t channel_level;
|
||||
/*! \brief The 15Hz AM power estimate */
|
||||
int32_t am_level;
|
||||
/*! \brief Sample counter for the small chunks of samples, after which a test is conducted. */
|
||||
int chunk_remainder;
|
||||
/*! \brief TRUE is the tone is currently confirmed present in the audio. */
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t30.h,v 1.5 2009/09/20 13:42:29 steveu Exp $
|
||||
* $Id: t30.h,v 1.5.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -253,7 +253,7 @@ struct t30_state_s
|
||||
int tx_stop_page;
|
||||
/*! \brief The current completion status. */
|
||||
int current_status;
|
||||
/*! \brief Internet Aware FAX mode bit mask. */
|
||||
/*! \brief Internet aware FAX mode bit mask. */
|
||||
int iaf;
|
||||
/*! \brief A bit mask of the currently supported modem types. */
|
||||
int supported_modems;
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* t30_dis_dtc_dcs_bits.h - ITU T.30 fax control bits definitions
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2009 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* 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: t30_dis_dtc_dcs_bits.h,v 1.1.4.1 2009/12/19 09:47:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_T30_DIS_DTC_DCS_BITS_H_)
|
||||
#define _SPANDSP_PRIVATE_T30_DIS_DTC_DCS_BITS_H_
|
||||
|
||||
/* Indicates that the terminal has the Simple mode capability defined in ITU-T Rec. T.37.
|
||||
Internet address signals CIA, TSA or CSA can be sent and received. The recipient terminal
|
||||
may process or ignore this signal. */
|
||||
#define T30_DIS_BIT_T37 1
|
||||
#define T30_DCS_BIT_T37 1
|
||||
|
||||
/* Indicates that the terminal has the capability to communicate using ITU-T Rec. T.38.
|
||||
Internet address signals CIA, TSA or CSA can be sent and received. The recipient terminal
|
||||
may process or ignore this signal. */
|
||||
#define T30_DIS_BIT_T38 3
|
||||
#define T30_DCS_BIT_T38 3
|
||||
|
||||
/* Bit 4 set to "1" indicates 3rd Generation Mobile Network Access to the GSTN Connection.
|
||||
Bit 4 set to "0" conveys no information about the type of connection. */
|
||||
#define T30_DIS_BIT_3G_MOBILE 4
|
||||
#define T30_DCS_BIT_3G_MOBILE 4
|
||||
|
||||
/* When ISDN mode is used, in DIS/DTC bit 6 shall be set to "0". */
|
||||
#define T30_DIS_BIT_V8_CAPABILITY 6
|
||||
|
||||
/* When ISDN mode is used, in DIS/DTC bit 7 shall be set to "0". */
|
||||
#define T30_DIS_BIT_64_OCTET_ECM_FRAMES_PREFERRED 7
|
||||
|
||||
/* Bit 9 indicates that there is a facsimile document ready to be polled from the answering
|
||||
terrminal. It is not an indication of a capability. */
|
||||
#define T30_DIS_BIT_READY_TO_TRANSMIT_FAX_DOCUMENT 9
|
||||
|
||||
/* In DIS/DTC bit 10 indicates that the answering terminal has receiving capabilities.
|
||||
In DCS it is a command to the receiving terminal to set itself in the receive mode. */
|
||||
#define T30_DIS_BIT_READY_TO_RECEIVE_FAX_DOCUMENT 10
|
||||
#define T30_DCS_BIT_RECEIVE_FAX_DOCUMENT 10
|
||||
|
||||
/* Bits 11, 12, 13, 14 - modem type */
|
||||
|
||||
#define T30_DIS_BIT_200_200_CAPABLE 15
|
||||
#define T30_DCS_BIT_200_200 15
|
||||
|
||||
#define T30_DIS_BIT_2D_CAPABLE 16
|
||||
#define T30_DCS_BIT_2D_CODING 16
|
||||
|
||||
/* Standard facsimile terminals conforming to ITU-T Rec. T.4 must have the following capability:
|
||||
Paper length = 297 mm. */
|
||||
|
||||
/* Bits 17, 18 - recording width */
|
||||
|
||||
/* Bits 19, 20 - paper length */
|
||||
|
||||
/* Bits 21, 22, 23 - min scan line time */
|
||||
|
||||
/* When ISDN mode is used, in DIS/DTC bits 21 to 23 shall be set to "1". */
|
||||
|
||||
#define T30_DIS_BIT_UNCOMPRESSED_CAPABLE 26
|
||||
#define T30_DCS_BIT_UNCOMPRESSED_MODE 26
|
||||
|
||||
/* When ISDN mode is used, in DIS/DTC bit 27 shall be set to "1". */
|
||||
#define T30_DIS_BIT_ECM_CAPABLE 27
|
||||
#define T30_DCS_BIT_ECM 27
|
||||
|
||||
/* The value of bit 28 in the DCS command is only valid when ECM is selected. */
|
||||
#define T30_DCS_BIT_64_OCTET_ECM_FRAMES 28
|
||||
|
||||
/* The value of bit 31 in the DCS command is only valid when ECM is selected. */
|
||||
#define T30_DIS_BIT_T6_CAPABLE 31
|
||||
#define T30_DCS_BIT_T6_MODE 31
|
||||
|
||||
#define T30_DIS_BIT_FNV_CAPABLE 33
|
||||
#define T30_DCS_BIT_FNV_CAPABLE 33
|
||||
|
||||
#define T30_DIS_BIT_MULTIPLE_SELECTIVE_POLLING_CAPABLE 34
|
||||
|
||||
#define T30_DIS_BIT_POLLED_SUBADDRESSING_CAPABLE 35
|
||||
|
||||
#define T30_DIS_BIT_T43_CAPABLE 36
|
||||
#define T30_DCS_BIT_T43_CODING 36
|
||||
|
||||
#define T30_DIS_BIT_PLANE_INTERLEAVE_CAPABLE 37
|
||||
#define T30_DCS_BIT_PLANE_INTERLEAVE 37
|
||||
|
||||
#define T30_DIS_BIT_G726_CAPABLE 38
|
||||
#define T30_DCS_BIT_G726 38
|
||||
|
||||
#define T30_DIS_BIT_200_400_CAPABLE 41
|
||||
#define T30_DCS_BIT_200_400 41
|
||||
|
||||
#define T30_DIS_BIT_300_300_CAPABLE 42
|
||||
#define T30_DCS_BIT_300_300 42
|
||||
|
||||
#define T30_DIS_BIT_400_400_CAPABLE 43
|
||||
#define T30_DCS_BIT_400_400 43
|
||||
|
||||
/* Bits 44 and 45 are used only in conjunction with bits 15 and 43. Bit 44 in DCS, when used,
|
||||
shall correctly indicate the resolution of the transmitted document, which means that bit 44 in DCS may
|
||||
not always match the indication of bits 44 and 45 in DIS/DTC. Cross selection will cause the distortion
|
||||
and reduction of reproducible area.
|
||||
If a receiver indicates in DIS that it prefers to receive metric-based information, but the transmitter has
|
||||
only the equivalent inch-based information (or vice versa), then communication shall still take place.
|
||||
Bits 44 and 45 do not require the provision of any additional features on the terminal to
|
||||
indicate to the sending or receiving user whether the information was transmitted or received on a metric-metric,
|
||||
inch-inch, metric-inch, inch-metric basis. */
|
||||
|
||||
#define T30_DIS_BIT_INCH_RESOLUTION_PREFERRED 44
|
||||
#define T30_DCS_BIT_INCH_RESOLUTION 44
|
||||
|
||||
#define T30_DIS_BIT_METRIC_RESOLUTION_PREFERRED 45
|
||||
|
||||
#define T30_DIS_BIT_MIN_SCAN_TIME_HALVES 46
|
||||
|
||||
#define T30_DIS_BIT_SELECTIVE_POLLING_CAPABLE 47
|
||||
|
||||
#define T30_DIS_BIT_SUBADDRESSING_CAPABLE 49
|
||||
#define T30_DCS_BIT_SUBADDRESS_TRANSMISSION 49
|
||||
|
||||
#define T30_DIS_BIT_PASSWORD 50
|
||||
#define T30_DCS_BIT_SENDER_ID_TRANSMISSION 50
|
||||
|
||||
/* Bit 51 indicates that there is a data file ready to be polled from the answering terminal. It is
|
||||
not an indication of a capability. This bit is used in conjunction with bits 53, 54, 55 and 57. */
|
||||
#define T30_DIS_BIT_READY_TO_TRANSMIT_DATA_FILE 51
|
||||
|
||||
/* The binary file transfer protocol is described in ITU-T Rec. T.434. */
|
||||
#define T30_DIS_BIT_BFT_CAPABLE 53
|
||||
#define T30_DCS_BIT_BFT 53
|
||||
|
||||
#define T30_DIS_BIT_DTM_CAPABLE 54
|
||||
#define T30_DCS_BIT_DTM 54
|
||||
|
||||
#define T30_DIS_BIT_EDI_CAPABLE 55
|
||||
#define T30_DCS_BIT_EDI 55
|
||||
|
||||
#define T30_DIS_BIT_BTM_CAPABLE 57
|
||||
#define T30_DCS_BIT_BTM 57
|
||||
|
||||
/* Bit 59 indicates that there is a character-coded or mixed-mode document ready to be polled
|
||||
from the answering terminal. It is not an indication of a capability. This bit is used in
|
||||
conjunction with bits 60, 62 and 65. */
|
||||
#define T30_DIS_BIT_READY_TO_TRANSMIT_MIXED_MODE_DOCUMENT 59
|
||||
|
||||
#define T30_DIS_BIT_CHARACTER_MODE 60
|
||||
#define T30_DCS_BIT_CHARACTER_MODE 60
|
||||
|
||||
#define T30_DIS_BIT_MIXED_MODE 62
|
||||
#define T30_DCS_BIT_MIXED_MODE 62
|
||||
|
||||
#define T30_DIS_BIT_PROCESSABLE_MODE_26 65
|
||||
|
||||
#define T30_DIS_BIT_DIGITAL_NETWORK_CAPABLE 66
|
||||
#define T30_DCS_BIT_DIGITAL_NETWORK_CAPABLE 66
|
||||
|
||||
#define T30_DIS_BIT_DUPLEX_CAPABLE 67
|
||||
#define T30_DCS_BIT_DUPLEX_CAPABLE 67
|
||||
|
||||
#define T30_DIS_BIT_T81_CAPABLE 68
|
||||
#define T30_DCS_BIT_FULL_COLOUR_MODEX 68
|
||||
|
||||
#define T30_DIS_BIT_FULL_COLOUR_CAPABLE 69
|
||||
#define T30_DCS_BIT_FULL_COLOUR_MODE 69
|
||||
|
||||
/* In a DIS/DTC frame, setting bit 71 to "0" indicates that the called terminal can only accept
|
||||
image data which has been digitized to 8 bits/pel/component for JPEG mode. This is also true for T.43
|
||||
mode if bit 36 is also set to "1". Setting bit 71 to "1" indicates that the called terminal can also accept
|
||||
image data that are digitized to 12 bits/pel/component for JPEG mode. This is also true for T.43 mode if
|
||||
bit 36 is also set to "1". In a DCS frame, setting bit 71 to "0" indicates that the calling terminal's image
|
||||
data are digitized to 8 bits/pel/component for JPEG mode. This is also true for T.43 mode if bit 36 is also
|
||||
set to "1". Setting bit 71 to "1" indicates that the calling terminal transmits image data which has been
|
||||
digitized to 12 bits/pel/component for JPEG mode. This is also true for T.43 mode if bit 36 is also set
|
||||
to "1". */
|
||||
#define T30_DIS_BIT_12BIT_CAPABLE 71
|
||||
#define T30_DCS_BIT_12BIT_COMPONENT 71
|
||||
|
||||
#define T30_DIS_BIT_NO_SUBSAMPLING 73
|
||||
#define T30_DCS_BIT_NO_SUBSAMPLING 73
|
||||
|
||||
#define T30_DIS_BIT_CUSTOM_ILLUMINANT 74
|
||||
#define T30_DCS_BIT_CUSTOM_ILLUMINANT 74
|
||||
|
||||
#define T30_DIS_BIT_CUSTOM_GAMUT_RANGE 75
|
||||
#define T30_DCS_BIT_CUSTOM_GAMUT_RANGE 75
|
||||
|
||||
#define T30_DIS_BIT_NORTH_AMERICAN_LETTER_CAPABLE 76
|
||||
#define T30_DCS_BIT_NORTH_AMERICAN_LETTER 76
|
||||
|
||||
#define T30_DIS_BIT_NORTH_AMERICAN_LEGAL_CAPABLE 77
|
||||
#define T30_DCS_BIT_NORTH_AMERICAN_LEGAL 77
|
||||
|
||||
#define T30_DIS_BIT_T85_CAPABLE 78
|
||||
#define T30_DCS_BIT_T85_MODE 78
|
||||
|
||||
#define T30_DIS_BIT_T85_L0_CAPABLE 79
|
||||
#define T30_DCS_BIT_T85_L0_MODE 79
|
||||
|
||||
/* In a DIS/DTC frame, setting bit 97 to "0" indicates that the called terminal does not have the
|
||||
capability to accept 300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm
|
||||
resolutions for colour/gray-scale images or T.44 Mixed Raster Content (MRC) mask layer.
|
||||
|
||||
Setting bit 97 to "1" indicates that the called terminal does have the capability to accept
|
||||
300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm resolutions for
|
||||
colour/gray-scale images and MRC mask layer. Bit 97 is valid only when bits 68 and 42 or 43
|
||||
(300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm) are set to "1".
|
||||
|
||||
In a DCS frame, setting bit 97 to "0" indicates that the calling terminal does not use
|
||||
300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm resolutions
|
||||
for colour/gray-scale images and mask layer.
|
||||
|
||||
Setting bit 97 to "1" indicates that the calling terminal uses 300 pels/25.4 mm x 300 lines/25.4 mm
|
||||
or 400 pels/25.4 mm x 400 lines/25.4 mm resolutions for colour/gray-scale images and MRC mask layer.
|
||||
Bit 97 is valid only when bits 68 and 42 or 43 (300 pels/25.4 mm x 300 lines/25.4 mm and
|
||||
400 pels/25.4 mm x 400 lines/25.4 mm) are set to "1".
|
||||
|
||||
In a DIS/DTC frame, combinations of bit 42, bit 43 and bit 97 indicate that the called terminal
|
||||
has higher resolution capabilities as follows:
|
||||
|
||||
Resolution capabilities (pels/25.4 mm)
|
||||
DIS/DTC Monochrome Colour/gray-scale
|
||||
42 43 97 300 x 300 400 x 400 300 x 300 400 x 400
|
||||
0 0 0 no no no no
|
||||
1 0 0 yes no no no
|
||||
0 1 0 no yes no no
|
||||
1 1 0 yes yes no no
|
||||
0 0 1 (invalid)
|
||||
1 0 1 yes no yes no
|
||||
0 1 1 no yes no yes
|
||||
1 1 1 yes yes yes yes
|
||||
"yes" means that the called terminal has the corresponding capability.
|
||||
"no" means that the called terminal does not have the corresponding capability. */
|
||||
#define T30_DIS_BIT_COLOUR_GREY_300_300_400_400_CAPABLE 97
|
||||
#define T30_DCS_BIT_COLOUR_GREY_300_300_400_400 97
|
||||
|
||||
/* In a DIS/DTC frame, setting bit 98 to "0" indicates that the called terminal does not have the
|
||||
capability to accept 100 pels/25.4 mm x 100 lines/25.4 mm spatial resolution for colour or gray-scale
|
||||
images. Setting bit 98 to "1" indicates that the called terminal does have the capability to accept
|
||||
100 pels/25.4 mm x 100 lines/25.4 mm spatial resolution for colour or gray-scale images. Bit 98 is valid
|
||||
only when bit 68 is set to "1". In a DCS frame, setting bit 98 to "0" indicates that the calling terminal does
|
||||
not use 100 pels/25.4 mm x 100 lines/25.4 mm spatial resolution for colour or gray-scale images. Setting
|
||||
bit 98 to "1" indicates that the calling terminal uses 100 pels/25.4 mm x 100 lines/25.4 mm spatial
|
||||
resolution for colour or gray-scale images. */
|
||||
#define T30_DIS_BIT_COLOUR_GREY_100_100_CAPABLE 98
|
||||
#define T30_DCS_BIT_COLOUR_GREY_100_100 98
|
||||
|
||||
/* To provide an error recovery mechanism, when PWD/SEP/SUB/SID/PSA/IRA/ISP frames are sent with DCS or DTC,
|
||||
bits 49, 102 and 50 in DCS or bits 47, 101, 50 and 35 in DTC shall be set to "1" with the following
|
||||
meaning:
|
||||
Bit DIS DTC DCS
|
||||
35 Polled SubAddress capability Polled SubAddress transmission Not allowed – set to "0"
|
||||
47 Selective polling capability Selective polling transmission Not allowed – set to "0"
|
||||
49 Subaddressing capability Not allowed (Set to "0") Subaddressing transmission
|
||||
50 Password Password transmission Sender Identification transmission
|
||||
101 Internet Selective Polling Address capability Internet Selective Polling Address transmission Not allowed – set to "0"
|
||||
102 Internet Routing Address capability Not allowed (Set to "0") Internet Routing Address transmission
|
||||
|
||||
Terminals conforming to the 1993 version of T.30 may set the above bits to "0" even though PWD/SEP/SUB
|
||||
frames are transmitted. */
|
||||
#define T30_DIS_BIT_INTERNET_SELECTIVE_POLLING_ADDRESS 101
|
||||
|
||||
#define T30_DIS_BIT_INTERNET_ROUTING_ADDRESS 102
|
||||
#define T30_DCS_BIT_INTERNET_ROUTING_ADDRESS_TRANSMISSION 102
|
||||
|
||||
#define T30_DIS_BIT_600_600_CAPABLE 105
|
||||
#define T30_DCS_BIT_600_600 105
|
||||
|
||||
#define T30_DIS_BIT_1200_1200_CAPABLE 106
|
||||
#define T30_DCS_BIT_1200_1200 106
|
||||
|
||||
#define T30_DIS_BIT_300_600_CAPABLE 107
|
||||
#define T30_DCS_BIT_300_600 107
|
||||
|
||||
#define T30_DIS_BIT_400_800_CAPABLE 108
|
||||
#define T30_DCS_BIT_400_800 108
|
||||
|
||||
#define T30_DIS_BIT_600_1200_CAPABLE 109
|
||||
#define T30_DCS_BIT_600_1200 109
|
||||
|
||||
#define T30_DIS_BIT_COLOUR_GREY_600_600_CAPABLE 110
|
||||
#define T30_DCS_BIT_COLOUR_GREY_600_600 110
|
||||
|
||||
#define T30_DIS_BIT_COLOUR_GREY_1200_1200_CAPABLE 111
|
||||
#define T30_DCS_BIT_COLOUR_GREY_1200_1200 111
|
||||
|
||||
#define T30_DIS_BIT_ALTERNATE_DOUBLE_SIDED_CAPABLE 113
|
||||
#define T30_DCS_BIT_ALTERNATE_DOUBLE_SIDED_CAPABLE 113
|
||||
|
||||
#define T30_DIS_BIT_CONTINUOUS_DOUBLE_SIDED_CAPABLE 114
|
||||
#define T30_DCS_BIT_CONTINUOUS_DOUBLE_SIDED_CAPABLE 114
|
||||
|
||||
#define T30_DIS_BIT_BLACK_AND_WHITE_MRC 115
|
||||
|
||||
#define T30_DIS_BIT_T45_CAPABLE 116
|
||||
#define T30_DCS_BIT_T45_MODE 116
|
||||
|
||||
/* This bit defines the available colour space, when bit 92, 93 or 94 is set to "1".
|
||||
Available colour space for all combinations of bits 92, 93, 94 and 119 are shown in the following table.
|
||||
It should be noted that terminals which conform to the 2003 and earlier versions of this Recommendation
|
||||
will send LAB with "1" in bit 92, 93 or 94 even if bit 119 is set to "1".
|
||||
|
||||
Available colour space for DIS/DTC bits 92, 93, 94 and 119
|
||||
|
||||
92 93 94 119 Mode of T.44 Available colour space
|
||||
0 0 0 x Not available -
|
||||
1 0 0 0 Mode 1 LAB only
|
||||
1 0 0 1 Mode 1 YCC only
|
||||
x 1 x 0 Mode 2 or higher LAB only
|
||||
x x 1 0 Mode 2 or higher LAB only
|
||||
x 1 x 1 Mode 2 or higher LAB and YCC
|
||||
x x 1 1 Mode 2 or higher LAB and YCC
|
||||
|
||||
Colour space for DCS bits 92, 93, 94 and 119
|
||||
|
||||
92 93 94 119 Mode of T.44 Colour space
|
||||
0 0 0 x* Not available -
|
||||
1 0 0 0 Mode 1 LAB
|
||||
1 0 0 1 Mode 1 YCC
|
||||
x 1 x 0 Mode 2 or higher LAB
|
||||
x x 1 0 Mode 2 or higher LAB
|
||||
x 1 x 1 Mode 2 or higher YCC or mixing of YCC and LAB
|
||||
x x 1 1 Mode 2 or higher YCC or mixing of YCC and LAB */
|
||||
#define T30_DIS_BIT_T44_COLOUR_SPACE 119
|
||||
#define T30_DCS_BIT_T44_COLOUR_SPACE 119
|
||||
|
||||
/* Can only be set in the communication through the T.38 gateway, to cope with delay of network.
|
||||
T.x timer (12+-1s) should be used after emitting RNR or TNR. However, after receiving
|
||||
PPS signal in ECM mode, T.5 timer should be used. */
|
||||
#define T30_DIS_BIT_T38_FLOW_CONTROL_CAPABLE 121
|
||||
#define T30_DCS_BIT_T38_FLOW_CONTROL_CAPABLE 121
|
||||
|
||||
/* For resolutions greater than 200 lines/25.4 mm, 4.2.1.1/T.4 specifies the use of specific K
|
||||
factors for each standardized vertical resolution. To ensure backward compatibility with earlier
|
||||
versions of ITU-T Rec. T.4, bit 122 indicates when such K factors are being used. */
|
||||
#define T30_DIS_BIT_K_GREATER_THAN_4 122
|
||||
|
||||
/* This bit should be set to "1" if the fax device is an Internet-Aware Fax Device as defined in
|
||||
ITU-T Rec. T.38 and if it is not affected by the data signal rate indicated by the DIS and DTC
|
||||
signals when communicating with another Internet-Aware Fax Device operating in T.38 mode. This
|
||||
bit shall not be used in GSTN mode. */
|
||||
#define T30_DIS_BIT_T38_FAX_CAPABLE 123
|
||||
/* This bit should be set to "1" if the fax device elects to operate in an Internet-Aware Fax mode
|
||||
as defined in ITU-T Rec. T.38 in response to a device which has set the related DIS bit to "1".
|
||||
When this bit is set to "1", the data signal rate of the modem (bits 11-14) should be set to "0". */
|
||||
#define T30_DCS_BIT_T38_FAX_MODE 123
|
||||
|
||||
/* When either bit of 31, 36, 38, 51, 53, 54, 55, 57, 59, 60, 62, 65, 68, 78, 79, 115, 116 and 127 is
|
||||
set to "1", ECM must be used. If the value of bit field 92 to 94 is non-zero, then ECM must be used.
|
||||
|
||||
Annex K describes the optional continuous-tone colour and gray scale images mode
|
||||
(sYCC-JPEG mode) protocol. When bit 127 in DIS/DTC frame is set to "1", the called terminal has the
|
||||
capability to accept sYCC-JPEG mode. This is defined with complete independent in the colour space
|
||||
CIELAB. In addition, when bit 127 in DCS frame is set to "1", ECM must be used and bits 15, 17, 18,
|
||||
19, 20, 41, 42, 43, 45, 46, 68, 69, 71, 73, 74, 75, 76, 77, 97, 98, 105, 106, 107, 108,
|
||||
109, 110 and 111 in DCS frame are "Don't care", and should be set to "0". In the case of
|
||||
transmission of multiple images, a post message signal PPS-MPS between pages, PPS-NULL between
|
||||
partial pages and PPS-EOP following the last page should be sent from the calling terminal to the
|
||||
called terminal. */
|
||||
#define T30_DIS_BIT_SYCC_T81_CAPABLE 127
|
||||
#define T30_DCS_BIT_SYCC_T81_MODE 127
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_gateway.h,v 1.4 2009/05/16 03:34:45 steveu Exp $
|
||||
* $Id: t38_gateway.h,v 1.5 2009/11/07 08:58:58 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -163,8 +163,8 @@ typedef struct
|
||||
int ecm_mode;
|
||||
/*! \brief The current bit rate for the fast modem. */
|
||||
int fast_bit_rate;
|
||||
/*! \brief The current fast modem type. */
|
||||
int fast_modem;
|
||||
/*! \brief The current fast receive modem type. */
|
||||
int fast_rx_modem;
|
||||
/*! \brief The type of fast receive modem currently active, which may be T38_NONE */
|
||||
int fast_rx_active;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_non_ecm_buffer.h,v 1.2 2008/10/13 14:19:18 steveu Exp $
|
||||
* $Id: t38_non_ecm_buffer.h,v 1.2.4.1 2009/12/19 06:43:28 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_T38_NON_ECM_BUFFER_H_)
|
||||
@@ -36,7 +36,7 @@ struct t38_non_ecm_buffer_state_s
|
||||
{
|
||||
/*! \brief Minimum number of bits per row, used when fill bits are being deleted on the
|
||||
link, and restored at the emitting gateway. */
|
||||
int min_row_bits;
|
||||
int min_bits_per_row;
|
||||
|
||||
/*! \brief non-ECM modem transmit data buffer. */
|
||||
uint8_t data[T38_NON_ECM_TX_BUF_LEN];
|
||||
@@ -55,8 +55,8 @@ struct t38_non_ecm_buffer_state_s
|
||||
/*! \brief The non-ECM flow control fill octet (0xFF before the first data, and 0x00
|
||||
once data has started). */
|
||||
uint8_t flow_control_fill_octet;
|
||||
/*! \brief TRUE if we are in the initial all ones part of non-ECM transmission. */
|
||||
int at_initial_all_ones;
|
||||
/*! \brief A code for the phase of input buffering, from initial all ones to completion. */
|
||||
int input_phase;
|
||||
/*! \brief TRUE is the end of non-ECM data indication has been received. */
|
||||
int data_finished;
|
||||
/*! \brief The current octet being transmitted from the buffer. */
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* private/t4_rx.h - definitions for T.4 FAX receive processing
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2003 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* 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: t4_rx.h,v 1.6.2.8 2009/12/21 17:18:40 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_T4_RX_H_)
|
||||
#define _SPANDSP_PRIVATE_T4_RX_H_
|
||||
|
||||
/*!
|
||||
TIFF specific state information to go with T.4 compression or decompression handling.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*! \brief The current file name. */
|
||||
const char *file;
|
||||
/*! \brief The libtiff context for the current TIFF file */
|
||||
TIFF *tiff_file;
|
||||
|
||||
/*! \brief The number of pages in the current image file. */
|
||||
int pages_in_file;
|
||||
|
||||
/*! \brief The compression type for output to the TIFF file. */
|
||||
int32_t output_compression;
|
||||
/*! \brief The TIFF photometric setting for the current page. */
|
||||
uint16_t photo_metric;
|
||||
/*! \brief The TIFF fill order setting for the current page. */
|
||||
uint16_t fill_order;
|
||||
/*! \brief The TIFF G3 FAX options. */
|
||||
int32_t output_t4_options;
|
||||
|
||||
/* "Background" information about the FAX, which can be stored in the image file. */
|
||||
/*! \brief The vendor of the machine which produced the file. */
|
||||
const char *vendor;
|
||||
/*! \brief The model of machine which produced the file. */
|
||||
const char *model;
|
||||
/*! \brief The local ident string. */
|
||||
const char *local_ident;
|
||||
/*! \brief The remote end's ident string. */
|
||||
const char *far_ident;
|
||||
/*! \brief The FAX sub-address. */
|
||||
const char *sub_address;
|
||||
/*! \brief The FAX DCS information, as an ASCII string. */
|
||||
const char *dcs;
|
||||
|
||||
/*! \brief The first page to transfer. -1 to start at the beginning of the file. */
|
||||
int start_page;
|
||||
/*! \brief The last page to transfer. -1 to continue to the end of the file. */
|
||||
int stop_page;
|
||||
} t4_tiff_state_t;
|
||||
|
||||
typedef struct t4_t6_decode_state_s t4_t6_decode_state_t;
|
||||
|
||||
/*!
|
||||
T.4 1D, T4 2D and T6 decompressor state.
|
||||
*/
|
||||
struct t4_t6_decode_state_s
|
||||
{
|
||||
/*! \brief Callback function to write a row of pixels to the image destination. */
|
||||
t4_row_write_handler_t row_write_handler;
|
||||
/*! \brief Opaque pointer passed to row_write_handler. */
|
||||
void *row_write_user_data;
|
||||
|
||||
/*! \brief Incoming bit buffer for decompression. */
|
||||
uint32_t rx_bitstream;
|
||||
/*! \brief The number of bits currently in rx_bitstream. */
|
||||
int rx_bits;
|
||||
/*! \brief The number of bits to be skipped before trying to match the next code word. */
|
||||
int rx_skip_bits;
|
||||
|
||||
/*! \brief This variable is used to count the consecutive EOLS we have seen. If it
|
||||
reaches six, this is the end of the image. It is initially set to -1 for
|
||||
1D and 2D decoding, as an indicator that we must wait for the first EOL,
|
||||
before decoding any image data. */
|
||||
int consecutive_eols;
|
||||
|
||||
/*! \brief The reference or starting changing element on the coding line. At the
|
||||
start of the coding line, a0 is set on an imaginary white changing element
|
||||
situated just before the first element on the line. During the coding of
|
||||
the coding line, the position of a0 is defined by the previous coding mode.
|
||||
(See T.4/4.2.1.3.2.). */
|
||||
int a0;
|
||||
/*! \brief The first changing element on the reference line to the right of a0 and of
|
||||
opposite colour to a0. */
|
||||
int b1;
|
||||
/*! \brief The length of the in-progress run of black or white. */
|
||||
int run_length;
|
||||
/*! \brief 2D horizontal mode control. */
|
||||
int black_white;
|
||||
/*! \brief TRUE if the current run is black */
|
||||
int its_black;
|
||||
|
||||
/*! \brief The current step into the current row run-lengths buffer. */
|
||||
int a_cursor;
|
||||
/*! \brief The current step into the reference row run-lengths buffer. */
|
||||
int b_cursor;
|
||||
|
||||
/*! \brief A pointer into the image buffer indicating where the last row begins */
|
||||
int last_row_starts_at;
|
||||
|
||||
/*! \brief The current number of consecutive bad rows. */
|
||||
int curr_bad_row_run;
|
||||
/*! \brief The longest run of consecutive bad rows seen in the current page. */
|
||||
int longest_bad_row_run;
|
||||
/*! \brief The total number of bad rows in the current page. */
|
||||
int bad_rows;
|
||||
};
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* private/t4_tx.h - definitions for T.4 FAX transmit processing
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2003 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* 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: t4_tx.h,v 1.7.2.4 2009/12/21 17:18:40 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_T4_TX_H_)
|
||||
#define _SPANDSP_PRIVATE_T4_TX_H_
|
||||
|
||||
typedef struct t4_t6_encode_state_s t4_t6_encode_state_t;
|
||||
|
||||
/*!
|
||||
T.4 1D, T4 2D and T6 compressor state.
|
||||
*/
|
||||
struct t4_t6_encode_state_s
|
||||
{
|
||||
/*! \brief The minimum number of encoded bits per row. This is a timing thing
|
||||
for hardware FAX machines. */
|
||||
int min_bits_per_row;
|
||||
/*! \brief The current maximum contiguous rows that may be 2D encoded. */
|
||||
int max_rows_to_next_1d_row;
|
||||
|
||||
/*! \brief The text which will be used in FAX page header. No text results
|
||||
in no header line. */
|
||||
const char *header_info;
|
||||
|
||||
/*! \brief Number of rows left that can be 2D encoded, before a 1D encoded row
|
||||
must be used. */
|
||||
int rows_to_next_1d_row;
|
||||
|
||||
/*! \brief The number of runs currently in the reference row. */
|
||||
int ref_steps;
|
||||
|
||||
/*! \brief Pointer to the byte containing the next image bit to transmit. */
|
||||
int bit_pos;
|
||||
/*! \brief Pointer to the bit within the byte containing the next image bit to transmit. */
|
||||
int bit_ptr;
|
||||
|
||||
/*! \brief Callback function to read a row of pixels from the image source. */
|
||||
t4_row_read_handler_t row_read_handler;
|
||||
/*! \brief Opaque pointer passed to row_read_handler. */
|
||||
void *row_read_user_data;
|
||||
};
|
||||
|
||||
/*!
|
||||
T.4 FAX compression/decompression descriptor. This defines the working state
|
||||
for a single instance of a T.4 FAX compression or decompression channel.
|
||||
*/
|
||||
struct t4_state_s
|
||||
{
|
||||
/*! \brief The same structure is used for T.4 transmit and receive. This variable
|
||||
records which mode is in progress. */
|
||||
int rx;
|
||||
|
||||
/*! \brief The type of compression used between the FAX machines. */
|
||||
int line_encoding;
|
||||
|
||||
/*! \brief The time at which handling of the current page began. */
|
||||
time_t page_start_time;
|
||||
|
||||
/*! \brief The size of the compressed image on the line side, in bits. */
|
||||
int line_image_size;
|
||||
|
||||
/*! \brief The current number of bytes per row of uncompressed image data. */
|
||||
int bytes_per_row;
|
||||
/*! \brief The size of the image in the image buffer, in bytes. */
|
||||
int image_size;
|
||||
/*! \brief The current size of the image buffer. */
|
||||
int image_buffer_size;
|
||||
/*! \brief A point to the image buffer. */
|
||||
uint8_t *image_buffer;
|
||||
|
||||
/*! \brief The number of pages transferred to date. */
|
||||
int current_page;
|
||||
/*! \brief Column-to-column (X) resolution in pixels per metre. */
|
||||
int x_resolution;
|
||||
/*! \brief Row-to-row (Y) resolution in pixels per metre. */
|
||||
int y_resolution;
|
||||
/*! \brief Width of the current page, in pixels. */
|
||||
int image_width;
|
||||
/*! \brief Length of the current page, in pixels. */
|
||||
int image_length;
|
||||
/*! \brief Current pixel row number. */
|
||||
int row;
|
||||
|
||||
/*! \brief This variable is set if we are treating the current row as a 2D encoded
|
||||
one. */
|
||||
int row_is_2d;
|
||||
/*! \brief The current length of the current row. */
|
||||
int row_len;
|
||||
|
||||
/*! \brief Black and white run-lengths for the current row. */
|
||||
uint32_t *cur_runs;
|
||||
/*! \brief Black and white run-lengths for the reference row. */
|
||||
uint32_t *ref_runs;
|
||||
/*! \brief Pointer to the buffer for the current pixel row. */
|
||||
uint8_t *row_buf;
|
||||
|
||||
/*! \brief Encoded data bits buffer. */
|
||||
uint32_t tx_bitstream;
|
||||
/*! \brief The number of bits currently in tx_bitstream. */
|
||||
int tx_bits;
|
||||
|
||||
/*! \brief The current number of bits in the current encoded row. */
|
||||
int row_bits;
|
||||
/*! \brief The minimum bits in any row of the current page. For monitoring only. */
|
||||
int min_row_bits;
|
||||
/*! \brief The maximum bits in any row of the current page. For monitoring only. */
|
||||
int max_row_bits;
|
||||
|
||||
/*! \brief Error and flow logging control */
|
||||
logging_state_t logging;
|
||||
|
||||
/*! \brief All TIFF file specific state information for the T.4 context. */
|
||||
t4_tiff_state_t tiff;
|
||||
t4_t6_decode_state_t t4_t6_rx;
|
||||
t4_t6_encode_state_t t4_t6_tx;
|
||||
};
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v18.h,v 1.4 2009/04/11 15:16:14 steveu Exp $
|
||||
* $Id: v18.h,v 1.5 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_V18_H_)
|
||||
@@ -31,7 +31,7 @@
|
||||
struct v18_state_s
|
||||
{
|
||||
/*! \brief TRUE if we are the calling modem */
|
||||
int caller;
|
||||
int calling_party;
|
||||
int mode;
|
||||
put_msg_func_t put_msg;
|
||||
void *user_data;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v22bis.h,v 1.11 2009/07/09 13:52:09 steveu Exp $
|
||||
* $Id: v22bis.h,v 1.12 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_V22BIS_H_)
|
||||
@@ -76,7 +76,7 @@ struct v22bis_state_s
|
||||
/*! \brief The maximum permitted bit rate of the modem. Valid values are 1200 and 2400. */
|
||||
int bit_rate;
|
||||
/*! \brief TRUE is this is the calling side modem. */
|
||||
int caller;
|
||||
int calling_party;
|
||||
/*! \brief The callback function used to get the next bit to be transmitted. */
|
||||
get_bit_func_t get_bit;
|
||||
/*! \brief A user specified opaque pointer passed to the get_bit callback routine. */
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v42.h,v 1.1 2008/11/15 14:43:08 steveu Exp $
|
||||
* $Id: v42.h,v 1.2 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_V42_H_)
|
||||
@@ -92,7 +92,7 @@ struct lapm_state_s
|
||||
struct v42_state_s
|
||||
{
|
||||
/*! TRUE if we are the calling party, otherwise FALSE */
|
||||
int caller;
|
||||
int calling_party;
|
||||
/*! TRUE if we should detect whether the far end is V.42 capable. FALSE if we go
|
||||
directly to protocol establishment */
|
||||
int detect;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v8.h,v 1.1 2008/10/13 13:14:01 steveu Exp $
|
||||
* $Id: v8.h,v 1.3 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_V8_H_)
|
||||
@@ -31,9 +31,15 @@
|
||||
struct v8_state_s
|
||||
{
|
||||
/*! \brief TRUE if we are the calling modem */
|
||||
int caller;
|
||||
/*! \brief The current state of the V8 protocol */
|
||||
int calling_party;
|
||||
|
||||
v8_result_handler_t *result_handler;
|
||||
void *result_handler_user_data;
|
||||
|
||||
/*! \brief The current state of the V.8 protocol */
|
||||
int state;
|
||||
int fsk_tx_on;
|
||||
int modem_connect_tone_tx_on;
|
||||
int negotiation_timer;
|
||||
int ci_timer;
|
||||
int ci_count;
|
||||
@@ -43,24 +49,14 @@ struct v8_state_s
|
||||
modem_connect_tones_tx_state_t ansam_tx;
|
||||
modem_connect_tones_rx_state_t ansam_rx;
|
||||
|
||||
v8_result_handler_t *result_handler;
|
||||
void *result_handler_user_data;
|
||||
|
||||
/*! \brief Modulation schemes available at this end. */
|
||||
int available_modulations;
|
||||
int local_end_modulations;
|
||||
int common_modulations;
|
||||
int negotiated_modulation;
|
||||
int far_end_modulations;
|
||||
|
||||
int call_function;
|
||||
int protocol;
|
||||
int pstn_access;
|
||||
int nsf_seen;
|
||||
int pcm_modem_availability;
|
||||
int t66_seen;
|
||||
|
||||
/* V8 data parsing */
|
||||
unsigned int bit_stream;
|
||||
v8_result_t result;
|
||||
|
||||
/* V.8 data parsing */
|
||||
uint32_t bit_stream;
|
||||
int bit_cnt;
|
||||
/* Indicates the type of message coming up */
|
||||
int preamble_type;
|
||||
@@ -70,7 +66,7 @@ struct v8_state_s
|
||||
/*! \brief a reference copy of the last CM or JM message, used when
|
||||
testing for matches. */
|
||||
uint8_t cm_jm_data[64];
|
||||
int cm_jm_count;
|
||||
int cm_jm_len;
|
||||
int got_cm_jm;
|
||||
int got_cj;
|
||||
int zero_byte_count;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t30.h,v 1.126 2009/09/21 15:52:39 steveu Exp $
|
||||
* $Id: t30.h,v 1.126.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -347,7 +347,7 @@ enum
|
||||
T30_SUPPORT_V17 = 0x04,
|
||||
/*! Support the V.34 modem (up to 33,600bps) for image transfer. */
|
||||
T30_SUPPORT_V34 = 0x08,
|
||||
/*! Support the Internet Aware FAX mode (no bit rate limit) for image transfer. */
|
||||
/*! Support the Internet aware FAX mode (no bit rate limit) for image transfer. */
|
||||
T30_SUPPORT_IAF = 0x10
|
||||
};
|
||||
|
||||
@@ -361,16 +361,18 @@ enum
|
||||
T30_SUPPORT_T4_2D_COMPRESSION = 0x04,
|
||||
/*! T.6 2D compression */
|
||||
T30_SUPPORT_T6_COMPRESSION = 0x08,
|
||||
/*! T.85 monochrome JBIG coding */
|
||||
/*! T.85 monochrome JBIG compression */
|
||||
T30_SUPPORT_T85_COMPRESSION = 0x10,
|
||||
/*! T.43 colour JBIG coding */
|
||||
/*! T.43 colour JBIG compression */
|
||||
T30_SUPPORT_T43_COMPRESSION = 0x20,
|
||||
/*! T.45 run length colour compression */
|
||||
T30_SUPPORT_T45_COMPRESSION = 0x40,
|
||||
/*! T.81 + T.30 Annex E colour JPEG coding */
|
||||
/*! T.81 + T.30 Annex E colour JPEG compression */
|
||||
T30_SUPPORT_T81_COMPRESSION = 0x80,
|
||||
/*! T.81 + T.30 Annex K colour sYCC-JPEG coding */
|
||||
T30_SUPPORT_SYCC_T81_COMPRESSION = 0x100
|
||||
/*! T.81 + T.30 Annex K colour sYCC-JPEG compression */
|
||||
T30_SUPPORT_SYCC_T81_COMPRESSION = 0x100,
|
||||
/*! T.88 monochrome JBIG2 compression */
|
||||
T30_SUPPORT_T88_COMPRESSION = 0x200
|
||||
};
|
||||
|
||||
enum
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* fcf.h - ITU T.30 fax control field definitions
|
||||
* t30_fcf.h - ITU T.30 fax control field definitions
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t30_fcf.h,v 1.17 2008/08/03 03:44:00 steveu Exp $
|
||||
* $Id: t30_fcf.h,v 1.18 2009/10/08 15:14:31 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_non_ecm_buffer.h,v 1.7 2009/02/10 13:06:47 steveu Exp $
|
||||
* $Id: t38_non_ecm_buffer.h,v 1.7.4.1 2009/12/19 06:43:28 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -35,9 +35,38 @@
|
||||
\section t38_non_ecm_buffer_page_sec_1 What does it do?
|
||||
|
||||
The T.38 rate adapting non-ECM image data buffer is used to buffer TCF and non-ECM
|
||||
FAX image data being gatewayed from a T.38 linke to an analogue FAX modem link.
|
||||
FAX image data being gatewayed from a T.38 link to an analogue FAX modem link.
|
||||
|
||||
As well as rate adapting, the buffer has the ability to impose a minimum on the number
|
||||
of bits per row of image data. This allows any row padding zeros to be stripped from
|
||||
the data stream, to minimise the data sent as T.38 packets, and be reinserted before
|
||||
the data is sent to its final destination. Not all T.38 implementations support this
|
||||
feature, so it's use must be negotiated.
|
||||
|
||||
\section t38_non_ecm_buffer_page_sec_2 How does it work?
|
||||
|
||||
When inserting padding bits, whether to ensure a minimum row time or for flow control,
|
||||
it is important the right value is inserted at the right point in the data sequence.
|
||||
If we are in the optional initial period of all ones, we can insert a byte of extra
|
||||
ones at any time. Once we pass that initial stage, TCF and image data need separate
|
||||
handling.
|
||||
|
||||
TCF data is all zeros. Once the period of all zeros has begun it is OK to insert
|
||||
additional bytes of zeros at any point.
|
||||
|
||||
Image data consists of rows, separated by EOL (end of line) markers. Inserting
|
||||
zeros at arbitrary times would corrupt the image. However, it is OK to insert a
|
||||
considerable number of extra zeros just before an EOL. Therefore we track where the
|
||||
EOL markers occur as we fill the buffer. As we empty the buffer stop outputting real
|
||||
data, and start outputting bytes of zero, if we reach this last EOL marker location.
|
||||
The EOL marker is 11 zeros following by 1 (1D mode) or 2 (2D mode) ones. Therefore, it
|
||||
always spills across 2 bytes in the buffer, and there is always a point where we can
|
||||
insert our extra zeros between bytes.
|
||||
|
||||
Padding between the group of successive EOL markers which for the RTC (return to control)
|
||||
marker that ends an image causes some FAX machines not to recognise them as an RTC condition.
|
||||
Therefore, our padding applies special protection so padding never occurs between two
|
||||
successive EOL markers, with no pixel data between them.
|
||||
*/
|
||||
|
||||
/*! The buffer length much be a power of two. The chosen length is big enough for
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* t4_rx.h - definitions for T.4 FAX receive processing
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2003 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* 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: t4_rx.h,v 1.3.2.3 2009/12/21 17:18:40 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_SPANDSP_T4_RX_H_)
|
||||
#define _SPANDSP_T4_RX_H_
|
||||
|
||||
/*! \page t4_page T.4 image compression and decompression
|
||||
|
||||
\section t4_page_sec_1 What does it do?
|
||||
The T.4 image compression and decompression routines implement the 1D and 2D
|
||||
encoding methods defined in ITU specification T.4. They also implement the pure
|
||||
2D encoding method defined in T.6. These are image compression algorithms used
|
||||
for FAX transmission.
|
||||
|
||||
\section t4_page_sec_1 How does it work?
|
||||
*/
|
||||
|
||||
typedef int (*t4_row_write_handler_t)(void *user_data, const uint8_t buf[], size_t len);
|
||||
|
||||
/*! Supported compression modes. */
|
||||
typedef enum
|
||||
{
|
||||
/*! No compression */
|
||||
T4_COMPRESSION_NONE = 0,
|
||||
/*! T.1 1D compression */
|
||||
T4_COMPRESSION_ITU_T4_1D = 1,
|
||||
/*! T.4 2D compression */
|
||||
T4_COMPRESSION_ITU_T4_2D = 2,
|
||||
/*! T.6 2D compression */
|
||||
T4_COMPRESSION_ITU_T6 = 3,
|
||||
/*! T.85 monochrome JBIG coding */
|
||||
T4_COMPRESSION_ITU_T85 = 4,
|
||||
/*! T.43 colour JBIG coding */
|
||||
T4_COMPRESSION_ITU_T43 = 5,
|
||||
/*! T.45 run length colour compression */
|
||||
T4_COMPRESSION_ITU_T45 = 6,
|
||||
/*! T.81 + T.30 Annex E colour JPEG coding */
|
||||
T4_COMPRESSION_ITU_T81 = 7,
|
||||
/*! T.81 + T.30 Annex K colour sYCC-JPEG coding */
|
||||
T4_COMPRESSION_ITU_SYCC_T81 = 8
|
||||
} t4_image_compression_t;
|
||||
|
||||
/*! Supported X resolutions, in pixels per metre. */
|
||||
typedef enum
|
||||
{
|
||||
T4_X_RESOLUTION_R4 = 4016,
|
||||
T4_X_RESOLUTION_R8 = 8031,
|
||||
T4_X_RESOLUTION_300 = 11811,
|
||||
T4_X_RESOLUTION_R16 = 16063,
|
||||
T4_X_RESOLUTION_600 = 23622,
|
||||
T4_X_RESOLUTION_800 = 31496,
|
||||
T4_X_RESOLUTION_1200 = 47244
|
||||
} t4_image_x_resolution_t;
|
||||
|
||||
/*! Supported Y resolutions, in pixels per metre. */
|
||||
typedef enum
|
||||
{
|
||||
T4_Y_RESOLUTION_STANDARD = 3850,
|
||||
T4_Y_RESOLUTION_FINE = 7700,
|
||||
T4_Y_RESOLUTION_300 = 11811,
|
||||
T4_Y_RESOLUTION_SUPERFINE = 15400, /* 400 is 15748 */
|
||||
T4_Y_RESOLUTION_600 = 23622,
|
||||
T4_Y_RESOLUTION_800 = 31496,
|
||||
T4_Y_RESOLUTION_1200 = 47244
|
||||
} t4_image_y_resolution_t;
|
||||
|
||||
/*!
|
||||
Exact widths in PELs for the difference resolutions, and page widths.
|
||||
Note:
|
||||
The A4 widths also apply to North American letter and legal.
|
||||
The R4 resolution widths are not supported in recent versions of T.30
|
||||
Only images of exactly these widths are acceptable for FAX transmisson.
|
||||
|
||||
R4 864 pels/215mm for ISO A4, North American Letter and Legal
|
||||
R4 1024 pels/255mm for ISO B4
|
||||
R4 1216 pels/303mm for ISO A3
|
||||
R8 1728 pels/215mm for ISO A4, North American Letter and Legal
|
||||
R8 2048 pels/255mm for ISO B4
|
||||
R8 2432 pels/303mm for ISO A3
|
||||
R16 3456 pels/215mm for ISO A4, North American Letter and Legal
|
||||
R16 4096 pels/255mm for ISO B4
|
||||
R16 4864 pels/303mm for ISO A3
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
T4_WIDTH_R4_A4 = 864,
|
||||
T4_WIDTH_R4_B4 = 1024,
|
||||
T4_WIDTH_R4_A3 = 1216,
|
||||
T4_WIDTH_R8_A4 = 1728,
|
||||
T4_WIDTH_R8_B4 = 2048,
|
||||
T4_WIDTH_R8_A3 = 2432,
|
||||
T4_WIDTH_300_A4 = 2592,
|
||||
T4_WIDTH_300_B4 = 3072,
|
||||
T4_WIDTH_300_A3 = 3648,
|
||||
T4_WIDTH_R16_A4 = 3456,
|
||||
T4_WIDTH_R16_B4 = 4096,
|
||||
T4_WIDTH_R16_A3 = 4864,
|
||||
T4_WIDTH_600_A4 = 5184,
|
||||
T4_WIDTH_600_B4 = 6144,
|
||||
T4_WIDTH_600_A3 = 7296,
|
||||
T4_WIDTH_1200_A4 = 10368,
|
||||
T4_WIDTH_1200_B4 = 12288,
|
||||
T4_WIDTH_1200_A3 = 14592
|
||||
} t4_image_width_t;
|
||||
|
||||
/*!
|
||||
Length of the various supported paper sizes, in pixels at the various Y resolutions.
|
||||
Paper sizes are
|
||||
A4 (215mm x 297mm)
|
||||
B4 (255mm x 364mm)
|
||||
A3 (303mm x 418.56mm)
|
||||
North American Letter (215.9mm x 279.4mm)
|
||||
North American Legal (215.9mm x 355.6mm)
|
||||
Unlimited
|
||||
|
||||
T.4 does not accurately define the maximum number of scan lines in a page. A wide
|
||||
variety of maximum row counts are used in the real world. It is important not to
|
||||
set our sending limit too high, or a receiving machine might split pages. It is
|
||||
important not to set it too low, or we might clip pages.
|
||||
|
||||
Values seen for standard resolution A4 pages include 1037, 1045, 1109, 1126 and 1143.
|
||||
1109 seems the most-popular. At fine res 2150, 2196, 2200, 2237, 2252-2262, 2264,
|
||||
2286, and 2394 are used. 2255 seems the most popular. We try to use balanced choices
|
||||
here.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/* A4 is 297mm long */
|
||||
T4_LENGTH_STANDARD_A4 = 1143,
|
||||
T4_LENGTH_FINE_A4 = 2286,
|
||||
T4_LENGTH_300_A4 = 4665,
|
||||
T4_LENGTH_SUPERFINE_A4 = 4573,
|
||||
T4_LENGTH_600_A4 = 6998,
|
||||
T4_LENGTH_800_A4 = 9330,
|
||||
T4_LENGTH_1200_A4 = 13996,
|
||||
/* B4 is 364mm long */
|
||||
T4_LENGTH_STANDARD_B4 = 1401,
|
||||
T4_LENGTH_FINE_B4 = 2802,
|
||||
T4_LENGTH_300_B4 = 0,
|
||||
T4_LENGTH_SUPERFINE_B4 = 5605,
|
||||
T4_LENGTH_600_B4 = 0,
|
||||
T4_LENGTH_800_B4 = 0,
|
||||
T4_LENGTH_1200_B4 = 0,
|
||||
/* North American letter is 279.4mm long */
|
||||
T4_LENGTH_STANDARD_US_LETTER = 1075,
|
||||
T4_LENGTH_FINE_US_LETTER = 2151,
|
||||
T4_LENGTH_300_US_LETTER = 0,
|
||||
T4_LENGTH_SUPERFINE_US_LETTER = 4302,
|
||||
T4_LENGTH_600_US_LETTER = 0,
|
||||
T4_LENGTH_800_US_LETTER = 0,
|
||||
T4_LENGTH_1200_US_LETTER = 0,
|
||||
/* North American legal is 355.6mm long */
|
||||
T4_LENGTH_STANDARD_US_LEGAL = 1369,
|
||||
T4_LENGTH_FINE_US_LEGAL = 2738,
|
||||
T4_LENGTH_300_US_LEGAL = 0,
|
||||
T4_LENGTH_SUPERFINE_US_LEGAL = 5476,
|
||||
T4_LENGTH_600_US_LEGAL = 0,
|
||||
T4_LENGTH_800_US_LEGAL = 0,
|
||||
T4_LENGTH_1200_US_LEGAL = 0
|
||||
} t4_image_length_t;
|
||||
|
||||
/*!
|
||||
T.4 FAX compression/decompression descriptor. This defines the working state
|
||||
for a single instance of a T.4 FAX compression or decompression channel.
|
||||
*/
|
||||
typedef struct t4_state_s t4_state_t;
|
||||
|
||||
/*!
|
||||
T.4 FAX compression/decompression statistics.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*! \brief The number of pages transferred so far. */
|
||||
int pages_transferred;
|
||||
/*! \brief The number of pages in the file (<0 if unknown). */
|
||||
int pages_in_file;
|
||||
/*! \brief The number of horizontal pixels in the most recent page. */
|
||||
int width;
|
||||
/*! \brief The number of vertical pixels in the most recent page. */
|
||||
int length;
|
||||
/*! \brief The number of bad pixel rows in the most recent page. */
|
||||
int bad_rows;
|
||||
/*! \brief The largest number of bad pixel rows in a block in the most recent page. */
|
||||
int longest_bad_row_run;
|
||||
/*! \brief The horizontal resolution of the page in pixels per metre */
|
||||
int x_resolution;
|
||||
/*! \brief The vertical resolution of the page in pixels per metre */
|
||||
int y_resolution;
|
||||
/*! \brief The type of compression used between the FAX machines */
|
||||
int encoding;
|
||||
/*! \brief The size of the image on the line, in bytes */
|
||||
int line_image_size;
|
||||
} t4_stats_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! \brief Prepare for reception of a document.
|
||||
\param s The T.4 context.
|
||||
\param file The name of the file to be received.
|
||||
\param output_encoding The output encoding.
|
||||
\return A pointer to the context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(t4_state_t *) t4_rx_init(t4_state_t *s, const char *file, int output_encoding);
|
||||
|
||||
/*! \brief Prepare to receive the next page of the current document.
|
||||
\param s The T.4 context.
|
||||
\return zero for success, -1 for failure. */
|
||||
SPAN_DECLARE(int) t4_rx_start_page(t4_state_t *s);
|
||||
|
||||
/*! \brief Put a bit of the current document page.
|
||||
\param s The T.4 context.
|
||||
\param bit The data bit.
|
||||
\return TRUE when the bit ends the document page, otherwise FALSE. */
|
||||
SPAN_DECLARE(int) t4_rx_put_bit(t4_state_t *s, int bit);
|
||||
|
||||
/*! \brief Put a byte of the current document page.
|
||||
\param s The T.4 context.
|
||||
\param byte The data byte.
|
||||
\return TRUE when the byte ends the document page, otherwise FALSE. */
|
||||
SPAN_DECLARE(int) t4_rx_put_byte(t4_state_t *s, uint8_t byte);
|
||||
|
||||
/*! \brief Put a byte of the current document page.
|
||||
\param s The T.4 context.
|
||||
\param buf The buffer containing the chunk.
|
||||
\param len The length of the chunk.
|
||||
\return TRUE when the byte ends the document page, otherwise FALSE. */
|
||||
SPAN_DECLARE(int) t4_rx_put_chunk(t4_state_t *s, const uint8_t buf[], int len);
|
||||
|
||||
/*! \brief Complete the reception of a page.
|
||||
\param s The T.4 receive context.
|
||||
\return 0 for success, otherwise -1. */
|
||||
SPAN_DECLARE(int) t4_rx_end_page(t4_state_t *s);
|
||||
|
||||
/*! \brief End reception of a document. Tidy up and close the file.
|
||||
This should be used to end T.4 reception started with
|
||||
t4_rx_init.
|
||||
\param s The T.4 receive context.
|
||||
\return 0 for success, otherwise -1. */
|
||||
SPAN_DECLARE(int) t4_rx_release(t4_state_t *s);
|
||||
|
||||
/*! \brief End reception of a document. Tidy up, close the file and
|
||||
free the context. This should be used to end T.4 reception
|
||||
started with t4_rx_init.
|
||||
\param s The T.4 receive context.
|
||||
\return 0 for success, otherwise -1. */
|
||||
SPAN_DECLARE(int) t4_rx_free(t4_state_t *s);
|
||||
|
||||
/*! \brief Set the row write handler for a T.4 receive context.
|
||||
\param s The T.4 receive context.
|
||||
\param handler A pointer to the handler routine.
|
||||
\param user_data An opaque pointer passed to the handler routine.
|
||||
\return 0 for success, otherwise -1. */
|
||||
SPAN_DECLARE(int) t4_rx_set_row_write_handler(t4_state_t *s, t4_row_write_handler_t handler, void *user_data);
|
||||
|
||||
/*! \brief Set the encoding for the received data.
|
||||
\param s The T.4 context.
|
||||
\param encoding The encoding. */
|
||||
SPAN_DECLARE(void) t4_rx_set_rx_encoding(t4_state_t *s, int encoding);
|
||||
|
||||
/*! \brief Set the expected width of the received image, in pixel columns.
|
||||
\param s The T.4 context.
|
||||
\param width The number of pixels across the image. */
|
||||
SPAN_DECLARE(void) t4_rx_set_image_width(t4_state_t *s, int width);
|
||||
|
||||
/*! \brief Set the row-to-row (y) resolution to expect for a received image.
|
||||
\param s The T.4 context.
|
||||
\param resolution The resolution, in pixels per metre. */
|
||||
SPAN_DECLARE(void) t4_rx_set_y_resolution(t4_state_t *s, int resolution);
|
||||
|
||||
/*! \brief Set the column-to-column (x) resolution to expect for a received image.
|
||||
\param s The T.4 context.
|
||||
\param resolution The resolution, in pixels per metre. */
|
||||
SPAN_DECLARE(void) t4_rx_set_x_resolution(t4_state_t *s, int resolution);
|
||||
|
||||
/*! \brief Set the DCS information of the fax, for inclusion in the file.
|
||||
\param s The T.4 context.
|
||||
\param dcs The DCS information, formatted as an ASCII string. */
|
||||
SPAN_DECLARE(void) t4_rx_set_dcs(t4_state_t *s, const char *dcs);
|
||||
|
||||
/*! \brief Set the sub-address of the fax, for inclusion in the file.
|
||||
\param s The T.4 context.
|
||||
\param sub_address The sub-address string. */
|
||||
SPAN_DECLARE(void) t4_rx_set_sub_address(t4_state_t *s, const char *sub_address);
|
||||
|
||||
/*! \brief Set the identity of the remote machine, for inclusion in the file.
|
||||
\param s The T.4 context.
|
||||
\param ident The identity string. */
|
||||
SPAN_DECLARE(void) t4_rx_set_far_ident(t4_state_t *s, const char *ident);
|
||||
|
||||
/*! \brief Set the vendor of the remote machine, for inclusion in the file.
|
||||
\param s The T.4 context.
|
||||
\param vendor The vendor string, or NULL. */
|
||||
SPAN_DECLARE(void) t4_rx_set_vendor(t4_state_t *s, const char *vendor);
|
||||
|
||||
/*! \brief Set the model of the remote machine, for inclusion in the file.
|
||||
\param s The T.4 context.
|
||||
\param model The model string, or NULL. */
|
||||
SPAN_DECLARE(void) t4_rx_set_model(t4_state_t *s, const char *model);
|
||||
|
||||
/*! Get the current image transfer statistics.
|
||||
\brief Get the current transfer statistics.
|
||||
\param s The T.4 context.
|
||||
\param t A pointer to a statistics structure. */
|
||||
SPAN_DECLARE(void) t4_get_transfer_statistics(t4_state_t *s, t4_stats_t *t);
|
||||
|
||||
/*! Get the short text name of an encoding format.
|
||||
\brief Get the short text name of an encoding format.
|
||||
\param encoding The encoding type.
|
||||
\return A pointer to the string. */
|
||||
SPAN_DECLARE(const char *) t4_encoding_to_str(int encoding);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* t4_tx.h - definitions for T.4 FAX transmit processing
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2003 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* 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: t4_tx.h,v 1.2.2.3 2009/12/21 17:18:40 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_SPANDSP_T4_TX_H_)
|
||||
#define _SPANDSP_T4_TX_H_
|
||||
|
||||
typedef int (*t4_row_read_handler_t)(void *user_data, uint8_t buf[], size_t len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! \brief Prepare for transmission of a document.
|
||||
\param s The T.4 context.
|
||||
\param file The name of the file to be sent.
|
||||
\param start_page The first page to send. -1 for no restriction.
|
||||
\param stop_page The last page to send. -1 for no restriction.
|
||||
\return A pointer to the context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(t4_state_t *) t4_tx_init(t4_state_t *s, const char *file, int start_page, int stop_page);
|
||||
|
||||
/*! \brief Prepare to send the next page of the current document.
|
||||
\param s The T.4 context.
|
||||
\return zero for success, -1 for failure. */
|
||||
SPAN_DECLARE(int) t4_tx_start_page(t4_state_t *s);
|
||||
|
||||
/*! \brief Prepare the current page for a resend.
|
||||
\param s The T.4 context.
|
||||
\return zero for success, -1 for failure. */
|
||||
SPAN_DECLARE(int) t4_tx_restart_page(t4_state_t *s);
|
||||
|
||||
/*! \brief Check for the existance of the next page, and whether its format is like the
|
||||
current one. This information can be needed before it is determined that the current
|
||||
page is finished with.
|
||||
\param s The T.4 context.
|
||||
\return 0 for next page found with the same format as the current page.
|
||||
1 for next page found with different format from the current page.
|
||||
-1 for no page found, or file failure. */
|
||||
SPAN_DECLARE(int) t4_tx_next_page_has_different_format(t4_state_t *s);
|
||||
|
||||
/*! \brief Complete the sending of a page.
|
||||
\param s The T.4 context.
|
||||
\return zero for success, -1 for failure. */
|
||||
SPAN_DECLARE(int) t4_tx_end_page(t4_state_t *s);
|
||||
|
||||
/*! \brief Return the next bit of the current document page, without actually
|
||||
moving forward in the buffer. The document will be padded for the
|
||||
current minimum scan line time.
|
||||
\param s The T.4 context.
|
||||
\return The next bit (i.e. 0 or 1). For the last bit of data, bit 1 is
|
||||
set (i.e. the returned value is 2 or 3). */
|
||||
SPAN_DECLARE(int) t4_tx_check_bit(t4_state_t *s);
|
||||
|
||||
/*! \brief Get the next bit of the current document page. The document will
|
||||
be padded for the current minimum scan line time.
|
||||
\param s The T.4 context.
|
||||
\return The next bit (i.e. 0 or 1). For the last bit of data, bit 1 is
|
||||
set (i.e. the returned value is 2 or 3). */
|
||||
SPAN_DECLARE(int) t4_tx_get_bit(t4_state_t *s);
|
||||
|
||||
/*! \brief Get the next byte of the current document page. The document will
|
||||
be padded for the current minimum scan line time.
|
||||
\param s The T.4 context.
|
||||
\return The next byte. For the last byte of data, bit 8 is
|
||||
set. In this case, one or more bits of the byte may be padded with
|
||||
zeros, to complete the byte. */
|
||||
SPAN_DECLARE(int) t4_tx_get_byte(t4_state_t *s);
|
||||
|
||||
/*! \brief Get the next chunk of the current document page. The document will
|
||||
be padded for the current minimum scan line time.
|
||||
\param s The T.4 context.
|
||||
\param buf The buffer into which the chunk is to written.
|
||||
\param max_len The maximum length of the chunk.
|
||||
\return The actual length of the chunk. If this is less than max_len it
|
||||
indicates that the end of the document has been reached. */
|
||||
SPAN_DECLARE(int) t4_tx_get_chunk(t4_state_t *s, uint8_t buf[], int max_len);
|
||||
|
||||
/*! \brief End the transmission of a document. Tidy up and close the file.
|
||||
This should be used to end T.4 transmission started with t4_tx_init.
|
||||
\param s The T.4 context.
|
||||
\return 0 for success, otherwise -1. */
|
||||
SPAN_DECLARE(int) t4_tx_release(t4_state_t *s);
|
||||
|
||||
/*! \brief End the transmission of a document. Tidy up, close the file and
|
||||
free the context. This should be used to end T.4 transmission
|
||||
started with t4_tx_init.
|
||||
\param s The T.4 context.
|
||||
\return 0 for success, otherwise -1. */
|
||||
SPAN_DECLARE(int) t4_tx_free(t4_state_t *s);
|
||||
|
||||
/*! \brief Set the encoding for the encoded data.
|
||||
\param s The T.4 context.
|
||||
\param encoding The encoding. */
|
||||
SPAN_DECLARE(void) t4_tx_set_tx_encoding(t4_state_t *s, int encoding);
|
||||
|
||||
/*! \brief Set the minimum number of encoded bits per row. This allows the
|
||||
makes the encoding process to be set to comply with the minimum row
|
||||
time specified by a remote receiving machine.
|
||||
\param s The T.4 context.
|
||||
\param bits The minimum number of bits per row. */
|
||||
SPAN_DECLARE(void) t4_tx_set_min_row_bits(t4_state_t *s, int bits);
|
||||
|
||||
/*! \brief Set the identity of the local machine, for inclusion in page headers.
|
||||
\param s The T.4 context.
|
||||
\param ident The identity string. */
|
||||
SPAN_DECLARE(void) t4_tx_set_local_ident(t4_state_t *s, const char *ident);
|
||||
|
||||
/*! Set the info field, included in the header line included in each page of an encoded
|
||||
FAX. This is a string of up to 50 characters. Other information (date, local ident, etc.)
|
||||
are automatically included in the header. If the header info is set to NULL or a zero
|
||||
length string, no header lines will be added to the encoded FAX.
|
||||
\brief Set the header info.
|
||||
\param s The T.4 context.
|
||||
\param info A string, of up to 50 bytes, which will form the info field. */
|
||||
SPAN_DECLARE(void) t4_tx_set_header_info(t4_state_t *s, const char *info);
|
||||
|
||||
/*! \brief Set the row read handler for a T.4 transmit context.
|
||||
\param s The T.4 transmit context.
|
||||
\param handler A pointer to the handler routine.
|
||||
\param user_data An opaque pointer passed to the handler routine.
|
||||
\return 0 for success, otherwise -1. */
|
||||
SPAN_DECLARE(int) t4_tx_set_row_read_handler(t4_state_t *s, t4_row_read_handler_t handler, void *user_data);
|
||||
|
||||
/*! \brief Get the row-to-row (y) resolution of the current page.
|
||||
\param s The T.4 context.
|
||||
\return The resolution, in pixels per metre. */
|
||||
SPAN_DECLARE(int) t4_tx_get_y_resolution(t4_state_t *s);
|
||||
|
||||
/*! \brief Get the column-to-column (x) resolution of the current page.
|
||||
\param s The T.4 context.
|
||||
\return The resolution, in pixels per metre. */
|
||||
SPAN_DECLARE(int) t4_tx_get_x_resolution(t4_state_t *s);
|
||||
|
||||
/*! \brief Get the width of the current page, in pixel columns.
|
||||
\param s The T.4 context.
|
||||
\return The number of columns. */
|
||||
SPAN_DECLARE(int) t4_tx_get_image_width(t4_state_t *s);
|
||||
|
||||
/*! \brief Get the number of pages in the file.
|
||||
\param s The T.4 context.
|
||||
\return The number of pages, or -1 if there is an error. */
|
||||
SPAN_DECLARE(int) t4_tx_get_pages_in_file(t4_state_t *s);
|
||||
|
||||
/*! \brief Get the currnet page number in the file.
|
||||
\param s The T.4 context.
|
||||
\return The page number, or -1 if there is an error. */
|
||||
SPAN_DECLARE(int) t4_tx_get_current_page_in_file(t4_state_t *s);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: telephony.h,v 1.18 2009/03/23 14:17:42 steveu Exp $
|
||||
* $Id: telephony.h,v 1.18.4.2 2009/12/21 18:38:06 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_TELEPHONY_H_)
|
||||
@@ -69,8 +69,8 @@ typedef int (span_rx_fillin_handler_t)(void *s, int len);
|
||||
/*! \brief A handler for transmit, where the buffer will be filled. */
|
||||
typedef int (span_tx_handler_t)(void *s, int16_t amp[], int max_len);
|
||||
|
||||
#define ms_to_samples(t) (((t)*SAMPLE_RATE)/1000)
|
||||
#define us_to_samples(t) (((t)*SAMPLE_RATE)/1000000)
|
||||
#define ms_to_samples(t) ((t)*(SAMPLE_RATE/1000))
|
||||
#define us_to_samples(t) ((t)/(1000000/SAMPLE_RATE))
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v18.h,v 1.5 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: v18.h,v 1.6 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -69,14 +69,14 @@ SPAN_DECLARE(logging_state_t *) v18_get_logging_state(v18_state_t *s);
|
||||
/*! Initialise a V.18 context.
|
||||
\brief Initialise a V.18 context.
|
||||
\param s The V.18 context.
|
||||
\param caller TRUE if caller mode, else answerer mode.
|
||||
\param calling_party TRUE if caller mode, else answerer mode.
|
||||
\param mode Mode of operation.
|
||||
\param put_msg A callback routine called to deliver the received text
|
||||
to the application.
|
||||
\param user_data An opaque pointer for the callback routine.
|
||||
\return A pointer to the V.18 context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
||||
int caller,
|
||||
int calling_party,
|
||||
int mode,
|
||||
put_msg_func_t put_msg,
|
||||
void *user_data);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v22bis.h,v 1.45 2009/07/09 13:52:09 steveu Exp $
|
||||
* $Id: v22bis.h,v 1.46 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -164,7 +164,7 @@ SPAN_DECLARE(int) v22bis_current_bit_rate(v22bis_state_t *s);
|
||||
\param s The modem context.
|
||||
\param bit_rate The bit rate of the modem. Valid values are 1200 and 2400.
|
||||
\param guard The guard tone option. 0 = none, 1 = 550Hz, 2 = 1800Hz.
|
||||
\param caller TRUE if this is the calling modem.
|
||||
\param calling_party TRUE if this is the calling modem.
|
||||
\param get_bit The callback routine used to get the data to be transmitted.
|
||||
\param put_bit The callback routine used to get the data to be transmitted.
|
||||
\param user_data An opaque pointer, passed in calls to the get and put routines.
|
||||
@@ -172,7 +172,7 @@ SPAN_DECLARE(int) v22bis_current_bit_rate(v22bis_state_t *s);
|
||||
SPAN_DECLARE(v22bis_state_t *) v22bis_init(v22bis_state_t *s,
|
||||
int bit_rate,
|
||||
int guard,
|
||||
int caller,
|
||||
int calling_party,
|
||||
get_bit_func_t get_bit,
|
||||
void *get_bit_user_data,
|
||||
put_bit_func_t put_bit,
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v42.h,v 1.30 2009/02/10 13:06:47 steveu Exp $
|
||||
* $Id: v42.h,v 1.31 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page v42_page V.42 modem error correction
|
||||
@@ -130,12 +130,12 @@ SPAN_DECLARE(int) v42_tx_bit(void *user_data);
|
||||
|
||||
/*! Initialise a V.42 context.
|
||||
\param s The V.42 context.
|
||||
\param caller TRUE if caller mode, else answerer mode.
|
||||
\param calling_party TRUE if caller mode, else answerer mode.
|
||||
\param frame_handler A callback function to handle received frames of data.
|
||||
\param user_data An opaque pointer passed to the frame handler routine.
|
||||
\return ???
|
||||
*/
|
||||
SPAN_DECLARE(v42_state_t *) v42_init(v42_state_t *s, int caller, int detect, v42_frame_handler_t frame_handler, void *user_data);
|
||||
SPAN_DECLARE(v42_state_t *) v42_init(v42_state_t *s, int calling_party, int detect, v42_frame_handler_t frame_handler, void *user_data);
|
||||
|
||||
/*! Restart a V.42 context.
|
||||
\param s The V.42 context.
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v8.h,v 1.28 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: v8.h,v 1.31 2009/11/04 16:10:14 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -50,13 +50,13 @@ typedef void (v8_result_handler_t)(void *user_data, v8_result_t *result);
|
||||
enum v8_call_function_e
|
||||
{
|
||||
V8_CALL_TBS = 0,
|
||||
V8_CALL_H324,
|
||||
V8_CALL_V18,
|
||||
V8_CALL_T101,
|
||||
V8_CALL_T30_TX,
|
||||
V8_CALL_T30_RX,
|
||||
V8_CALL_V_SERIES,
|
||||
V8_CALL_FUNCTION_EXTENSION
|
||||
V8_CALL_H324 = 1,
|
||||
V8_CALL_V18 = 2,
|
||||
V8_CALL_T101 = 3,
|
||||
V8_CALL_T30_TX = 4,
|
||||
V8_CALL_T30_RX = 5,
|
||||
V8_CALL_V_SERIES = 6,
|
||||
V8_CALL_FUNCTION_EXTENSION = 7
|
||||
};
|
||||
|
||||
enum v8_modulation_e
|
||||
@@ -88,30 +88,33 @@ enum v8_protocol_e
|
||||
|
||||
enum v8_pstn_access_e
|
||||
{
|
||||
V8_PSTN_ACCESS_CALL_DCE_CELLULAR = 0x20,
|
||||
V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR = 0x40,
|
||||
V8_PSTN_ACCESS_DCE_ON_DIGTIAL = 0x80
|
||||
V8_PSTN_ACCESS_CALL_DCE_CELLULAR = 0x01,
|
||||
V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR = 0x02,
|
||||
V8_PSTN_ACCESS_DCE_ON_DIGITAL = 0x04
|
||||
};
|
||||
|
||||
enum v8_pcm_modem_availability_e
|
||||
{
|
||||
V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE = 0x20,
|
||||
V8_PSTN_PCM_MODEM_V90_V92_DIGITAL = 0x40,
|
||||
V8_PSTN_PCM_MODEM_V91 = 0x80
|
||||
V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE = 0x01,
|
||||
V8_PSTN_PCM_MODEM_V90_V92_DIGITAL = 0x02,
|
||||
V8_PSTN_PCM_MODEM_V91 = 0x04
|
||||
};
|
||||
|
||||
typedef struct v8_state_s v8_state_t;
|
||||
|
||||
struct v8_result_s
|
||||
{
|
||||
int modem_connect_tone_detected;
|
||||
int call_function;
|
||||
int available_modulations;
|
||||
int far_end_modulations;
|
||||
int negotiated_modulation;
|
||||
int protocol;
|
||||
int pstn_access;
|
||||
int nsf_seen;
|
||||
int nsf;
|
||||
int pcm_modem_availability;
|
||||
int t66_seen;
|
||||
int t66;
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -122,14 +125,16 @@ extern "C"
|
||||
/*! Initialise a V.8 context.
|
||||
\brief Initialise a V.8 context.
|
||||
\param s The V.8 context.
|
||||
\param caller TRUE if caller mode, else answerer mode.
|
||||
\param calling_party TRUE if caller mode, else answerer mode.
|
||||
\param use_ansam_pr TRUE if ANSam/ is to be used, else ANSam will be used.
|
||||
\param available_modulations A bitwise list of the modulation schemes to be
|
||||
advertised as available here.
|
||||
\param result_handler The callback routine used to handle the results of negotiation.
|
||||
\param user_data An opaque pointer passed to the result_handler routine.
|
||||
\return A pointer to the V.8 context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(v8_state_t *) v8_init(v8_state_t *s,
|
||||
int caller,
|
||||
int calling_party,
|
||||
int use_ansam_pr,
|
||||
int available_modulations,
|
||||
v8_result_handler_t *result_handler,
|
||||
void *user_data);
|
||||
@@ -175,7 +180,9 @@ SPAN_DECLARE(const char *) v8_call_function_to_str(int call_function);
|
||||
SPAN_DECLARE(const char *) v8_modulation_to_str(int modulation_scheme);
|
||||
SPAN_DECLARE(const char *) v8_protocol_to_str(int protocol);
|
||||
SPAN_DECLARE(const char *) v8_pstn_access_to_str(int pstn_access);
|
||||
SPAN_DECLARE(const char *) v8_nsf_to_str(int nsf);
|
||||
SPAN_DECLARE(const char *) v8_pcm_modem_availability_to_str(int pcm_modem_availability);
|
||||
SPAN_DECLARE(const char *) v8_t66_to_str(int t66);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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: version.h.in,v 1.3 2009/03/01 12:39:02 steveu Exp $
|
||||
* $Id: version.h.in,v 1.3.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_VERSION_H_)
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
/* The date and time of the version are in UTC form. */
|
||||
|
||||
#define SPANDSP_RELEASE_DATE 20091005
|
||||
#define SPANDSP_RELEASE_TIME 163835
|
||||
#define SPANDSP_RELEASE_DATETIME_STRING "20091005 163835"
|
||||
#define SPANDSP_RELEASE_DATE 20091221
|
||||
#define SPANDSP_RELEASE_TIME 183911
|
||||
#define SPANDSP_RELEASE_DATETIME_STRING "20091221 183911"
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
|
||||
@@ -10,19 +10,19 @@
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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: version.h.in,v 1.3 2009/03/01 12:39:02 steveu Exp $
|
||||
* $Id: version.h.in,v 1.3.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_VERSION_H_)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: super_tone_rx.c,v 1.33 2009/02/10 13:06:46 steveu Exp $
|
||||
* $Id: super_tone_rx.c,v 1.33.4.1 2009/12/19 09:47:56 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -218,8 +218,23 @@ SPAN_DECLARE(super_tone_rx_descriptor_t *) super_tone_rx_make_descriptor(super_t
|
||||
|
||||
SPAN_DECLARE(int) super_tone_rx_free_descriptor(super_tone_rx_descriptor_t *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
for (i = 0; i < desc->tones; i++)
|
||||
{
|
||||
if (desc->tone_list[i])
|
||||
free(desc->tone_list[i]);
|
||||
}
|
||||
if (desc->tone_list)
|
||||
free(desc->tone_list);
|
||||
if (desc->tone_segs)
|
||||
free(desc->tone_segs);
|
||||
if (desc->desc)
|
||||
free(desc->desc);
|
||||
free(desc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
+273
-218
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t30_api.c,v 1.13 2009/02/03 16:28:40 steveu Exp $
|
||||
* $Id: t30_api.c,v 1.13.4.2 2009/12/19 14:18:13 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -60,7 +60,8 @@
|
||||
#include "spandsp/v29tx.h"
|
||||
#include "spandsp/v27ter_rx.h"
|
||||
#include "spandsp/v27ter_tx.h"
|
||||
#include "spandsp/t4.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/t30_fcf.h"
|
||||
#include "spandsp/t35.h"
|
||||
#include "spandsp/t30.h"
|
||||
@@ -68,7 +69,8 @@
|
||||
#include "spandsp/t30_logging.h"
|
||||
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t4.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
||||
#include "t30_local.h"
|
||||
@@ -83,7 +85,7 @@ SPAN_DECLARE(int) t30_set_tx_ident(t30_state_t *s, const char *id)
|
||||
if (strlen(id) > T30_MAX_IDENT_LEN)
|
||||
return -1;
|
||||
strcpy(s->tx_info.ident, id);
|
||||
t4_tx_set_local_ident(&(s->t4), s->tx_info.ident);
|
||||
t4_tx_set_local_ident(&s->t4, s->tx_info.ident);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -544,7 +546,7 @@ SPAN_DECLARE(int) t30_set_tx_page_header_info(t30_state_t *s, const char *info)
|
||||
if (strlen(info) > T30_MAX_PAGE_HEADER_INFO)
|
||||
return -1;
|
||||
strcpy(s->header_info, info);
|
||||
t4_tx_set_header_info(&(s->t4), s->header_info);
|
||||
t4_tx_set_header_info(&s->t4, s->header_info);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t30_logging.c,v 1.12 2009/04/12 09:12:10 steveu Exp $
|
||||
* $Id: t30_logging.c,v 1.12.4.2 2009/12/19 10:44:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -60,14 +60,16 @@
|
||||
#include "spandsp/v29tx.h"
|
||||
#include "spandsp/v27ter_rx.h"
|
||||
#include "spandsp/v27ter_tx.h"
|
||||
#include "spandsp/t4.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/t30_fcf.h"
|
||||
#include "spandsp/t35.h"
|
||||
#include "spandsp/t30.h"
|
||||
#include "spandsp/t30_logging.h"
|
||||
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t4.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
||||
#include "t30_local.h"
|
||||
@@ -931,7 +933,7 @@ SPAN_DECLARE(void) t30_decode_dis_dtc_dcs(t30_state_t *s, const uint8_t *pkt, in
|
||||
octet_bit_field(log, pkt, 121, "Flow control capability for T.38 communication", NULL, NULL);
|
||||
octet_bit_field(log, pkt, 122, "K>4", NULL, NULL);
|
||||
octet_bit_field(log, pkt, 123, "Internet aware T.38 mode fax (not affected by data signal rate bits)", NULL, NULL);
|
||||
octet_field(log, pkt, 124, 126, "T.89 (Application profiles for ITU-T Rec T.8)", t89_profile_tags);
|
||||
octet_field(log, pkt, 124, 126, "T.89 (Application profiles for ITU-T Rec T.88)", t89_profile_tags);
|
||||
octet_bit_field(log, pkt, 127, "sYCC-JPEG coding", NULL, NULL);
|
||||
octet_bit_field(log, pkt, 128, "Extension indicator", NULL, NULL);
|
||||
if (!(pkt[18] & DISBIT8))
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t31.c,v 1.153 2009/10/05 16:33:25 steveu Exp $
|
||||
* $Id: t31.c,v 1.155.4.1 2009/12/19 10:44:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -74,7 +74,8 @@
|
||||
#include "spandsp/v17rx.h"
|
||||
#include "spandsp/super_tone_rx.h"
|
||||
#include "spandsp/modem_connect_tones.h"
|
||||
#include "spandsp/t4.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/t30.h"
|
||||
#include "spandsp/t30_logging.h"
|
||||
#include "spandsp/t38_core.h"
|
||||
@@ -1293,12 +1294,12 @@ static int non_ecm_get_chunk(void *user_data, uint8_t buf[], int len)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void tone_detected(void *user_data, int on, int level, int delay)
|
||||
static void tone_detected(void *user_data, int tone, int level, int delay)
|
||||
{
|
||||
t31_state_t *s;
|
||||
|
||||
s = (t31_state_t *) user_data;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "FAX tone declared %s (%ddBm0)\n", (on) ? "on" : "off", level);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s detected (%ddBm0)\n", modem_connect_tone_to_str(tone), level);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@@ -1509,7 +1510,7 @@ static void t31_v21_rx(t31_state_t *s)
|
||||
s->hdlc_tx.len = 0;
|
||||
s->dled = FALSE;
|
||||
hdlc_rx_init(&(s->audio.modems.hdlc_rx), FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept_frame, s);
|
||||
fsk_rx_init(&(s->audio.modems.v21_rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &(s->audio.modems.hdlc_rx));
|
||||
fsk_rx_init(&(s->audio.modems.v21_rx), &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, &(s->audio.modems.hdlc_rx));
|
||||
fsk_rx_signal_cutoff(&(s->audio.modems.v21_rx), -39.09f);
|
||||
s->at_state.transmit = TRUE;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_core.c,v 1.53 2009/07/14 13:54:22 steveu Exp $
|
||||
* $Id: t38_core.c,v 1.54 2009/10/09 14:53:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -224,17 +224,17 @@ SPAN_DECLARE(const char *) t38_cm_profile_to_str(int profile)
|
||||
switch (profile)
|
||||
{
|
||||
case '1':
|
||||
return "G3 Facsimile Terminal: (Sending Facsimile)";
|
||||
return "G3 FAX sending terminal";
|
||||
case '2':
|
||||
return "G3 Facsimile Terminal: (Receiving Facsimile)";
|
||||
return "G3 FAX receiving terminal";
|
||||
case '3':
|
||||
return "V.34 HDX and G3 Facsimile Terminal: (Sending Facsimile)";
|
||||
return "V.34 HDX and G3 FAX sending terminal";
|
||||
case '4':
|
||||
return "V.34 HDX and G3 Facsimile Terminal: (Receiving Facsimile)";
|
||||
return "V.34 HDX and G3 FAX receiving terminal";
|
||||
case '5':
|
||||
return "V.34 HDX-only Facsimile Terminal: (Sending Facsimile)";
|
||||
return "V.34 HDX-only FAX sending terminal";
|
||||
case '6':
|
||||
return "V.34 HDX-only Facsimile Terminal: (Receiving Facsimile)";
|
||||
return "V.34 HDX-only FAX receiving terminal";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
@@ -260,10 +260,10 @@ SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len)
|
||||
return "NACK: No compatible mode available";
|
||||
case '1':
|
||||
/* Response for profiles 1 and 2 */
|
||||
return "NACK: No V.34 fax, use G3 fax";
|
||||
return "NACK: No V.34 FAX, use G3 FAX";
|
||||
case '2':
|
||||
/* Response for profiles 5 and 6 */
|
||||
return "NACK: V.34 fax only.";
|
||||
return "NACK: V.34 only FAX.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+119
-66
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_gateway.c,v 1.164 2009/07/14 13:54:22 steveu Exp $
|
||||
* $Id: t38_gateway.c,v 1.171.4.2 2009/12/19 10:44:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -73,7 +73,8 @@
|
||||
#include "spandsp/v17rx.h"
|
||||
#include "spandsp/super_tone_rx.h"
|
||||
#include "spandsp/modem_connect_tones.h"
|
||||
#include "spandsp/t4.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/t30_fcf.h"
|
||||
#include "spandsp/t35.h"
|
||||
#include "spandsp/t30.h"
|
||||
@@ -95,7 +96,8 @@
|
||||
#include "spandsp/private/modem_connect_tones.h"
|
||||
#include "spandsp/private/hdlc.h"
|
||||
#include "spandsp/private/fax_modems.h"
|
||||
#include "spandsp/private/t4.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
#include "spandsp/private/t38_core.h"
|
||||
#include "spandsp/private/t38_non_ecm_buffer.h"
|
||||
@@ -181,7 +183,7 @@ static void t38_hdlc_rx_put_bit(hdlc_rx_state_t *t, int new_bit);
|
||||
static void non_ecm_put_bit(void *user_data, int bit);
|
||||
static void non_ecm_remove_fill_and_put_bit(void *user_data, int bit);
|
||||
static void non_ecm_push_residue(t38_gateway_state_t *s);
|
||||
static void tone_detected(void *user_data, int on, int level, int delay);
|
||||
static void tone_detected(void *user_data, int tone, int level, int delay);
|
||||
|
||||
static void set_rx_handler(t38_gateway_state_t *s, span_rx_handler_t *handler, void *user_data)
|
||||
{
|
||||
@@ -302,12 +304,12 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void tone_detected(void *user_data, int on, int level, int delay)
|
||||
static void tone_detected(void *user_data, int tone, int level, int delay)
|
||||
{
|
||||
t38_gateway_state_t *s;
|
||||
|
||||
s = (t38_gateway_state_t *) user_data;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "FAX tone declared %s (%ddBm0)\n", (on) ? "on" : "off", level);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s detected (%ddBm0)\n", modem_connect_tone_to_str(tone), level);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@@ -540,16 +542,16 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
set_rx_active(s, TRUE);
|
||||
break;
|
||||
case T38_IND_V8_ANSAM:
|
||||
t->tx_bit_rate = 0;
|
||||
t->tx_bit_rate = 300;
|
||||
break;
|
||||
case T38_IND_V8_SIGNAL:
|
||||
t->tx_bit_rate = 0;
|
||||
t->tx_bit_rate = 300;
|
||||
break;
|
||||
case T38_IND_V34_CNTL_CHANNEL_1200:
|
||||
t->tx_bit_rate = 0;
|
||||
t->tx_bit_rate = 1200;
|
||||
break;
|
||||
case T38_IND_V34_PRI_CHANNEL:
|
||||
t->tx_bit_rate = 0;
|
||||
t->tx_bit_rate = 33600;
|
||||
break;
|
||||
case T38_IND_V34_CC_RETRAIN:
|
||||
t->tx_bit_rate = 0;
|
||||
@@ -796,6 +798,13 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
||||
case T30_DCS | 1:
|
||||
/* We need to check which modem type is about to be used, so we can start the
|
||||
correct modem. */
|
||||
s->core.fast_bit_rate = 0;
|
||||
s->core.fast_rx_modem = T38_NONE;
|
||||
s->core.image_data_mode = FALSE;
|
||||
s->core.short_train = FALSE;
|
||||
if (from_modem)
|
||||
s->core.timed_mode = TIMED_MODE_TCF_PREDICTABLE_MODEM_START_BEGIN;
|
||||
/*endif*/
|
||||
if (len >= 5)
|
||||
{
|
||||
/* The table is short, and not searched often, so a brain-dead linear scan seems OK */
|
||||
@@ -807,8 +816,12 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
||||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
/* If we are processing a message from the modem side, the contents determine the fast receive modem.
|
||||
we are to use. If it comes from the T.38 side the contents do not. */
|
||||
s->core.fast_bit_rate = modem_codes[i].bit_rate;
|
||||
s->core.fast_modem = modem_codes[i].modem_type;
|
||||
if (from_modem)
|
||||
s->core.fast_rx_modem = modem_codes[i].modem_type;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
if (len >= 6)
|
||||
@@ -816,26 +829,34 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
||||
j = (buf[5] & (DISBIT7 | DISBIT6 | DISBIT5)) >> 4;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Min bits test = 0x%X\n", buf[5]);
|
||||
s->core.min_row_bits = (s->core.fast_bit_rate*minimum_scan_line_times[j])/1000;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Min bits per row = %d\n", j);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->core.min_row_bits = 0;
|
||||
}
|
||||
/*endif*/
|
||||
s->core.ecm_mode = (len >= 7) && (buf[6] & DISBIT3);
|
||||
s->core.image_data_mode = FALSE;
|
||||
s->core.short_train = FALSE;
|
||||
if (from_modem)
|
||||
s->core.timed_mode = TIMED_MODE_TCF_PREDICTABLE_MODEM_START_BEGIN;
|
||||
/*endif*/
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Fast rx modem = %d/%d, ECM = %d, Min bits per row = %d\n", s->core.fast_rx_modem, s->core.fast_bit_rate, s->core.ecm_mode, s->core.min_row_bits);
|
||||
break;
|
||||
case T30_PPS:
|
||||
case T30_PPS | 1:
|
||||
switch (buf[3] & 0xFE)
|
||||
{
|
||||
case T30_EOP:
|
||||
case T30_EOM:
|
||||
case T30_EOS:
|
||||
case T30_MPS:
|
||||
case T30_PRI_EOP:
|
||||
case T30_EOM:
|
||||
case T30_PRI_EOM:
|
||||
case T30_EOS:
|
||||
#if 0
|
||||
/* If we are hitting one of these conditions, it will take another DCS/DTC to select
|
||||
the fast modem again, so abandon our idea of it. */
|
||||
s->core.fast_bit_rate = 0;
|
||||
s->core.fast_rx_modem = T38_NONE;
|
||||
s->core.image_data_mode = FALSE;
|
||||
s->core.short_train = FALSE;
|
||||
#endif
|
||||
/* Fall through */
|
||||
case T30_MPS:
|
||||
case T30_PRI_MPS:
|
||||
s->core.count_page_on_mcf = TRUE;
|
||||
break;
|
||||
@@ -843,18 +864,27 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
||||
/*endswitch*/
|
||||
break;
|
||||
case T30_EOP:
|
||||
case T30_EOM:
|
||||
case T30_EOS:
|
||||
case T30_MPS:
|
||||
case T30_PRI_EOP:
|
||||
case T30_PRI_EOM:
|
||||
case T30_PRI_MPS:
|
||||
case T30_EOP | 1:
|
||||
case T30_EOM | 1:
|
||||
case T30_EOS | 1:
|
||||
case T30_MPS | 1:
|
||||
case T30_PRI_EOP:
|
||||
case T30_PRI_EOP | 1:
|
||||
case T30_EOM:
|
||||
case T30_EOM | 1:
|
||||
case T30_PRI_EOM:
|
||||
case T30_PRI_EOM | 1:
|
||||
case T30_EOS:
|
||||
case T30_EOS | 1:
|
||||
#if 0
|
||||
/* If we are hitting one of these conditions, it will take another DCS/DTC to select
|
||||
the fast modem again, so abandon our idea of t. */
|
||||
s->core.fast_bit_rate = 0;
|
||||
s->core.fast_rx_modem = T38_NONE;
|
||||
s->core.image_data_mode = FALSE;
|
||||
s->core.short_train = FALSE;
|
||||
#endif
|
||||
/* Fall through */
|
||||
case T30_MPS:
|
||||
case T30_MPS | 1:
|
||||
case T30_PRI_MPS:
|
||||
case T30_PRI_MPS | 1:
|
||||
s->core.count_page_on_mcf = TRUE;
|
||||
break;
|
||||
@@ -1015,6 +1045,62 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
|
||||
s = (t38_gateway_state_t *) user_data;
|
||||
xx = &s->t38x;
|
||||
/* There are a couple of special cases of data type that need their own treatment. */
|
||||
switch (data_type)
|
||||
{
|
||||
case T38_DATA_V8:
|
||||
switch (field_type)
|
||||
{
|
||||
case T38_FIELD_CM_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CM profile %d - %s\n", buf[0] - '0', t38_cm_profile_to_str(buf[0]));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CM message - %d\n", len);
|
||||
/*endif*/
|
||||
break;
|
||||
case T38_FIELD_JM_MESSAGE:
|
||||
if (len >= 2)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "JM - %s\n", t38_jm_to_str(buf, len));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for JM message - %d\n", len);
|
||||
/*endif*/
|
||||
break;
|
||||
case T38_FIELD_CI_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CI 0x%X\n", buf[0]);
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CI message - %d\n", len);
|
||||
/*endif*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
return 0;
|
||||
case T38_DATA_V34_PRI_RATE:
|
||||
switch (field_type)
|
||||
{
|
||||
case T38_FIELD_V34RATE:
|
||||
if (len >= 3)
|
||||
{
|
||||
xx->t38.v34_rate = t38_v34rate_to_bps(buf, len);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "V.34 rate %d bps\n", xx->t38.v34_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for V34rate message - %d\n", len);
|
||||
}
|
||||
/*endif*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
switch (field_type)
|
||||
{
|
||||
case T38_FIELD_HDLC_DATA:
|
||||
@@ -1352,39 +1438,6 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
/*endif*/
|
||||
xx->corrupt_current_frame[0] = FALSE;
|
||||
break;
|
||||
case T38_FIELD_CM_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CM profile %d - %s\n", buf[0] - '0', t38_cm_profile_to_str(buf[0]));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CM message - %d\n", len);
|
||||
/*endif*/
|
||||
break;
|
||||
case T38_FIELD_JM_MESSAGE:
|
||||
if (len >= 2)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "JM - %s\n", t38_jm_to_str(buf, len));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for JM message - %d\n", len);
|
||||
/*endif*/
|
||||
break;
|
||||
case T38_FIELD_CI_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CI 0x%X\n", buf[0]);
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CI message - %d\n", len);
|
||||
/*endif*/
|
||||
break;
|
||||
case T38_FIELD_V34RATE:
|
||||
if (len >= 3)
|
||||
{
|
||||
xx->t38.v34_rate = t38_v34rate_to_bps(buf, len);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "V.34 rate %d bps\n", xx->t38.v34_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for V34rate message - %d\n", len);
|
||||
}
|
||||
/*endif*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1944,14 +1997,14 @@ static int restart_rx_modem(t38_gateway_state_t *s)
|
||||
s->core.to_t38.in_bits = 0;
|
||||
s->core.to_t38.out_octets = 0;
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Restart rx modem - modem = %d, short train = %d, ECM = %d\n", s->core.fast_modem, s->core.short_train, s->core.ecm_mode);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Restart rx modem - modem = %d, short train = %d, ECM = %d\n", s->core.fast_rx_modem, s->core.short_train, s->core.ecm_mode);
|
||||
|
||||
hdlc_rx_init(&(s->audio.modems.hdlc_rx), FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, NULL, s);
|
||||
s->audio.modems.rx_signal_present = FALSE;
|
||||
s->audio.modems.rx_trained = FALSE;
|
||||
/* Default to the transmit data being V.21, unless a faster modem pops up trained. */
|
||||
s->t38x.current_tx_data_type = T38_DATA_V21;
|
||||
fsk_rx_init(&(s->audio.modems.v21_rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) t38_hdlc_rx_put_bit, &(s->audio.modems.hdlc_rx));
|
||||
fsk_rx_init(&(s->audio.modems.v21_rx), &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) t38_hdlc_rx_put_bit, &(s->audio.modems.hdlc_rx));
|
||||
#if 0
|
||||
fsk_rx_signal_cutoff(&(s->audio.modems.v21_rx), -45.5f);
|
||||
#endif
|
||||
@@ -1971,7 +2024,7 @@ static int restart_rx_modem(t38_gateway_state_t *s)
|
||||
/*endif*/
|
||||
to_t38_buffer_init(&s->core.to_t38);
|
||||
s->core.to_t38.octets_per_data_packet = 1;
|
||||
switch (s->core.fast_modem)
|
||||
switch (s->core.fast_rx_modem)
|
||||
{
|
||||
case T38_V17_RX:
|
||||
v17_rx_restart(&s->audio.modems.v17_rx, s->core.fast_bit_rate, s->core.short_train);
|
||||
@@ -2245,7 +2298,7 @@ SPAN_DECLARE(t38_gateway_state_t *) t38_gateway_init(t38_gateway_state_t *s,
|
||||
t38_gateway_set_nsx_suppression(s, (const uint8_t *) "\x00\x00\x00", 3, (const uint8_t *) "\x00\x00\x00", 3);
|
||||
|
||||
s->core.to_t38.octets_per_data_packet = 1;
|
||||
s->core.ecm_allowed = FALSE;
|
||||
s->core.ecm_allowed = TRUE;
|
||||
t38_non_ecm_buffer_init(&s->core.non_ecm_to_modem, FALSE, 0);
|
||||
restart_rx_modem(s);
|
||||
s->core.timed_mode = TIMED_MODE_STARTUP;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_non_ecm_buffer.c,v 1.9 2009/10/05 16:33:25 steveu Exp $
|
||||
* $Id: t38_non_ecm_buffer.c,v 1.9.4.1 2009/12/19 06:43:28 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -57,13 +57,22 @@
|
||||
|
||||
#include "spandsp/private/t38_non_ecm_buffer.h"
|
||||
|
||||
/* Phases */
|
||||
enum
|
||||
{
|
||||
TCF_AT_INITIAL_ALL_ONES = 0,
|
||||
TCF_AT_ALL_ZEROS = 1,
|
||||
IMAGE_WAITING_FOR_FIRST_EOL = 2,
|
||||
IMAGE_IN_PROGRESS = 3
|
||||
};
|
||||
|
||||
static void restart_buffer(t38_non_ecm_buffer_state_t *s)
|
||||
{
|
||||
/* This should be called when draining the buffer is complete, which should
|
||||
occur before any fresh data can possibly arrive to begin refilling it. */
|
||||
s->octet = 0xFF;
|
||||
s->flow_control_fill_octet = 0xFF;
|
||||
s->at_initial_all_ones = TRUE;
|
||||
s->input_phase = (s->image_data_mode) ? IMAGE_WAITING_FOR_FIRST_EOL : TCF_AT_INITIAL_ALL_ONES;
|
||||
s->bit_stream = 0xFFFF;
|
||||
s->out_ptr = 0;
|
||||
s->in_ptr = 0;
|
||||
@@ -126,61 +135,164 @@ SPAN_DECLARE(void) t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, cons
|
||||
int upper;
|
||||
int lower;
|
||||
|
||||
/* TCF consists of:
|
||||
- zero or more ones, followed by
|
||||
- about 1.5s of zeros
|
||||
There may be a little junk at the end, as the modem shuts down.
|
||||
|
||||
We can stuff with extra ones in the initial period of all ones, and we can stuff with extra
|
||||
zeros once the zeros start. The thing we need to be wary about is the odd zero bit in the
|
||||
midst of the ones, due to a bit error. */
|
||||
|
||||
/* Non-ECM image data consists of:
|
||||
- zero or more ones, followed by
|
||||
- zero or more zeros, followed by
|
||||
- an EOL (end of line), which marks the start of the image, followed by
|
||||
- a succession of data rows, with an EOL at the end of each, followed by
|
||||
- an RTC (return to control)
|
||||
There may be a little junk at the end, as the modem shuts down.
|
||||
|
||||
An EOL 11 zeros followed by a one in a T.4 1D image or 11 zeros followed by a one followed
|
||||
by a one or a zero in a T.4 2D image. An RTC consists of 6 EOLs in succession, with no
|
||||
pixel data between them.
|
||||
|
||||
We can stuff with ones until we get the first EOL into our buffer, then we can stuff with
|
||||
zeros in front of each EOL at any point up the the RTC. We should not pad between the EOLs
|
||||
which make up the RTC. Most FAX machines don't care about this, but a few will not recognise
|
||||
the RTC if here is padding between the EOLs.
|
||||
|
||||
We need to buffer whole rows before we output their beginning, so there is no possibility
|
||||
of underflow mid-row. */
|
||||
|
||||
/* FoIP has latency issues, because of the fairly tight timeouts in the T.30 spec. We must
|
||||
ensure our buffering does everything needed to avoid underflows, and to meet the minimum
|
||||
row length requirements imposed by many mechanical FAX machines. We cannot, however,
|
||||
afford to bulk up the data, by sending superfluous bytes. The resulting loop delay could
|
||||
provoke an erroneous timeout of the acknowledgement signal. */
|
||||
|
||||
i = 0;
|
||||
if (s->at_initial_all_ones)
|
||||
switch (s->input_phase)
|
||||
{
|
||||
case TCF_AT_INITIAL_ALL_ONES:
|
||||
/* Dump initial 0xFF bytes. We will add enough of our own to makes things flow
|
||||
smoothly. If we don't strip these off, we might end up delaying the start of
|
||||
forwarding by a large amount, as we could end up with a large block of 0xFF
|
||||
forwarding by a substantial amount, as we could end up with a large block of 0xFF
|
||||
bytes before the real data begins. This is especially true with PC FAX
|
||||
systems. This test is very simplistic, as a single bit error will throw it
|
||||
off course. */
|
||||
systems. This test is very simplistic, as bit errors could confuse it. */
|
||||
for ( ; i < len; i++)
|
||||
{
|
||||
if (buf[i] != 0xFF)
|
||||
{
|
||||
s->at_initial_all_ones = FALSE;
|
||||
s->input_phase = TCF_AT_ALL_ZEROS;
|
||||
s->flow_control_fill_octet = 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (s->image_data_mode)
|
||||
{
|
||||
/* This is image data */
|
||||
/* Fall through */
|
||||
case TCF_AT_ALL_ZEROS:
|
||||
for ( ; i < len; i++)
|
||||
{
|
||||
s->data[s->in_ptr] = buf[i];
|
||||
s->latest_eol_ptr = s->in_ptr;
|
||||
/* TODO: We can't buffer overflow, since we wrap around. However, the tail could
|
||||
overwrite itself if things fall badly behind. */
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
s->in_octets++;
|
||||
}
|
||||
break;
|
||||
case IMAGE_WAITING_FOR_FIRST_EOL:
|
||||
/* Dump anything up to the first EOL. Let the output side stuff with 0xFF bytes while waiting
|
||||
for that first EOL. What occurs before the first EOL is expected to be a period of all ones
|
||||
and then a period of all zeros. We really don't care what junk might be there. By definition,
|
||||
the image only starts at the first EOL. */
|
||||
for ( ; i < len; i++)
|
||||
{
|
||||
/* Check for EOLs, because at an EOL we can pause and pump out zeros while
|
||||
waiting for more incoming data. */
|
||||
if (buf[i])
|
||||
{
|
||||
/* There might be an EOL here. Look for at least 11 zeros, followed by a one, split
|
||||
between two octets. Between those two octets we can insert numerous zero octets
|
||||
as a means of flow control. Note that we stuff in blocks of 8 bits, and not at
|
||||
the minimal level. */
|
||||
/* Or'ing with 0x800 here is simply to avoid zero words looking like they have -1
|
||||
/* Or'ing with 0x800 here is to avoid zero words looking like they have -1
|
||||
trailing zeros */
|
||||
upper = bottom_bit(s->bit_stream | 0x800);
|
||||
lower = top_bit(buf[i]);
|
||||
if (upper - lower > 3)
|
||||
if ((upper - lower) > (11 - 8))
|
||||
{
|
||||
/* This is an EOL - our first row is beginning. */
|
||||
s->input_phase = IMAGE_IN_PROGRESS;
|
||||
/* Start a new row */
|
||||
s->row_bits = lower - 8;
|
||||
s->latest_eol_ptr = s->in_ptr;
|
||||
s->flow_control_fill_octet = 0x00;
|
||||
|
||||
/* If we push out two bytes of zero, and our latest non-zero byte
|
||||
we should definitely form a proper EOL to begin things, with a
|
||||
few harmless extra zero bits at the front. */
|
||||
s->data[s->in_ptr] = 0x00;
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
s->data[s->in_ptr] = 0x00;
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
s->data[s->in_ptr] = buf[i];
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
s->in_octets += 3;
|
||||
s->bit_stream = (s->bit_stream << 8) | buf[i];
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s->bit_stream = (s->bit_stream << 8) | buf[i];
|
||||
}
|
||||
if (i >= len)
|
||||
break;
|
||||
/* Fall through */
|
||||
case IMAGE_IN_PROGRESS:
|
||||
/* Now we have seen an EOL, we can stuff with zeros just in front of that EOL, or any
|
||||
subsequent EOL that does not immediately follow a previous EOL (i.e. a candidate RTC).
|
||||
We need to track our way through the image data, allowing the output side to only send
|
||||
up to the last EOL. This prevents the possibility of underflow mid-row, where we cannot
|
||||
safely stuff anything in the bit stream. */
|
||||
for ( ; i < len; i++)
|
||||
{
|
||||
if (buf[i])
|
||||
{
|
||||
/* There might be an EOL here. Look for at least 11 zeros, followed by a one, split
|
||||
between two octets. Between those two octets we can insert numerous zero octets
|
||||
as a means of flow control. Note that we stuff in blocks of 8 bits, and not at
|
||||
the minimal level. */
|
||||
/* Or'ing with 0x800 here is to avoid zero words looking like they have -1
|
||||
trailing zeros */
|
||||
upper = bottom_bit(s->bit_stream | 0x800);
|
||||
lower = top_bit(buf[i]);
|
||||
if ((upper - lower) > (11 - 8))
|
||||
{
|
||||
/* This is an EOL. */
|
||||
s->row_bits += (8 - lower);
|
||||
/* If the row is too short, extend it in chunks of a whole byte. */
|
||||
/* TODO: extend by the precise amount we should, instead of this
|
||||
rough approach. */
|
||||
while (s->row_bits < s->min_row_bits)
|
||||
/* Make sure we don't stretch back to back EOLs, as that could spoil the RTC.
|
||||
This is a slightly crude check, as we don't know if we are processing a T.4 1D
|
||||
or T.4 2D image. Accepting 12 or 12 bits apart as meaning back to back is fine,
|
||||
as no 1D image row could be 1 bit long. */
|
||||
if (s->row_bits < 12 || s->row_bits > 13)
|
||||
{
|
||||
s->min_row_bits_fill_octets++;
|
||||
s->data[s->in_ptr] = 0;
|
||||
s->row_bits += 8;
|
||||
/* TODO: We can't buffer overflow, since we wrap around. However, the tail could
|
||||
overwrite itself if things fall badly behind. */
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
/* If the row is too short, extend it in chunks of a whole byte. */
|
||||
/* TODO: extend by the precise amount we should, instead of this
|
||||
rough approach. */
|
||||
while (s->row_bits < s->min_bits_per_row)
|
||||
{
|
||||
s->min_row_bits_fill_octets++;
|
||||
s->data[s->in_ptr] = 0;
|
||||
s->row_bits += 8;
|
||||
/* TODO: We can't buffer overflow, since we wrap around. However,
|
||||
the tail could overwrite itself if things fall badly behind. */
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
}
|
||||
/* This is now the limit for the output side, before it starts
|
||||
stuffing. */
|
||||
s->latest_eol_ptr = s->in_ptr;
|
||||
}
|
||||
/* Start a new row */
|
||||
s->row_bits = lower - 8;
|
||||
s->in_rows++;
|
||||
s->latest_eol_ptr = s->in_ptr;
|
||||
s->flow_control_fill_octet = 0x00;
|
||||
}
|
||||
}
|
||||
s->bit_stream = (s->bit_stream << 8) | buf[i];
|
||||
@@ -191,26 +303,7 @@ SPAN_DECLARE(void) t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, cons
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
s->in_octets++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is TCF data */
|
||||
for ( ; i < len; i++)
|
||||
{
|
||||
/* Check for zero bytes, as we can pause and pump out zeros while waiting
|
||||
for more incoming data. Of course, the entire TCF data should be zero,
|
||||
but it might not be, due to bit errors, or something weird happening. */
|
||||
if (buf[i] == 0x00)
|
||||
{
|
||||
s->latest_eol_ptr = s->in_ptr;
|
||||
s->flow_control_fill_octet = 0x00;
|
||||
}
|
||||
s->data[s->in_ptr] = buf[i];
|
||||
/* TODO: We can't buffer overflow, since we wrap around. However, the tail could
|
||||
overwrite itself if things fall badly behind. */
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
s->in_octets++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -249,14 +342,14 @@ SPAN_DECLARE(void) t38_non_ecm_buffer_report_output_status(t38_non_ecm_buffer_st
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(void) t38_non_ecm_buffer_set_mode(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits)
|
||||
SPAN_DECLARE(void) t38_non_ecm_buffer_set_mode(t38_non_ecm_buffer_state_t *s, int mode, int min_bits_per_row)
|
||||
{
|
||||
s->image_data_mode = mode;
|
||||
s->min_row_bits = min_row_bits;
|
||||
s->min_bits_per_row = min_bits_per_row;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(t38_non_ecm_buffer_state_t *) t38_non_ecm_buffer_init(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits)
|
||||
SPAN_DECLARE(t38_non_ecm_buffer_state_t *) t38_non_ecm_buffer_init(t38_non_ecm_buffer_state_t *s, int mode, int min_bits_per_row)
|
||||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
@@ -264,12 +357,9 @@ SPAN_DECLARE(t38_non_ecm_buffer_state_t *) t38_non_ecm_buffer_init(t38_non_ecm_b
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->octet = 0xFF;
|
||||
s->flow_control_fill_octet = 0xFF;
|
||||
s->at_initial_all_ones = TRUE;
|
||||
s->bit_stream = 0xFFFF;
|
||||
s->image_data_mode = mode;
|
||||
s->min_row_bits = min_row_bits;
|
||||
s->min_bits_per_row = min_bits_per_row;
|
||||
restart_buffer(s);
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_terminal.c,v 1.128 2009/09/04 14:38:46 steveu Exp $
|
||||
* $Id: t38_terminal.c,v 1.129.4.2 2009/12/19 10:44:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -63,7 +63,8 @@
|
||||
#include "spandsp/v27ter_rx.h"
|
||||
#include "spandsp/v17tx.h"
|
||||
#include "spandsp/v17rx.h"
|
||||
#include "spandsp/t4.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/t30_fcf.h"
|
||||
#include "spandsp/t35.h"
|
||||
#include "spandsp/t30.h"
|
||||
@@ -73,7 +74,8 @@
|
||||
#include "spandsp/t38_terminal.h"
|
||||
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t4.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
#include "spandsp/private/t38_core.h"
|
||||
#include "spandsp/private/t38_terminal.h"
|
||||
@@ -231,8 +233,6 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
|
||||
front_end_status(s, T30_FRONT_END_CED_PRESENT);
|
||||
break;
|
||||
case T38_IND_V21_PREAMBLE:
|
||||
/* Some T.38 implementations insert these preamble indicators between HDLC frames, so
|
||||
we need to be tolerant of that. */
|
||||
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
|
||||
front_end_status(s, T30_FRONT_END_SIGNAL_PRESENT);
|
||||
break;
|
||||
@@ -248,6 +248,8 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
|
||||
case T38_IND_V17_12000_LONG_TRAINING:
|
||||
case T38_IND_V17_14400_SHORT_TRAINING:
|
||||
case T38_IND_V17_14400_LONG_TRAINING:
|
||||
case T38_IND_V34_CNTL_CHANNEL_1200:
|
||||
case T38_IND_V34_PRI_CHANNEL:
|
||||
case T38_IND_V33_12000_TRAINING:
|
||||
case T38_IND_V33_14400_TRAINING:
|
||||
/* We really don't care what kind of modem is delivering the following image data.
|
||||
@@ -257,22 +259,30 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
|
||||
break;
|
||||
case T38_IND_V8_ANSAM:
|
||||
case T38_IND_V8_SIGNAL:
|
||||
case T38_IND_V34_CNTL_CHANNEL_1200:
|
||||
case T38_IND_V34_PRI_CHANNEL:
|
||||
case T38_IND_V34_CC_RETRAIN:
|
||||
/* V.34 support is a work in progress. */
|
||||
front_end_status(s, T30_FRONT_END_SIGNAL_PRESENT);
|
||||
break;
|
||||
default:
|
||||
front_end_status(s, T30_FRONT_END_SIGNAL_ABSENT);
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->rx_data_missing = FALSE;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int fake_rx_indicator(t38_core_state_t *t, t38_terminal_state_t *s, int indicator)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = process_rx_indicator(t, s, indicator);
|
||||
t->current_rx_indicator = indicator;
|
||||
return ret;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len)
|
||||
{
|
||||
t38_terminal_state_t *s;
|
||||
@@ -285,29 +295,64 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
|
||||
s = (t38_terminal_state_t *) user_data;
|
||||
fe = &s->t38_fe;
|
||||
#if 0
|
||||
/* In termination mode we don't care very much what the data type is. */
|
||||
/* In termination mode we don't care very much what the data type is apart from a couple of
|
||||
special cases. */
|
||||
switch (data_type)
|
||||
{
|
||||
case T38_DATA_V21:
|
||||
case T38_DATA_V27TER_2400:
|
||||
case T38_DATA_V27TER_4800:
|
||||
case T38_DATA_V29_7200:
|
||||
case T38_DATA_V29_9600:
|
||||
case T38_DATA_V17_7200:
|
||||
case T38_DATA_V17_9600:
|
||||
case T38_DATA_V17_12000:
|
||||
case T38_DATA_V17_14400:
|
||||
case T38_DATA_V8:
|
||||
switch (field_type)
|
||||
{
|
||||
case T38_FIELD_CM_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CM profile %d - %s\n", buf[0] - '0', t38_cm_profile_to_str(buf[0]));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CM message - %d\n", len);
|
||||
//front_end_status(s, T30_FRONT_END_RECEIVE_COMPLETE);
|
||||
break;
|
||||
case T38_FIELD_JM_MESSAGE:
|
||||
if (len >= 2)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "JM - %s\n", t38_jm_to_str(buf, len));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for JM message - %d\n", len);
|
||||
//front_end_status(s, T30_FRONT_END_RECEIVE_COMPLETE);
|
||||
break;
|
||||
case T38_FIELD_CI_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CI 0x%X\n", buf[0]);
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CI message - %d\n", len);
|
||||
//front_end_status(s, T30_FRONT_END_RECEIVE_COMPLETE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
return 0;
|
||||
case T38_DATA_V34_PRI_RATE:
|
||||
case T38_DATA_V34_CC_1200:
|
||||
case T38_DATA_V34_PRI_CH:
|
||||
case T38_DATA_V33_12000:
|
||||
case T38_DATA_V33_14400:
|
||||
switch (field_type)
|
||||
{
|
||||
case T38_FIELD_V34RATE:
|
||||
if (len >= 3)
|
||||
{
|
||||
/* Just get and store the rate. The front end has no real interest in the
|
||||
actual bit rate. */
|
||||
fe->t38.v34_rate = t38_v34rate_to_bps(buf, len);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "V.34 rate %d bps\n", fe->t38.v34_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for V34rate message - %d\n", len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/*endswitch*/
|
||||
switch (field_type)
|
||||
{
|
||||
case T38_FIELD_HDLC_DATA:
|
||||
@@ -316,8 +361,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
/* HDLC can just start without any signal indicator on some platforms, even when
|
||||
there is zero packet lost. Nasty, but true. Its a good idea to be tolerant of
|
||||
loss, though, so accepting a sudden start of HDLC data is the right thing to do. */
|
||||
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
|
||||
front_end_status(s, T30_FRONT_END_SIGNAL_PRESENT);
|
||||
fake_rx_indicator(t, s, T38_IND_V21_PREAMBLE);
|
||||
/* All real HDLC messages in the FAX world start with 0xFF. If this one is not starting
|
||||
with 0xFF it would appear some octets must have been missed before this one. */
|
||||
if (len <= 0 || buf[0] != 0xFF)
|
||||
@@ -386,7 +430,8 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
}
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->rx_data_missing = FALSE;
|
||||
fe->timeout_rx_samples = 0;
|
||||
/* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */
|
||||
fake_rx_indicator(t, s, T38_IND_NO_SIGNAL);
|
||||
break;
|
||||
case T38_FIELD_HDLC_FCS_BAD_SIG_END:
|
||||
if (len > 0)
|
||||
@@ -406,7 +451,8 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
}
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->rx_data_missing = FALSE;
|
||||
fe->timeout_rx_samples = 0;
|
||||
/* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */
|
||||
fake_rx_indicator(t, s, T38_IND_NO_SIGNAL);
|
||||
break;
|
||||
case T38_FIELD_HDLC_SIG_END:
|
||||
if (len > 0)
|
||||
@@ -428,9 +474,10 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->rx_data_missing = FALSE;
|
||||
fe->timeout_rx_samples = 0;
|
||||
front_end_status(s, T30_FRONT_END_RECEIVE_COMPLETE);
|
||||
}
|
||||
/* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */
|
||||
fake_rx_indicator(t, s, T38_IND_NO_SIGNAL);
|
||||
break;
|
||||
case T38_FIELD_T4_NON_ECM_DATA:
|
||||
if (!fe->rx_signal_present)
|
||||
@@ -468,40 +515,13 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
front_end_status(s, T30_FRONT_END_RECEIVE_COMPLETE);
|
||||
}
|
||||
fe->rx_signal_present = FALSE;
|
||||
fe->timeout_rx_samples = 0;
|
||||
break;
|
||||
case T38_FIELD_CM_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CM profile %d - %s\n", buf[0] - '0', t38_cm_profile_to_str(buf[0]));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CM message - %d\n", len);
|
||||
break;
|
||||
case T38_FIELD_JM_MESSAGE:
|
||||
if (len >= 2)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "JM - %s\n", t38_jm_to_str(buf, len));
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for JM message - %d\n", len);
|
||||
break;
|
||||
case T38_FIELD_CI_MESSAGE:
|
||||
if (len >= 1)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CI 0x%X\n", buf[0]);
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for CI message - %d\n", len);
|
||||
break;
|
||||
case T38_FIELD_V34RATE:
|
||||
if (len >= 3)
|
||||
{
|
||||
fe->t38.v34_rate = t38_v34rate_to_bps(buf, len);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "V.34 rate %d bps\n", fe->t38.v34_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for V34rate message - %d\n", len);
|
||||
}
|
||||
/* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */
|
||||
fake_rx_indicator(t, s, T38_IND_NO_SIGNAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+35
-23
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v17rx.c,v 1.153 2009/07/09 14:17:57 steveu Exp $
|
||||
* $Id: v17rx.c,v 1.153.4.4 2009/12/19 14:18:13 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -121,22 +121,28 @@ enum
|
||||
/* Coefficients for the band edge symbol timing synchroniser (alpha = 0.99) */
|
||||
/* low_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ - BAUD_RATE/2.0f)/SAMPLE_RATE; */
|
||||
/* high_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ + BAUD_RATE/2.0f)/SAMPLE_RATE; */
|
||||
#define SIN_LOW_BAND_EDGE 0.453990499f
|
||||
#define COS_LOW_BAND_EDGE 0.891006542f
|
||||
#define SIN_HIGH_BAND_EDGE 0.707106781f
|
||||
#define COS_HIGH_BAND_EDGE -0.707106781f
|
||||
#define ALPHA 0.99f
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR* 1.764193f)) /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*-1.400072f)) /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A ((int)(FP_FACTOR*-0.932131f)) /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B ((int)(FP_FACTOR* 0.700036f)) /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C ((int)(FP_FACTOR*-0.449451f)) /* -alpha*sin(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*(2.0f*ALPHA*COS_LOW_BAND_EDGE)))
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*(-ALPHA*ALPHA)))
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_2 ((int)(FP_FACTOR*(-ALPHA*SIN_LOW_BAND_EDGE)))
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*(2.0f*ALPHA*COS_HIGH_BAND_EDGE)))
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*(-ALPHA*ALPHA)))
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_2 ((int)(FP_FACTOR*(-ALPHA*SIN_HIGH_BAND_EDGE)))
|
||||
#define SYNC_MIXED_EDGES_COEFF_3 ((int)(FP_FACTOR*(-ALPHA*ALPHA*(SIN_HIGH_BAND_EDGE*COS_LOW_BAND_EDGE - SIN_LOW_BAND_EDGE*COS_HIGH_BAND_EDGE))))
|
||||
#else
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 1.764193f /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.400072f /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B 0.700036f /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C -0.449451f /* -alpha*sin(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 (2.0f*ALPHA*COS_LOW_BAND_EDGE)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 (-ALPHA*ALPHA)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_2 (-ALPHA*SIN_LOW_BAND_EDGE)
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 (2.0f*ALPHA*COS_HIGH_BAND_EDGE)
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 (-ALPHA*ALPHA)
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_2 (-ALPHA*SIN_HIGH_BAND_EDGE)
|
||||
#define SYNC_MIXED_EDGES_COEFF_3 (-ALPHA*ALPHA*(SIN_HIGH_BAND_EDGE*COS_LOW_BAND_EDGE - SIN_LOW_BAND_EDGE*COS_HIGH_BAND_EDGE))
|
||||
#endif
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
@@ -533,12 +539,18 @@ static __inline__ void symbol_sync(v17_rx_state_t *s)
|
||||
|
||||
/* This routine adapts the position of the half baud samples entering the equalizer. */
|
||||
|
||||
/* This symbol sync scheme is based on the technique first described by Dominique Godard in
|
||||
Passband Timing Recovery in an All-Digital Modem Receiver
|
||||
IEEE TRANSACTIONS ON COMMUNICATIONS, VOL. COM-26, NO. 5, MAY 1978 */
|
||||
|
||||
/* This is slightly rearranged for figure 3b of the Godard paper, as this saves a couple of
|
||||
maths operations */
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
/* TODO: The scalings used here need more thorough evaluation, to see if overflows are possible. */
|
||||
/* Cross correlate */
|
||||
v = (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_A
|
||||
+ (((s->symbol_sync_low[0] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_B
|
||||
+ (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[0] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_C;
|
||||
v = (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[0] >> 4)) >> 15)*SYNC_LOW_BAND_EDGE_COEFF_2
|
||||
- (((s->symbol_sync_low[0] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_HIGH_BAND_EDGE_COEFF_2
|
||||
+ (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_MIXED_EDGES_COEFF_3;
|
||||
/* Filter away any DC component */
|
||||
p = v - s->symbol_sync_dc_filter[1];
|
||||
s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0];
|
||||
@@ -548,9 +560,9 @@ static __inline__ void symbol_sync(v17_rx_state_t *s)
|
||||
if (abs(s->baud_phase) > 100*FP_FACTOR)
|
||||
{
|
||||
if (s->baud_phase > 0)
|
||||
i = (s->baud_phase > 1000*FP_FACTOR) ? 5 : 1;
|
||||
i = (s->baud_phase > 1000*FP_FACTOR) ? 15 : 1;
|
||||
else
|
||||
i = (s->baud_phase < -1000*FP_FACTOR) ? -5 : -1;
|
||||
i = (s->baud_phase < -1000*FP_FACTOR) ? -15 : -1;
|
||||
|
||||
//printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
|
||||
s->eq_put_step += i;
|
||||
@@ -558,9 +570,9 @@ static __inline__ void symbol_sync(v17_rx_state_t *s)
|
||||
}
|
||||
#else
|
||||
/* Cross correlate */
|
||||
v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A
|
||||
+ s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B
|
||||
+ s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_CROSS_CORR_COEFF_C;
|
||||
v = s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_LOW_BAND_EDGE_COEFF_2
|
||||
- s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_2
|
||||
+ s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_MIXED_EDGES_COEFF_3;
|
||||
|
||||
/* Filter away any DC component */
|
||||
p = v - s->symbol_sync_dc_filter[1];
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v18.c,v 1.10 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: v18.c,v 1.12 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -738,7 +738,7 @@ SPAN_DECLARE(logging_state_t *) v18_get_logging_state(v18_state_t *s)
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
||||
int caller,
|
||||
int calling_party,
|
||||
int mode,
|
||||
put_msg_func_t put_msg,
|
||||
void *user_data)
|
||||
@@ -749,7 +749,7 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->caller = caller;
|
||||
s->calling_party = calling_party;
|
||||
s->mode = mode;
|
||||
s->put_msg = put_msg;
|
||||
s->user_data = user_data;
|
||||
@@ -763,7 +763,7 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
||||
s->baudot_tx_shift = 2;
|
||||
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
|
||||
ride over the fraction. */
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_WEITBRECHT], 7, v18_tdd_put_async_byte, s);
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
|
||||
s->baudot_rx_shift = 0;
|
||||
break;
|
||||
case V18_MODE_5BIT_50:
|
||||
@@ -773,7 +773,7 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
||||
s->baudot_tx_shift = 2;
|
||||
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
|
||||
ride over the fraction. */
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_WEITBRECHT50], 7, v18_tdd_put_async_byte, s);
|
||||
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_WEITBRECHT50], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
|
||||
s->baudot_rx_shift = 0;
|
||||
break;
|
||||
case V18_MODE_DTMF:
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v22bis_rx.c,v 1.68 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: v22bis_rx.c,v 1.69 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -490,7 +490,7 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
|
||||
error could be higher. */
|
||||
s->rx.gardner_step = 4;
|
||||
s->rx.pattern_repeats = 0;
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
s->rx.training = V22BIS_RX_TRAINING_STAGE_UNSCRAMBLED_ONES;
|
||||
else
|
||||
s->rx.training = V22BIS_RX_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200;
|
||||
@@ -586,7 +586,7 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "+++ S1 detected (%d long)\n", s->rx.pattern_repeats);
|
||||
if (s->bit_rate == 2400)
|
||||
{
|
||||
if (!s->caller)
|
||||
if (!s->calling_party)
|
||||
{
|
||||
/* Accept establishment at 2400bps */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting U0011 (S1) (Answerer)\n");
|
||||
@@ -601,7 +601,7 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
|
||||
if (s->rx.training_count >= ms_to_symbols(270))
|
||||
{
|
||||
/* If we haven't seen the S1 signal by now, we are committed to be in 1200bps mode */
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "+++ Rx normal operation (1200)\n");
|
||||
/* The transmit side needs to sustain the scrambled ones for a timed period */
|
||||
@@ -625,7 +625,7 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
if (s->rx.training_count >= ms_to_symbols(100 + 450))
|
||||
{
|
||||
@@ -716,7 +716,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
|
||||
/* Calculate the I filter, with an arbitrary phase step, just so we can calculate
|
||||
the signal power of the required carrier, with any guard tone or spillback of our
|
||||
own transmitted signal suppressed. */
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
ii = rx_pulseshaper_2400_re[6][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
||||
@@ -769,7 +769,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
|
||||
if (step > PULSESHAPER_COEFF_SETS - 1)
|
||||
step = PULSESHAPER_COEFF_SETS - 1;
|
||||
s->rx.eq_put_step += PULSESHAPER_COEFF_SETS*40/(3*2);
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
ii = rx_pulseshaper_2400_re[step][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||
qq = rx_pulseshaper_2400_im[step][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||
@@ -836,7 +836,7 @@ int v22bis_rx_restart(v22bis_state_t *s)
|
||||
s->rx.training_count = 0;
|
||||
s->rx.signal_present = FALSE;
|
||||
|
||||
s->rx.carrier_phase_rate = dds_phase_ratef((s->caller) ? 2400.0f : 1200.0f);
|
||||
s->rx.carrier_phase_rate = dds_phase_ratef((s->calling_party) ? 2400.0f : 1200.0f);
|
||||
s->rx.carrier_phase = 0;
|
||||
power_meter_init(&(s->rx.rx_power), 5);
|
||||
v22bis_rx_signal_cutoff(s, -45.5f);
|
||||
@@ -855,7 +855,7 @@ int v22bis_rx_restart(v22bis_state_t *s)
|
||||
s->rx.training_error = 0.0f;
|
||||
s->rx.total_baud_timing_correction = 0;
|
||||
/* We want the carrier to pull in faster on the answerer side, as it has very little time to adapt. */
|
||||
s->rx.carrier_track_i = (s->caller) ? 8000.0f : 40000.0f;
|
||||
s->rx.carrier_track_i = (s->calling_party) ? 8000.0f : 40000.0f;
|
||||
s->rx.carrier_track_p = 8000000.0f;
|
||||
|
||||
s->negotiated_bit_rate = 1200;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v22bis_tx.c,v 1.63 2009/06/02 16:03:56 steveu Exp $
|
||||
* $Id: v22bis_tx.c,v 1.64 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -346,7 +346,7 @@ static complexf_t training_get(v22bis_state_t *s)
|
||||
if (++s->tx.training_count >= ms_to_symbols(100))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting S11 after U0011\n");
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
s->tx.training_count = 0;
|
||||
s->tx.training = V22BIS_TX_TRAINING_STAGE_S11;
|
||||
@@ -523,7 +523,7 @@ static int v22bis_tx_restart(v22bis_state_t *s)
|
||||
s->tx.rrc_filter_step = 0;
|
||||
s->tx.scramble_reg = 0;
|
||||
s->tx.scrambler_pattern_count = 0;
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
s->tx.training = V22BIS_TX_TRAINING_STAGE_INITIAL_SILENCE;
|
||||
else
|
||||
s->tx.training = V22BIS_TX_TRAINING_STAGE_INITIAL_TIMED_SILENCE;
|
||||
@@ -634,7 +634,7 @@ SPAN_DECLARE(int) v22bis_current_bit_rate(v22bis_state_t *s)
|
||||
SPAN_DECLARE(v22bis_state_t *) v22bis_init(v22bis_state_t *s,
|
||||
int bit_rate,
|
||||
int guard,
|
||||
int caller,
|
||||
int calling_party,
|
||||
get_bit_func_t get_bit,
|
||||
void *get_bit_user_data,
|
||||
put_bit_func_t put_bit,
|
||||
@@ -657,14 +657,14 @@ SPAN_DECLARE(v22bis_state_t *) v22bis_init(v22bis_state_t *s,
|
||||
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
||||
span_log_set_protocol(&s->logging, "V.22bis");
|
||||
s->bit_rate = bit_rate;
|
||||
s->caller = caller;
|
||||
s->calling_party = calling_party;
|
||||
|
||||
s->get_bit = get_bit;
|
||||
s->get_bit_user_data = get_bit_user_data;
|
||||
s->put_bit = put_bit;
|
||||
s->put_bit_user_data = put_bit_user_data;
|
||||
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
s->tx.carrier_phase_rate = dds_phase_ratef(1200.0f);
|
||||
}
|
||||
|
||||
+33
-21
@@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v29rx.c,v 1.167 2009/07/08 15:11:09 steveu Exp $
|
||||
* $Id: v29rx.c,v 1.167.4.4 2009/12/19 14:18:13 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -131,22 +131,28 @@ static const uint8_t space_map_9600[20][20] =
|
||||
/* Coefficients for the band edge symbol timing synchroniser (alpha = 0.99) */
|
||||
/* low_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ - BAUD_RATE/2.0f)/SAMPLE_RATE; */
|
||||
/* high_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ + BAUD_RATE/2.0f)/SAMPLE_RATE; */
|
||||
#define SIN_LOW_BAND_EDGE 0.382683432f
|
||||
#define COS_LOW_BAND_EDGE 0.923879533f
|
||||
#define SIN_HIGH_BAND_EDGE 0.760405966f
|
||||
#define COS_HIGH_BAND_EDGE -0.649448048f
|
||||
#define ALPHA 0.99f
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR* 1.829281f)) /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*-1.285907f)) /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A ((int)(FP_FACTOR*-0.932131f)) /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B ((int)(FP_FACTOR* 0.752802f)) /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C ((int)(FP_FACTOR*-0.378857f)) /* -alpha*sin(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*(2.0f*ALPHA*COS_LOW_BAND_EDGE)))
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*(-ALPHA*ALPHA)))
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_2 ((int)(FP_FACTOR*(-ALPHA*SIN_LOW_BAND_EDGE)))
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*(2.0f*ALPHA*COS_HIGH_BAND_EDGE)))
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*(-ALPHA*ALPHA)))
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_2 ((int)(FP_FACTOR*(-ALPHA*SIN_HIGH_BAND_EDGE)))
|
||||
#define SYNC_MIXED_EDGES_COEFF_3 ((int)(FP_FACTOR*(-ALPHA*ALPHA*(SIN_HIGH_BAND_EDGE*COS_LOW_BAND_EDGE - SIN_LOW_BAND_EDGE*COS_HIGH_BAND_EDGE))))
|
||||
#else
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 1.829281f /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.285907f /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B 0.752802f /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C -0.378857f /* -alpha*sin(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 (2.0f*ALPHA*COS_LOW_BAND_EDGE)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 (-ALPHA*ALPHA)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_2 (-ALPHA*SIN_LOW_BAND_EDGE)
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 (2.0f*ALPHA*COS_HIGH_BAND_EDGE)
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 (-ALPHA*ALPHA)
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_2 (-ALPHA*SIN_HIGH_BAND_EDGE)
|
||||
#define SYNC_MIXED_EDGES_COEFF_3 (-ALPHA*ALPHA*(SIN_HIGH_BAND_EDGE*COS_LOW_BAND_EDGE - SIN_LOW_BAND_EDGE*COS_HIGH_BAND_EDGE))
|
||||
#endif
|
||||
|
||||
SPAN_DECLARE(float) v29_rx_carrier_frequency(v29_rx_state_t *s)
|
||||
@@ -489,12 +495,18 @@ static __inline__ void symbol_sync(v29_rx_state_t *s)
|
||||
|
||||
/* This routine adapts the position of the half baud samples entering the equalizer. */
|
||||
|
||||
/* This symbol sync scheme is based on the technique first described by Dominique Godard in
|
||||
Passband Timing Recovery in an All-Digital Modem Receiver
|
||||
IEEE TRANSACTIONS ON COMMUNICATIONS, VOL. COM-26, NO. 5, MAY 1978 */
|
||||
|
||||
/* This is slightly rearranged for figure 3b of the Godard paper, as this saves a couple of
|
||||
maths operations */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
/* TODO: The scalings used here need more thorough evaluation, to see if overflows are possible. */
|
||||
/* Cross correlate */
|
||||
v = (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_A
|
||||
+ (((s->symbol_sync_low[0] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_B
|
||||
+ (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[0] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_C;
|
||||
v = (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[0] >> 4)) >> 15)*SYNC_LOW_BAND_EDGE_COEFF_2
|
||||
- (((s->symbol_sync_low[0] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_HIGH_BAND_EDGE_COEFF_2
|
||||
+ (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_MIXED_EDGES_COEFF_3;
|
||||
/* Filter away any DC component */
|
||||
p = v - s->symbol_sync_dc_filter[1];
|
||||
s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0];
|
||||
@@ -514,9 +526,9 @@ static __inline__ void symbol_sync(v29_rx_state_t *s)
|
||||
}
|
||||
#else
|
||||
/* Cross correlate */
|
||||
v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A
|
||||
+ s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B
|
||||
+ s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_CROSS_CORR_COEFF_C;
|
||||
v = s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_LOW_BAND_EDGE_COEFF_2
|
||||
- s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_2
|
||||
+ s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_MIXED_EDGES_COEFF_3;
|
||||
/* Filter away any DC component */
|
||||
p = v - s->symbol_sync_dc_filter[1];
|
||||
s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0];
|
||||
|
||||
+11
-11
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v42.c,v 1.50 2009/02/10 13:06:47 steveu Exp $
|
||||
* $Id: v42.c,v 1.51 2009/11/04 15:52:06 steveu Exp $
|
||||
*/
|
||||
|
||||
/* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. */
|
||||
@@ -1138,11 +1138,11 @@ static void negotiation_rx_bit(v42_state_t *s, int new_bit)
|
||||
break;
|
||||
/*endif*/
|
||||
s->rxstream &= 0x3FF;
|
||||
if (s->caller && s->rxstream == 0x145)
|
||||
if (s->calling_party && s->rxstream == 0x145)
|
||||
{
|
||||
s->rx_negotiation_step++;
|
||||
}
|
||||
else if (!s->caller && s->rxstream == 0x111)
|
||||
else if (!s->calling_party && s->rxstream == 0x111)
|
||||
{
|
||||
s->rx_negotiation_step++;
|
||||
}
|
||||
@@ -1174,15 +1174,15 @@ static void negotiation_rx_bit(v42_state_t *s, int new_bit)
|
||||
break;
|
||||
/*endif*/
|
||||
s->rxstream &= 0x3FF;
|
||||
if (s->caller && s->rxstream == 0x185)
|
||||
if (s->calling_party && s->rxstream == 0x185)
|
||||
{
|
||||
s->rx_negotiation_step++;
|
||||
}
|
||||
else if (s->caller && s->rxstream == 0x001)
|
||||
else if (s->calling_party && s->rxstream == 0x001)
|
||||
{
|
||||
s->rx_negotiation_step++;
|
||||
}
|
||||
else if (!s->caller && s->rxstream == 0x113)
|
||||
else if (!s->calling_party && s->rxstream == 0x113)
|
||||
{
|
||||
s->rx_negotiation_step++;
|
||||
}
|
||||
@@ -1206,7 +1206,7 @@ static void negotiation_rx_bit(v42_state_t *s, int new_bit)
|
||||
{
|
||||
/* HIT */
|
||||
s->rx_negotiation_step++;
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
if (s->t400_timer >= 0)
|
||||
{
|
||||
@@ -1252,7 +1252,7 @@ static int v42_support_negotiation_tx_bit(v42_state_t *s)
|
||||
{
|
||||
int bit;
|
||||
|
||||
if (s->caller)
|
||||
if (s->calling_party)
|
||||
{
|
||||
if (s->txbits <= 0)
|
||||
{
|
||||
@@ -1355,7 +1355,7 @@ SPAN_DECLARE(void) v42_restart(v42_state_t *s)
|
||||
{
|
||||
span_schedule_init(&s->lapm.sched);
|
||||
|
||||
s->lapm.we_are_originator = s->caller;
|
||||
s->lapm.we_are_originator = s->calling_party;
|
||||
lapm_restart(&s->lapm);
|
||||
if (s->detect)
|
||||
{
|
||||
@@ -1379,7 +1379,7 @@ fprintf(stderr, "Setting T400 i\n");
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(v42_state_t *) v42_init(v42_state_t *s, int caller, int detect, v42_frame_handler_t frame_handler, void *user_data)
|
||||
SPAN_DECLARE(v42_state_t *) v42_init(v42_state_t *s, int calling_party, int detect, v42_frame_handler_t frame_handler, void *user_data)
|
||||
{
|
||||
int alloced;
|
||||
|
||||
@@ -1394,7 +1394,7 @@ SPAN_DECLARE(v42_state_t *) v42_init(v42_state_t *s, int caller, int detect, v42
|
||||
alloced = TRUE;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->caller = caller;
|
||||
s->calling_party = calling_party;
|
||||
s->detect = detect;
|
||||
s->lapm.iframe_receive = frame_handler;
|
||||
s->lapm.iframe_receive_user_data = user_data;
|
||||
|
||||
+340
-194
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v8.c,v 1.39 2009/06/24 00:34:38 steveu Exp $
|
||||
* $Id: v8.c,v 1.42 2009/11/04 16:10:14 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "spandsp/logging.h"
|
||||
#include "spandsp/queue.h"
|
||||
#include "spandsp/async.h"
|
||||
#include "spandsp/vector_int.h"
|
||||
#include "spandsp/complex.h"
|
||||
#include "spandsp/dds.h"
|
||||
#include "spandsp/tone_detect.h"
|
||||
@@ -67,7 +68,6 @@
|
||||
enum
|
||||
{
|
||||
V8_WAIT_1S,
|
||||
V8_CI,
|
||||
V8_CI_ON,
|
||||
V8_CI_OFF,
|
||||
V8_HEARD_ANSAM,
|
||||
@@ -76,7 +76,6 @@ enum
|
||||
V8_CM_WAIT,
|
||||
|
||||
V8_SIGC,
|
||||
V8_WAIT_200MS,
|
||||
V8_JM_ON,
|
||||
V8_SIGA,
|
||||
|
||||
@@ -91,6 +90,23 @@ enum
|
||||
V8_SYNC_V92
|
||||
} v8_sync_types_e;
|
||||
|
||||
enum
|
||||
{
|
||||
V8_CALL_FUNCTION_TAG = 0x01,
|
||||
V8_MODULATION_TAG = 0x05,
|
||||
V8_PROTOCOLS_TAG = 0x0A,
|
||||
V8_PSTN_ACCESS_TAG = 0x0D,
|
||||
V8_NSF_TAG = 0x0F,
|
||||
V8_PCM_MODEM_AVAILABILITY_TAG = 0x07,
|
||||
V8_T66_TAG = 0x0E
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
V8_CI_SYNC_OCTET = 0x00,
|
||||
V8_CM_JM_SYNC_OCTET = 0xE0
|
||||
};
|
||||
|
||||
SPAN_DECLARE(const char *) v8_call_function_to_str(int call_function)
|
||||
{
|
||||
switch (call_function)
|
||||
@@ -172,12 +188,85 @@ SPAN_DECLARE(const char *) v8_protocol_to_str(int protocol)
|
||||
|
||||
SPAN_DECLARE(const char *) v8_pstn_access_to_str(int pstn_access)
|
||||
{
|
||||
switch (pstn_access)
|
||||
{
|
||||
case V8_PSTN_ACCESS_CALL_DCE_CELLULAR:
|
||||
return "Calling modem on cellular";
|
||||
case V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR:
|
||||
return "Answering modem on cellular";
|
||||
case V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR | V8_PSTN_ACCESS_CALL_DCE_CELLULAR:
|
||||
return "Answering and calling modems on cellular";
|
||||
case V8_PSTN_ACCESS_DCE_ON_DIGITAL:
|
||||
return "DCE on digital";
|
||||
case V8_PSTN_ACCESS_DCE_ON_DIGITAL | V8_PSTN_ACCESS_CALL_DCE_CELLULAR:
|
||||
return "DCE on digital, and calling modem on cellular";
|
||||
case V8_PSTN_ACCESS_DCE_ON_DIGITAL | V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR:
|
||||
return "DCE on digital, answering modem on cellular";
|
||||
case V8_PSTN_ACCESS_DCE_ON_DIGITAL | V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR | V8_PSTN_ACCESS_CALL_DCE_CELLULAR:
|
||||
return "DCE on digital, and answering and calling modems on cellular";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(const char *) v8_nsf_to_str(int nsf)
|
||||
{
|
||||
switch (nsf)
|
||||
{
|
||||
case 0:
|
||||
return "???";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(const char *) v8_pcm_modem_availability_to_str(int pcm_modem_availability)
|
||||
{
|
||||
switch (pcm_modem_availability)
|
||||
{
|
||||
case 0:
|
||||
return "PCM unavailable";
|
||||
case V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE:
|
||||
return "V.90/V.92 analogue available";
|
||||
case V8_PSTN_PCM_MODEM_V90_V92_DIGITAL:
|
||||
return "V.90/V.92 digital available";
|
||||
case V8_PSTN_PCM_MODEM_V90_V92_DIGITAL | V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE:
|
||||
return "V.90/V.92 digital/analogue available";
|
||||
case V8_PSTN_PCM_MODEM_V91:
|
||||
return "V.91 available";
|
||||
case V8_PSTN_PCM_MODEM_V91 | V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE:
|
||||
return "V.91 and V.90/V.92 analogue available";
|
||||
case V8_PSTN_PCM_MODEM_V91 | V8_PSTN_PCM_MODEM_V90_V92_DIGITAL:
|
||||
return "V.91 and V.90/V.92 digital available";
|
||||
case V8_PSTN_PCM_MODEM_V91 | V8_PSTN_PCM_MODEM_V90_V92_DIGITAL | V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE:
|
||||
return "V.91 and V.90/V.92 digital/analogue available";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(const char *) v8_t66_to_str(int t66)
|
||||
{
|
||||
/* T.66 doesn't really define any V.8 values. The bits are all reserved. */
|
||||
switch (t66)
|
||||
{
|
||||
case 0:
|
||||
return "???";
|
||||
case 1:
|
||||
return "Reserved TIA";
|
||||
case 2:
|
||||
return "Reserved";
|
||||
case 3:
|
||||
return "Reserved TIA + others";
|
||||
case 4:
|
||||
return "Reserved";
|
||||
case 5:
|
||||
return "Reserved TIA + others";
|
||||
case 6:
|
||||
return "Reserved";
|
||||
case 7:
|
||||
return "Reserved TIA + others";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -203,11 +292,8 @@ SPAN_DECLARE(void) v8_log_supported_modulations(v8_state_t *s, int modulation_sc
|
||||
|
||||
static const uint8_t *process_call_function(v8_state_t *s, const uint8_t *p)
|
||||
{
|
||||
int call_function;
|
||||
|
||||
call_function = (*p >> 5) & 0x07;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s\n", v8_call_function_to_str(call_function));
|
||||
s->call_function = call_function;
|
||||
s->result.call_function = (*p >> 5) & 0x07;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s\n", v8_call_function_to_str(s->result.call_function));
|
||||
return ++p;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -225,6 +311,7 @@ static const uint8_t *process_modulation_mode(v8_state_t *s, const uint8_t *p)
|
||||
if (*p & 0x20)
|
||||
far_end_modulations |= V8_MOD_V90;
|
||||
|
||||
/* Check for an extension octet */
|
||||
if ((*++p & 0x38) == 0x10)
|
||||
{
|
||||
if (*p & 0x80)
|
||||
@@ -238,6 +325,7 @@ static const uint8_t *process_modulation_mode(v8_state_t *s, const uint8_t *p)
|
||||
if (*p & 0x01)
|
||||
far_end_modulations |= V8_MOD_V32;
|
||||
|
||||
/* Check for an extension octet */
|
||||
if ((*++p & 0x38) == 0x10)
|
||||
{
|
||||
if (*p & 0x80)
|
||||
@@ -250,77 +338,59 @@ static const uint8_t *process_modulation_mode(v8_state_t *s, const uint8_t *p)
|
||||
far_end_modulations |= V8_MOD_V26BIS;
|
||||
if (*p & 0x01)
|
||||
far_end_modulations |= V8_MOD_V26TER;
|
||||
/* Skip any future extensions we do not understand */
|
||||
while ((*++p & 0x38) == 0x10)
|
||||
/* dummy loop */;
|
||||
}
|
||||
}
|
||||
s->far_end_modulations = far_end_modulations;
|
||||
v8_log_supported_modulations(s, s->far_end_modulations);
|
||||
s->result.far_end_modulations = far_end_modulations;
|
||||
v8_log_supported_modulations(s, s->result.far_end_modulations);
|
||||
return ++p;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static const uint8_t *process_protocols(v8_state_t *s, const uint8_t *p)
|
||||
{
|
||||
int protocol;
|
||||
|
||||
protocol = (*p >> 5) & 0x07;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s\n", v8_protocol_to_str(protocol));
|
||||
s->protocol = protocol;
|
||||
s->result.protocol = (*p >> 5) & 0x07;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW | SPAN_LOG_SUPPRESS_LABELLING, "%s\n", v8_protocol_to_str(s->result.protocol));
|
||||
return ++p;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static const uint8_t *process_pstn_access(v8_state_t *s, const uint8_t *p)
|
||||
{
|
||||
int pstn_access;
|
||||
|
||||
pstn_access = (*p >> 5) & 0x07;
|
||||
if (pstn_access & V8_PSTN_ACCESS_DCE_ON_DIGTIAL)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "DCE on digital network connection\n");
|
||||
else
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "DCE on analogue network connection\n");
|
||||
if (pstn_access & V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Answer DCE on cellular connection\n");
|
||||
if (pstn_access & V8_PSTN_ACCESS_CALL_DCE_CELLULAR)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Call DCE on cellular connection\n");
|
||||
s->result.pstn_access = (*p >> 5) & 0x07;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW | SPAN_LOG_SUPPRESS_LABELLING, "%s\n", v8_pstn_access_to_str(s->result.pstn_access));
|
||||
return ++p;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static const uint8_t *process_non_standard_facilities(v8_state_t *s, const uint8_t *p)
|
||||
{
|
||||
++p;
|
||||
p += *p;
|
||||
s->result.nsf = (*p >> 5) & 0x07;
|
||||
s->result.nsf_seen = TRUE;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW | SPAN_LOG_SUPPRESS_LABELLING, "%s\n", v8_nsf_to_str(s->result.nsf));
|
||||
return p;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static const uint8_t *process_pcm_modem_availability(v8_state_t *s, const uint8_t *p)
|
||||
{
|
||||
int pcm_availability;
|
||||
|
||||
pcm_availability = (*p >> 5) & 0x07;
|
||||
if (pcm_availability & V8_PSTN_PCM_MODEM_V91)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "V.91 available\n");
|
||||
if (pcm_availability & V8_PSTN_PCM_MODEM_V90_V92_DIGITAL)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "V.90 or V.92 digital modem available\n");
|
||||
if (pcm_availability & V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "V.90 or V.92 analogue modem available\n");
|
||||
s->result.pcm_modem_availability = (*p >> 5) & 0x07;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW | SPAN_LOG_SUPPRESS_LABELLING, "%s\n", v8_pcm_modem_availability_to_str(s->result.pcm_modem_availability));
|
||||
return ++p;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static const uint8_t *process_t66(v8_state_t *s, const uint8_t *p)
|
||||
{
|
||||
s->result.t66 = (*p >> 5) & 0x07;
|
||||
s->result.t66_seen = TRUE;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW | SPAN_LOG_SUPPRESS_LABELLING, "%s\n", v8_t66_to_str(s->result.t66));
|
||||
return ++p;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void ci_decode(v8_state_t *s)
|
||||
{
|
||||
if ((s->rx_data[0] & 0x1F) == 0x01)
|
||||
if ((s->rx_data[0] & 0x1F) == V8_CALL_FUNCTION_TAG)
|
||||
process_call_function(s, &s->rx_data[0]);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -333,57 +403,60 @@ static void cm_jm_decode(v8_state_t *s)
|
||||
return;
|
||||
|
||||
/* We must receive two consecutive identical CM or JM sequences to accept it. */
|
||||
if (s->cm_jm_count <= 0
|
||||
if (s->cm_jm_len <= 0
|
||||
||
|
||||
s->cm_jm_count != s->rx_data_ptr
|
||||
s->cm_jm_len != s->rx_data_ptr
|
||||
||
|
||||
memcmp(s->cm_jm_data, s->rx_data, s->rx_data_ptr))
|
||||
{
|
||||
/* Save the current CM or JM sequence */
|
||||
s->cm_jm_count = s->rx_data_ptr;
|
||||
s->cm_jm_len = s->rx_data_ptr;
|
||||
memcpy(s->cm_jm_data, s->rx_data, s->rx_data_ptr);
|
||||
return;
|
||||
}
|
||||
/* We have a pair of matching CMs or JMs */
|
||||
/* We have a matching pair of CMs or JMs, so we are happy this is correct. */
|
||||
s->got_cm_jm = TRUE;
|
||||
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Decoding\n");
|
||||
|
||||
/* Zero indicates the end */
|
||||
s->cm_jm_data[s->cm_jm_count] = 0;
|
||||
s->cm_jm_data[s->cm_jm_len] = 0;
|
||||
|
||||
s->far_end_modulations = 0;
|
||||
s->result.far_end_modulations = 0;
|
||||
p = s->cm_jm_data;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
switch (*p & 0x1F)
|
||||
{
|
||||
case 0x01:
|
||||
case V8_CALL_FUNCTION_TAG:
|
||||
p = process_call_function(s, p);
|
||||
break;
|
||||
case 0x05:
|
||||
case V8_MODULATION_TAG:
|
||||
p = process_modulation_mode(s, p);
|
||||
break;
|
||||
case 0x0A:
|
||||
case V8_PROTOCOLS_TAG:
|
||||
p = process_protocols(s, p);
|
||||
break;
|
||||
case 0x0D:
|
||||
case V8_PSTN_ACCESS_TAG:
|
||||
p = process_pstn_access(s, p);
|
||||
break;
|
||||
case 0x0F:
|
||||
case V8_NSF_TAG:
|
||||
p = process_non_standard_facilities(s, p);
|
||||
break;
|
||||
case 0x07:
|
||||
case V8_PCM_MODEM_AVAILABILITY_TAG:
|
||||
p = process_pcm_modem_availability(s, p);
|
||||
break;
|
||||
case 0x0E:
|
||||
case V8_T66_TAG:
|
||||
p = process_t66(s, p);
|
||||
break;
|
||||
default:
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
/* Skip any future extensions we do not understand */
|
||||
while ((*p & 0x38) == 0x10)
|
||||
p++;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -411,43 +484,60 @@ static void put_bit(void *user_data, int bit)
|
||||
}
|
||||
return;
|
||||
}
|
||||
//span_log(&s->logging, SPAN_LOG_FLOW, "Bit %d\n", bit);
|
||||
/* Wait until we sync. */
|
||||
s->bit_stream = (s->bit_stream >> 1) | (bit << 19);
|
||||
if (s->bit_stream == 0x803FF)
|
||||
new_preamble_type = V8_SYNC_CI;
|
||||
else if (s->bit_stream == 0xF03FF)
|
||||
new_preamble_type = V8_SYNC_CM_JM;
|
||||
else if (s->bit_stream == 0xAABFF)
|
||||
new_preamble_type = V8_SYNC_V92;
|
||||
else
|
||||
new_preamble_type = V8_SYNC_UNKNOWN;
|
||||
if (new_preamble_type)
|
||||
/* CI preamble is 10 ones then a framed 0x00
|
||||
CM/JM preamble is 10 ones then a framed 0x07
|
||||
V.92 preamble is 10 ones then a framed 0x55
|
||||
Should we look at all 10 ones? The first couple might be
|
||||
settling down. */
|
||||
/* The preamble + synchronisation bit sequence should be unique in
|
||||
any bit stream, so we can rely on seeing this at any time as being
|
||||
a real sync code. */
|
||||
switch (s->bit_stream)
|
||||
{
|
||||
case 0x803FF:
|
||||
new_preamble_type = V8_SYNC_CI;
|
||||
break;
|
||||
case 0xF03FF:
|
||||
new_preamble_type = V8_SYNC_CM_JM;
|
||||
break;
|
||||
case 0xAABFF:
|
||||
new_preamble_type = V8_SYNC_V92;
|
||||
break;
|
||||
default:
|
||||
new_preamble_type = V8_SYNC_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
if (new_preamble_type != V8_SYNC_UNKNOWN)
|
||||
{
|
||||
/* We have seen a fresh sync code */
|
||||
/* Debug */
|
||||
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
|
||||
{
|
||||
if (s->preamble_type == V8_SYNC_CI)
|
||||
if (s->preamble_type != V8_SYNC_UNKNOWN)
|
||||
{
|
||||
tag = "CI: ";
|
||||
switch (s->preamble_type)
|
||||
{
|
||||
case V8_SYNC_CI:
|
||||
tag = "CI: ";
|
||||
break;
|
||||
case V8_SYNC_CM_JM:
|
||||
tag = (s->calling_party) ? "JM: " : "CM: ";
|
||||
break;
|
||||
case V8_SYNC_V92:
|
||||
tag = "V92: ";
|
||||
break;
|
||||
default:
|
||||
tag = "??: ";
|
||||
break;
|
||||
}
|
||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, s->rx_data, s->rx_data_ptr);
|
||||
}
|
||||
else if (s->preamble_type == V8_SYNC_CM_JM)
|
||||
{
|
||||
if (s->caller)
|
||||
tag = "JM: ";
|
||||
else
|
||||
tag = "CM: ";
|
||||
}
|
||||
else if (s->preamble_type == V8_SYNC_V92)
|
||||
{
|
||||
tag = "V92: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
tag = "??: ";
|
||||
}
|
||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, s->rx_data, s->rx_data_ptr);
|
||||
}
|
||||
/* Decode previous sequence */
|
||||
/* If we were handling a valid sync code then we should process what has been
|
||||
received to date. */
|
||||
switch (s->preamble_type)
|
||||
{
|
||||
case V8_SYNC_CI:
|
||||
@@ -462,16 +552,16 @@ static void put_bit(void *user_data, int bit)
|
||||
s->rx_data_ptr = 0;
|
||||
}
|
||||
|
||||
/* Parse octets with 1 bit start, 1 bit stop */
|
||||
if (s->preamble_type)
|
||||
if (s->preamble_type != V8_SYNC_UNKNOWN)
|
||||
{
|
||||
/* Parse octets with 1 bit start, 1 bit stop */
|
||||
s->bit_cnt++;
|
||||
/* Start, stop? */
|
||||
if ((s->bit_stream & 0x80400) == 0x80000 && s->bit_cnt >= 10)
|
||||
{
|
||||
/* Store the available data */
|
||||
data = (uint8_t) ((s->bit_stream >> 11) & 0xFF);
|
||||
/* CJ detection */
|
||||
/* CJ (3 successive zero octets) detection */
|
||||
if (data == 0)
|
||||
{
|
||||
if (++s->zero_byte_count == 3)
|
||||
@@ -492,13 +582,14 @@ static void put_bit(void *user_data, int bit)
|
||||
|
||||
static void v8_decode_init(v8_state_t *s)
|
||||
{
|
||||
if (s->caller)
|
||||
fsk_rx_init(&s->v21rx, &preset_fsk_specs[FSK_V21CH2], FALSE, put_bit, s);
|
||||
else
|
||||
fsk_rx_init(&s->v21rx, &preset_fsk_specs[FSK_V21CH1], FALSE, put_bit, s);
|
||||
s->preamble_type = 0;
|
||||
fsk_rx_init(&s->v21rx,
|
||||
&preset_fsk_specs[(s->calling_party) ? FSK_V21CH2 : FSK_V21CH1],
|
||||
FSK_FRAME_MODE_ASYNC,
|
||||
put_bit,
|
||||
s);
|
||||
s->preamble_type = V8_SYNC_UNKNOWN;
|
||||
s->bit_stream = 0;
|
||||
s->cm_jm_count = 0;
|
||||
s->cm_jm_len = 0;
|
||||
s->got_cm_jm = FALSE;
|
||||
s->got_cj = FALSE;
|
||||
s->zero_byte_count = 0;
|
||||
@@ -513,11 +604,22 @@ static int get_bit(void *user_data)
|
||||
|
||||
s = user_data;
|
||||
if (queue_read(s->tx_queue, &bit, 1) <= 0)
|
||||
bit = 1;
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
return bit;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void v8_put_preamble(v8_state_t *s)
|
||||
{
|
||||
static const uint8_t preamble[10] =
|
||||
{
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
queue_write(s->tx_queue, preamble, 10);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void v8_put_byte(v8_state_t *s, int data)
|
||||
{
|
||||
int i;
|
||||
@@ -538,17 +640,12 @@ static void v8_put_byte(v8_state_t *s, int data)
|
||||
static void send_cm_jm(v8_state_t *s, int mod_mask)
|
||||
{
|
||||
int val;
|
||||
static const uint8_t preamble[20] =
|
||||
{
|
||||
/* 10 1's (0x3FF), then 10 bits of CM sync (0x00F) */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
/* Send a CM, or a JM as appropriate */
|
||||
queue_write(s->tx_queue, preamble, 20);
|
||||
|
||||
v8_put_preamble(s);
|
||||
v8_put_byte(s, V8_CM_JM_SYNC_OCTET);
|
||||
/* Data call */
|
||||
v8_put_byte(s, (V8_CALL_V_SERIES << 5) | 0x01);
|
||||
v8_put_byte(s, (V8_CALL_V_SERIES << 5) | V8_CALL_FUNCTION_TAG);
|
||||
|
||||
/* Supported modulations */
|
||||
val = 0x05;
|
||||
@@ -584,12 +681,12 @@ static void send_cm_jm(v8_state_t *s, int mod_mask)
|
||||
val |= 0x80;
|
||||
v8_put_byte(s, val);
|
||||
|
||||
v8_put_byte(s, (0 << 5) | 0x07);
|
||||
v8_put_byte(s, (0 << 5) | V8_PCM_MODEM_AVAILABILITY_TAG);
|
||||
|
||||
v8_put_byte(s, (V8_PROTOCOL_LAPM_V42 << 5) | 0x0A);
|
||||
v8_put_byte(s, (V8_PROTOCOL_LAPM_V42 << 5) | V8_PROTOCOLS_TAG);
|
||||
|
||||
/* No cellular right now */
|
||||
v8_put_byte(s, (0 << 5) | 0x0D);
|
||||
v8_put_byte(s, (0 << 5) | V8_PSTN_ACCESS_TAG);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@@ -615,75 +712,122 @@ SPAN_DECLARE_NONSTD(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len)
|
||||
|
||||
//span_log(&s->logging, SPAN_LOG_FLOW, "v8_tx state %d\n", s->state);
|
||||
len = 0;
|
||||
switch (s->state)
|
||||
if (s->modem_connect_tone_tx_on)
|
||||
{
|
||||
case V8_CI_ON:
|
||||
case V8_CM_ON:
|
||||
case V8_JM_ON:
|
||||
case V8_CJ_ON:
|
||||
len = fsk_tx(&s->v21tx, amp, max_len);
|
||||
break;
|
||||
case V8_CM_WAIT:
|
||||
/* Send the ANSam tone */
|
||||
len = modem_connect_tones_tx(&s->ansam_tx, amp, max_len);
|
||||
break;
|
||||
if (s->modem_connect_tone_tx_on > ms_to_samples(75))
|
||||
{
|
||||
/* Send the ANSam tone */
|
||||
len = modem_connect_tones_tx(&s->ansam_tx, amp, max_len);
|
||||
if (len < max_len)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "ANSam or ANSam/ ended\n");
|
||||
s->modem_connect_tone_tx_on = ms_to_samples(75);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (max_len > s->modem_connect_tone_tx_on)
|
||||
len = s->modem_connect_tone_tx_on;
|
||||
else
|
||||
len = max_len;
|
||||
vec_zeroi16(amp, len);
|
||||
s->modem_connect_tone_tx_on -= len;
|
||||
}
|
||||
}
|
||||
if (s->fsk_tx_on && len < max_len)
|
||||
{
|
||||
max_len -= len;
|
||||
len = fsk_tx(&s->v21tx, amp + len, max_len);
|
||||
if (len < max_len)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "FSK ends\n");
|
||||
s->fsk_tx_on = FALSE;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void v8_send_ci(v8_state_t *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Send 4 CI packets in a burst (the spec says at least 3) */
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
v8_put_preamble(s);
|
||||
v8_put_byte(s, V8_CI_SYNC_OCTET);
|
||||
v8_put_byte(s, (V8_CALL_V_SERIES << 5) | V8_CALL_FUNCTION_TAG);
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void handle_modem_connect_tone(v8_state_t *s, int tone)
|
||||
{
|
||||
s->result.modem_connect_tone_detected = tone;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "'%s' recognised\n", modem_connect_tone_to_str(tone));
|
||||
if (tone == MODEM_CONNECT_TONES_ANSAM
|
||||
||
|
||||
tone == MODEM_CONNECT_TONES_ANSAM_PR)
|
||||
{
|
||||
/* Set the Te interval. The spec. says 500ms is the minimum,
|
||||
but gives reasons why 1 second is a better value. */
|
||||
s->state = V8_HEARD_ANSAM;
|
||||
s->ci_timer = ms_to_samples(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we found a connect tone, and it isn't one of the modulated answer tones,
|
||||
indicating V.8 startup, we are not going to do V.8 processing. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-V.8 modem connect tone detected\n");
|
||||
s->state = V8_PARKED;
|
||||
if (s->result_handler)
|
||||
s->result_handler(s->result_handler_user_data, &s->result);
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
||||
{
|
||||
int i;
|
||||
int residual_samples;
|
||||
v8_result_t result;
|
||||
static const uint8_t preamble[20] =
|
||||
{
|
||||
/* 10 1's (0x3FF), then 10 bits of CI sync (0x001) */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
|
||||
};
|
||||
int tone;
|
||||
|
||||
//span_log(&s->logging, SPAN_LOG_FLOW, "v8_rx state %d\n", s->state);
|
||||
residual_samples = 0;
|
||||
switch (s->state)
|
||||
{
|
||||
case V8_WAIT_1S:
|
||||
residual_samples = modem_connect_tones_rx(&s->ansam_rx, amp, len);
|
||||
/* Wait 1 second before sending the first CI packet */
|
||||
if ((s->negotiation_timer -= len) > 0)
|
||||
break;
|
||||
s->state = V8_CI;
|
||||
s->ci_count = 0;
|
||||
modem_connect_tones_rx_init(&s->ansam_rx, MODEM_CONNECT_TONES_ANS_PR, NULL, NULL);
|
||||
fsk_tx_init(&s->v21tx, &preset_fsk_specs[FSK_V21CH1], get_bit, s);
|
||||
/* Fall through to the next state */
|
||||
case V8_CI:
|
||||
residual_samples = modem_connect_tones_rx(&s->ansam_rx, amp, len);
|
||||
/* Send 4 CI packets in a burst (the spec says at least 3) */
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
/* 10 1's (0x3FF), then CI sync (0x001) */
|
||||
queue_write(s->tx_queue, preamble, 20);
|
||||
v8_put_byte(s, (V8_CALL_V_SERIES << 5) | 0x01);
|
||||
}
|
||||
fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
|
||||
v8_send_ci(s);
|
||||
s->state = V8_CI_ON;
|
||||
s->fsk_tx_on = TRUE;
|
||||
break;
|
||||
case V8_CI_ON:
|
||||
residual_samples = modem_connect_tones_rx(&s->ansam_rx, amp, len);
|
||||
/* Check if an ANSam or ANSam/ tone has been detected */
|
||||
if ((tone = modem_connect_tones_rx_get(&s->ansam_rx)) != MODEM_CONNECT_TONES_NONE)
|
||||
{
|
||||
handle_modem_connect_tone(s, tone);
|
||||
break;
|
||||
}
|
||||
if (queue_empty(s->tx_queue))
|
||||
{
|
||||
s->state = V8_CI_OFF;
|
||||
s->ci_timer = ms_to_samples(500);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case V8_CI_OFF:
|
||||
residual_samples = modem_connect_tones_rx(&s->ansam_rx, amp, len);
|
||||
/* Check if an ANSam tone has been detected */
|
||||
if (modem_connect_tones_rx_get(&s->ansam_rx))
|
||||
/* Check if an ANSam or ANSam/ tone has been detected */
|
||||
if ((tone = modem_connect_tones_rx_get(&s->ansam_rx)) != MODEM_CONNECT_TONES_NONE)
|
||||
{
|
||||
/* Set the Te interval. The spec. says 500ms is the minimum,
|
||||
but gives reasons why 1 second is a better value. */
|
||||
s->ci_timer = ms_to_samples(1000);
|
||||
s->state = V8_HEARD_ANSAM;
|
||||
handle_modem_connect_tone(s, tone);
|
||||
break;
|
||||
}
|
||||
if ((s->ci_timer -= len) <= 0)
|
||||
@@ -691,6 +835,7 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
||||
if (++s->ci_count >= 10)
|
||||
{
|
||||
/* The spec says we should give up now. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Timeout waiting for modem connect tone\n");
|
||||
s->state = V8_PARKED;
|
||||
if (s->result_handler)
|
||||
s->result_handler(s->result_handler_user_data, NULL);
|
||||
@@ -698,46 +843,54 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
||||
else
|
||||
{
|
||||
/* Try again */
|
||||
s->state = V8_CI;
|
||||
fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
|
||||
v8_send_ci(s);
|
||||
s->state = V8_CI_ON;
|
||||
s->fsk_tx_on = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V8_HEARD_ANSAM:
|
||||
/* We have heard the ANSam signal, but we still need to wait for the
|
||||
/* We have heard the ANSam or ANSam/ signal, but we still need to wait for the
|
||||
end of the Te timeout period to comply with the spec. */
|
||||
if ((s->ci_timer -= len) <= 0)
|
||||
{
|
||||
v8_decode_init(s);
|
||||
s->state = V8_CM_ON;
|
||||
s->negotiation_timer = ms_to_samples(5000);
|
||||
send_cm_jm(s, s->available_modulations);
|
||||
fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
|
||||
send_cm_jm(s, s->local_end_modulations);
|
||||
s->state = V8_CM_ON;
|
||||
s->fsk_tx_on = TRUE;
|
||||
}
|
||||
break;
|
||||
case V8_CM_ON:
|
||||
residual_samples = fsk_rx(&s->v21rx, amp, len);
|
||||
if (s->got_cm_jm)
|
||||
{
|
||||
/* Now JM has been detected we send CJ and wait for 75 ms
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "JM recognised\n");
|
||||
/* Now JM has been detected, we send CJ and wait for 75 ms
|
||||
before finishing the V.8 analysis. */
|
||||
s->negotiated_modulation = select_modulation(s->far_end_modulations);
|
||||
s->result.negotiated_modulation = select_modulation(s->result.far_end_modulations);
|
||||
|
||||
queue_flush(s->tx_queue);
|
||||
for (i = 0; i < 9; i++)
|
||||
fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
|
||||
for (i = 0; i < 3; i++)
|
||||
v8_put_byte(s, 0);
|
||||
s->state = V8_CJ_ON;
|
||||
s->fsk_tx_on = TRUE;
|
||||
break;
|
||||
}
|
||||
if ((s->negotiation_timer -= len) <= 0)
|
||||
{
|
||||
/* Timeout */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Timeout waiting for JM\n");
|
||||
s->state = V8_PARKED;
|
||||
if (s->result_handler)
|
||||
s->result_handler(s->result_handler_user_data, NULL);
|
||||
}
|
||||
if (queue_empty(s->tx_queue))
|
||||
if (queue_contents(s->tx_queue) < 10)
|
||||
{
|
||||
/* Send CM again */
|
||||
send_cm_jm(s, s->available_modulations);
|
||||
send_cm_jm(s, s->local_end_modulations);
|
||||
}
|
||||
break;
|
||||
case V8_CJ_ON:
|
||||
@@ -752,49 +905,33 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
||||
if ((s->negotiation_timer -= len) <= 0)
|
||||
{
|
||||
/* The V.8 negotiation has succeeded. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Negotiation succeeded\n");
|
||||
s->state = V8_PARKED;
|
||||
if (s->result_handler)
|
||||
{
|
||||
result.call_function = s->call_function;
|
||||
result.available_modulations = s->far_end_modulations;
|
||||
result.negotiated_modulation = s->negotiated_modulation;
|
||||
result.protocol = s->protocol;
|
||||
result.pstn_access = s->pstn_access;
|
||||
result.nsf_seen = s->nsf_seen;
|
||||
result.pcm_modem_availability = s->pcm_modem_availability;
|
||||
result.t66_seen = s->t66_seen;
|
||||
s->result_handler(s->result_handler_user_data, &result);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V8_WAIT_200MS:
|
||||
if ((s->negotiation_timer -= len) <= 0)
|
||||
{
|
||||
/* Send the ANSam tone */
|
||||
modem_connect_tones_tx_init(&s->ansam_tx, MODEM_CONNECT_TONES_ANSAM_PR);
|
||||
|
||||
v8_decode_init(s);
|
||||
s->state = V8_CM_WAIT;
|
||||
s->negotiation_timer = ms_to_samples(5000);
|
||||
s->result_handler(s->result_handler_user_data, &s->result);
|
||||
}
|
||||
break;
|
||||
case V8_CM_WAIT:
|
||||
residual_samples = fsk_rx(&s->v21rx, amp, len);
|
||||
if (s->got_cm_jm)
|
||||
{
|
||||
/* Stop sending ANSam and send JM instead */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CM recognised\n");
|
||||
/* Stop sending ANSam or ANSam/ and send JM instead */
|
||||
fsk_tx_init(&s->v21tx, &preset_fsk_specs[FSK_V21CH2], get_bit, s);
|
||||
/* Set the timeout for JM */
|
||||
s->negotiation_timer = ms_to_samples(5000);
|
||||
s->state = V8_JM_ON;
|
||||
s->common_modulations = s->available_modulations & s->far_end_modulations;
|
||||
s->negotiated_modulation = select_modulation(s->common_modulations);
|
||||
s->common_modulations = s->local_end_modulations & s->result.far_end_modulations;
|
||||
s->result.negotiated_modulation = select_modulation(s->common_modulations);
|
||||
send_cm_jm(s, s->common_modulations);
|
||||
s->modem_connect_tone_tx_on = ms_to_samples(75);
|
||||
s->fsk_tx_on = TRUE;
|
||||
break;
|
||||
}
|
||||
if ((s->negotiation_timer -= len) <= 0)
|
||||
{
|
||||
/* Timeout */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Timeout waiting for CM\n");
|
||||
s->state = V8_PARKED;
|
||||
if (s->result_handler)
|
||||
s->result_handler(s->result_handler_user_data, NULL);
|
||||
@@ -804,7 +941,9 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
||||
residual_samples = fsk_rx(&s->v21rx, amp, len);
|
||||
if (s->got_cj)
|
||||
{
|
||||
/* Stop sending JM, and wait 75 ms */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "CJ recognised\n");
|
||||
/* Stop sending JM, flushing anything left in the buffer, and wait 75 ms */
|
||||
queue_flush(s->tx_queue);
|
||||
s->negotiation_timer = ms_to_samples(75);
|
||||
s->state = V8_SIGA;
|
||||
break;
|
||||
@@ -812,12 +951,13 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
||||
if ((s->negotiation_timer -= len) <= 0)
|
||||
{
|
||||
/* Timeout */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Timeout waiting for CJ\n");
|
||||
s->state = V8_PARKED;
|
||||
if (s->result_handler)
|
||||
s->result_handler(s->result_handler_user_data, NULL);
|
||||
break;
|
||||
}
|
||||
if (queue_empty(s->tx_queue))
|
||||
if (queue_contents(s->tx_queue) < 10)
|
||||
{
|
||||
/* Send JM */
|
||||
send_cm_jm(s, s->common_modulations);
|
||||
@@ -827,19 +967,10 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
||||
if ((s->negotiation_timer -= len) <= 0)
|
||||
{
|
||||
/* The V.8 negotiation has succeeded. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Negotiation succeeded\n");
|
||||
s->state = V8_PARKED;
|
||||
if (s->result_handler)
|
||||
{
|
||||
result.call_function = s->call_function;
|
||||
result.available_modulations = s->far_end_modulations;
|
||||
result.negotiated_modulation = s->negotiated_modulation;
|
||||
result.protocol = s->protocol;
|
||||
result.pstn_access = s->pstn_access;
|
||||
result.nsf_seen = s->nsf_seen;
|
||||
result.pcm_modem_availability = s->pcm_modem_availability;
|
||||
result.t66_seen = s->t66_seen;
|
||||
s->result_handler(s->result_handler_user_data, &result);
|
||||
}
|
||||
s->result_handler(s->result_handler_user_data, &s->result);
|
||||
}
|
||||
break;
|
||||
case V8_PARKED:
|
||||
@@ -857,7 +988,8 @@ SPAN_DECLARE(logging_state_t *) v8_get_logging_state(v8_state_t *s)
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(v8_state_t *) v8_init(v8_state_t *s,
|
||||
int caller,
|
||||
int calling_party,
|
||||
int use_ansam_pr,
|
||||
int available_modulations,
|
||||
v8_result_handler_t *result_handler,
|
||||
void *user_data)
|
||||
@@ -868,22 +1000,36 @@ SPAN_DECLARE(v8_state_t *) v8_init(v8_state_t *s,
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->caller = caller;
|
||||
s->available_modulations = available_modulations;
|
||||
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
||||
span_log_set_protocol(&s->logging, "V.8");
|
||||
s->local_end_modulations = available_modulations;
|
||||
s->result_handler = result_handler;
|
||||
s->result_handler_user_data = user_data;
|
||||
|
||||
s->ci_timer = 0;
|
||||
if (s->caller)
|
||||
if (calling_party)
|
||||
{
|
||||
s->calling_party = TRUE;
|
||||
s->state = V8_WAIT_1S;
|
||||
s->negotiation_timer = ms_to_samples(1000);
|
||||
s->ci_count = 0;
|
||||
modem_connect_tones_rx_init(&s->ansam_rx, MODEM_CONNECT_TONES_ANS_PR, NULL, NULL);
|
||||
fsk_tx_init(&s->v21tx, &preset_fsk_specs[FSK_V21CH1], get_bit, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->state = V8_WAIT_200MS;
|
||||
s->negotiation_timer = ms_to_samples(200);
|
||||
/* Send the ANSam or ANSam/ tone */
|
||||
s->calling_party = FALSE;
|
||||
modem_connect_tones_tx_init(&s->ansam_tx,
|
||||
(use_ansam_pr) ? MODEM_CONNECT_TONES_ANSAM_PR : MODEM_CONNECT_TONES_ANSAM);
|
||||
|
||||
v8_decode_init(s);
|
||||
s->state = V8_CM_WAIT;
|
||||
s->negotiation_timer = ms_to_samples(200 + 5000);
|
||||
s->modem_connect_tone_tx_on = ms_to_samples(75) + 1;
|
||||
}
|
||||
s->result.modem_connect_tone_detected = MODEM_CONNECT_TONES_NONE;
|
||||
|
||||
if ((s->tx_queue = queue_init(NULL, 1024, 0)) == NULL)
|
||||
return NULL;
|
||||
return s;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: at_interpreter_tests.c,v 1.23 2009/05/30 15:23:13 steveu Exp $
|
||||
* $Id: at_interpreter_tests.c,v 1.24 2009/10/09 14:53:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -234,6 +234,9 @@ static const struct command_response_s general_test_seq[] =
|
||||
{"AT+ETBM?\r", "\r\n+ETBM:0,0\r\n\r\nOK\r\n"},
|
||||
{"AT+EWIND=?\r", "\r\n+EWIND:(1-127),(1-127)\r\n\r\nOK\r\n"}, /* V.250 6.5.7 - Window size */
|
||||
{"AT+EWIND?\r", "\r\n+EWIND:0,0\r\n\r\nOK\r\n"},
|
||||
{"AT+F34=?\r", "\r\n+F34:(0-14),(0-14),(0-2),(0-14),(0-14)\r\n\r\nOK\r\n"},
|
||||
/* T.31 B.6.1 - Initial V.34 rate controls for FAX */
|
||||
{"AT+F34?\r", "\r\n+F34:0,0,0,0,0\r\n\r\nOK\r\n"},
|
||||
{"AT+FAR=?\r", "\r\n0,1\r\n\r\nOK\r\n"}, /* T.31 8.5.1 - Adaptive reception control */
|
||||
{"AT+FAR?\r", "\r\n0\r\n\r\nOK\r\n"},
|
||||
{"AT+FCL=?\r", "\r\n(0-255)\r\n\r\nOK\r\n"}, /* T.31 8.5.2 - Carrier loss timeout */
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax_decode.c,v 1.57 2009/09/15 14:01:53 steveu Exp $
|
||||
* $Id: fax_decode.c,v 1.58 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page fax_decode_page FAX decoder
|
||||
@@ -479,7 +479,7 @@ int main(int argc, char *argv[])
|
||||
span_log_set_protocol(&t30_dummy.logging, "T.30");
|
||||
|
||||
hdlc_rx_init(&hdlcrx, FALSE, TRUE, 5, hdlc_accept, NULL);
|
||||
fsk = fsk_rx_init(NULL, &preset_fsk_specs[FSK_V21CH2], TRUE, v21_put_bit, NULL);
|
||||
fsk = fsk_rx_init(NULL, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, v21_put_bit, NULL);
|
||||
v17 = v17_rx_init(NULL, 14400, v17_put_bit, NULL);
|
||||
v29 = v29_rx_init(NULL, 9600, v29_put_bit, NULL);
|
||||
//v29 = v29_rx_init(NULL, 7200, v29_put_bit, NULL);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax_tester.c,v 1.22 2009/02/12 12:38:39 steveu Exp $
|
||||
* $Id: fax_tester.c,v 1.23 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -496,7 +496,7 @@ void faxtester_set_rx_type(void *user_data, int type, int bit_rate, int short_tr
|
||||
case T30_MODEM_V21:
|
||||
if (s->flush_handler)
|
||||
s->flush_handler(s, s->flush_user_data, 3);
|
||||
fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data);
|
||||
fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data);
|
||||
fsk_rx_signal_cutoff(&t->v21_rx, -45.5);
|
||||
t->rx_handler = (span_rx_handler_t *) &fsk_rx;
|
||||
t->rx_user_data = &t->v21_rx;
|
||||
@@ -670,7 +670,7 @@ static void faxtester_fax_modems_init(fax_modems_state_t *s, int use_tep, void *
|
||||
|
||||
hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data);
|
||||
hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_underflow_handler, user_data);
|
||||
fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx);
|
||||
fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx);
|
||||
fsk_rx_signal_cutoff(&s->v21_rx, -45.5);
|
||||
fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx);
|
||||
fsk_tx_set_modem_status_handler(&s->v21_tx, modem_tx_status, user_data);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
#
|
||||
# spandsp fax tests
|
||||
#
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax_utils.c,v 1.3 2009/05/16 03:34:45 steveu Exp $
|
||||
* $Id: fax_utils.c,v 1.3.4.1 2009/12/19 09:47:57 steveu Exp $
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
@@ -95,8 +95,8 @@ void log_transfer_statistics(t30_state_t *s, const char *tag)
|
||||
printf("%s: ECM %s\n", tag, (t.error_correcting_mode) ? "on" : "off");
|
||||
printf("%s: tx pages %d, rx pages %d\n", tag, t.pages_tx, t.pages_rx);
|
||||
printf("%s: pages in the file %d\n", tag, t.pages_in_file);
|
||||
printf("%s: image size %d x %d\n", tag, t.width, t.length);
|
||||
printf("%s: image resolution %d x %d\n", tag, t.x_resolution, t.y_resolution);
|
||||
printf("%s: image size %d pels x %d pels\n", tag, t.width, t.length);
|
||||
printf("%s: image resolution %d pels/m x %d pels/m\n", tag, t.x_resolution, t.y_resolution);
|
||||
printf("%s: bad rows %d, longest bad row run %d\n", tag, t.bad_rows, t.longest_bad_row_run);
|
||||
printf("%s: bad ECM frames %d\n", tag, t.error_correcting_mode_retries);
|
||||
printf("%s: compression type %d\n", tag, t.encoding);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fsk_tests.c,v 1.58 2009/07/09 13:52:09 steveu Exp $
|
||||
* $Id: fsk_tests.c,v 1.59 2009/11/02 13:25:20 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page fsk_tests_page FSK modem tests
|
||||
@@ -283,7 +283,7 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, " Cannot open audio file '%s'\n", decode_test_file);
|
||||
exit(2);
|
||||
}
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, put_bit, NULL);
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, put_bit, NULL);
|
||||
fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx);
|
||||
test_bps = preset_fsk_specs[modem_under_test_1].baud_rate;
|
||||
|
||||
@@ -306,7 +306,7 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
{
|
||||
printf("Test cutoff level\n");
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, cutoff_test_put_bit, NULL);
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, cutoff_test_put_bit, NULL);
|
||||
fsk_rx_signal_cutoff(caller_rx, -30.0f);
|
||||
fsk_rx_set_modem_status_handler(caller_rx, cutoff_test_rx_status, (void *) &caller_rx);
|
||||
on_at = 0;
|
||||
@@ -370,14 +370,14 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
caller_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_1], (get_bit_func_t) bert_get_bit, &caller_bert);
|
||||
fsk_tx_set_modem_status_handler(caller_tx, tx_status, (void *) &caller_tx);
|
||||
answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, (put_bit_func_t) bert_put_bit, &answerer_bert);
|
||||
answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &answerer_bert);
|
||||
fsk_rx_set_modem_status_handler(answerer_rx, rx_status, (void *) &answerer_rx);
|
||||
}
|
||||
if (modem_under_test_2 >= 0)
|
||||
{
|
||||
answerer_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_2], (get_bit_func_t) bert_get_bit, &answerer_bert);
|
||||
fsk_tx_set_modem_status_handler(answerer_tx, tx_status, (void *) &answerer_tx);
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], TRUE, (put_bit_func_t) bert_put_bit, &caller_bert);
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &caller_bert);
|
||||
fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx);
|
||||
}
|
||||
test_bps = preset_fsk_specs[modem_under_test_1].baud_rate;
|
||||
@@ -477,14 +477,14 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
caller_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_1], (get_bit_func_t) bert_get_bit, &caller_bert);
|
||||
fsk_tx_set_modem_status_handler(caller_tx, tx_status, (void *) &caller_tx);
|
||||
answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, (put_bit_func_t) bert_put_bit, &answerer_bert);
|
||||
answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &answerer_bert);
|
||||
fsk_rx_set_modem_status_handler(answerer_rx, rx_status, (void *) &answerer_rx);
|
||||
}
|
||||
if (modem_under_test_2 >= 0)
|
||||
{
|
||||
answerer_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_2], (get_bit_func_t) bert_get_bit, &answerer_bert);
|
||||
fsk_tx_set_modem_status_handler(answerer_tx, tx_status, (void *) &answerer_tx);
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], TRUE, (put_bit_func_t) bert_put_bit, &caller_bert);
|
||||
caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &caller_bert);
|
||||
fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx);
|
||||
}
|
||||
noise_level++;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_gateway_tests.c,v 1.82 2009/05/30 15:23:14 steveu Exp $
|
||||
* $Id: t38_gateway_tests.c,v 1.82.4.1 2009/12/19 09:47:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -99,7 +99,7 @@ static int phase_b_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B", i);
|
||||
printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_rx_parameters(s, tag);
|
||||
return T30_ERR_OK;
|
||||
@@ -112,7 +112,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D", i);
|
||||
printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
@@ -128,7 +128,7 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E", i);
|
||||
printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_gateway_to_terminal_tests.c,v 1.66 2009/05/30 15:23:14 steveu Exp $
|
||||
* $Id: t38_gateway_to_terminal_tests.c,v 1.66.4.1 2009/12/19 09:47:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -94,7 +94,7 @@ static int phase_b_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B", i);
|
||||
printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_rx_parameters(s, tag);
|
||||
return T30_ERR_OK;
|
||||
@@ -107,7 +107,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D", i);
|
||||
printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
@@ -123,7 +123,7 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E", i);
|
||||
printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_non_ecm_buffer_tests.c,v 1.5 2009/04/25 14:17:47 steveu Exp $
|
||||
* $Id: t38_non_ecm_buffer_tests.c,v 1.5.4.1 2009/12/19 06:43:28 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -50,6 +50,88 @@ module, used for T.38 gateways.
|
||||
|
||||
#include "spandsp.h"
|
||||
|
||||
/* A pattern of widening gaps between ones, until at 11 apart an
|
||||
EOL should be registered */
|
||||
static const uint8_t spreader[] =
|
||||
{
|
||||
0x55,
|
||||
0x55,
|
||||
0x55,
|
||||
0x55,
|
||||
0x55,
|
||||
0x55,
|
||||
0x55,
|
||||
0x55, /* 1 apart */
|
||||
0x22, /* 2 and 3 apart */
|
||||
0x10, /* 4 apart */
|
||||
0x40, /* 5 apart */
|
||||
0x80, /* 6 apart */
|
||||
0x80, /* 7 apart */
|
||||
0x40, /* 8 apart */
|
||||
0x10, /* 9 apart */
|
||||
0x02, /* 10 apart */
|
||||
0x00,
|
||||
0x25 /* 11 apart */
|
||||
};
|
||||
|
||||
static int bit_no;
|
||||
|
||||
static int xxx(t38_non_ecm_buffer_state_t *s, logging_state_t *l, int log_bits, int n, int expected)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int bit;
|
||||
|
||||
t38_non_ecm_buffer_inject(s, &spreader[n], 1);
|
||||
if (expected >= 0)
|
||||
{
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) s);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", bit_no, bit);
|
||||
if (bit != expected)
|
||||
{
|
||||
printf("Tests failed - %d %d %d\n", bit_no, bit, expected);
|
||||
exit(2);
|
||||
}
|
||||
bit_no++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j = -1;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) s);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", bit_no, bit);
|
||||
if (j < 0)
|
||||
{
|
||||
if (bit == 1)
|
||||
j = 18*8 - 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
expected = (spreader[j >> 3] >> (7 - (j & 7))) & 1;
|
||||
if (bit != expected)
|
||||
{
|
||||
printf("Tests failed - %d %d %d\n", bit_no, bit, expected);
|
||||
exit(2);
|
||||
}
|
||||
j++;
|
||||
if (j >= 18*8)
|
||||
j = 0;
|
||||
}
|
||||
bit_no++;
|
||||
if (j == 17*8)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
t38_non_ecm_buffer_state_t buffer;
|
||||
@@ -60,65 +142,170 @@ int main(int argc, char *argv[])
|
||||
int log_bits;
|
||||
int i;
|
||||
|
||||
log_bits = FALSE;
|
||||
log_bits = (argc > 1);
|
||||
printf("T.38 non-ECM rate adapting buffer tests.\n");
|
||||
span_log_init(&logging, SPAN_LOG_FLOW, NULL);
|
||||
span_log_set_protocol(&logging, "Buffer");
|
||||
|
||||
printf("1 - Impose no minimum for the bits per row\n");
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 0);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(buf + 10, 0x55, 10);
|
||||
buf[25] = 0x80;
|
||||
memset(buf + 30, 0x55, 10);
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 50);
|
||||
t38_non_ecm_buffer_push(&buffer);
|
||||
n = 0;
|
||||
do
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
}
|
||||
while (bit >= 0);
|
||||
bit_no = 0;
|
||||
/* We should get ones until the buffers recognises an EOL */
|
||||
printf(" We should get ones here\n");
|
||||
for (i = 0; i < 17; i++)
|
||||
xxx(&buffer, &logging, log_bits, i, 1);
|
||||
printf(" We should change to zeros here\n");
|
||||
xxx(&buffer, &logging, log_bits, i, 0);
|
||||
for (i = 0; i < 17; i++)
|
||||
xxx(&buffer, &logging, log_bits, i, 0);
|
||||
printf(" We should get the first row here\n");
|
||||
xxx(&buffer, &logging, log_bits, i, -1);
|
||||
for (i = 0; i < 17; i++)
|
||||
xxx(&buffer, &logging, log_bits, i, 0);
|
||||
printf(" We should get the second row here\n");
|
||||
xxx(&buffer, &logging, log_bits, i, -1);
|
||||
for (i = 0; i < 17; i++)
|
||||
xxx(&buffer, &logging, log_bits, i, 0);
|
||||
printf(" We should get the third row here\n");
|
||||
xxx(&buffer, &logging, log_bits, i, -1);
|
||||
printf(" Done\n");
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
printf("2 - Impose no minimum for the bits per row, different alignment\n");
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 0);
|
||||
n = 0;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
/* The first one in this should be seen as the first EOL */
|
||||
memset(buf + 10, 0x55, 10);
|
||||
buf[25] = 0x40;
|
||||
/* EOL 2 */
|
||||
buf[25] = 0x20;
|
||||
/* EOL 3 */
|
||||
memset(buf + 30, 0x55, 10);
|
||||
/* EOL 4 */
|
||||
buf[45] = 0x10;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 50);
|
||||
t38_non_ecm_buffer_push(&buffer);
|
||||
n = 0;
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
printf("Rx bit %d - %d\n", n, bit);
|
||||
n++;
|
||||
if (bit == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
if (n != 337)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (n >= 18 && n <= 96)
|
||||
{
|
||||
if (bit == (n & 1))
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else if (n >= 178 && n <= 256)
|
||||
{
|
||||
if (bit == (n & 1))
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else if (n == 139 || n == 300)
|
||||
{
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit != 0)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (bit >= 0);
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
printf("3 - Demand a fairly high minimum for the bits per row\n");
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 400);
|
||||
n = 0;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
/* The first one in this should be seen as the first EOL */
|
||||
memset(buf + 10, 0x55, 10);
|
||||
buf[25] = 0x01;
|
||||
/* EOL 2 */
|
||||
buf[25] = 0x08;
|
||||
/* EOL 3 */
|
||||
memset(buf + 30, 0x55, 10);
|
||||
/* EOL 4 */
|
||||
buf[45] = 0x04;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 50);
|
||||
t38_non_ecm_buffer_push(&buffer);
|
||||
n = 0;
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
printf("Rx bit %d - %d\n", n, bit);
|
||||
n++;
|
||||
if (bit == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
if (n != 1273)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (n >= 18 && n <= 96)
|
||||
{
|
||||
if (bit == (n & 1))
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else if (n >= 834 && n <= 912)
|
||||
{
|
||||
if (bit == (n & 1))
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else if (n == 429 || n == 1238)
|
||||
{
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit != 0)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (bit >= 0);
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
printf("4 - Take some time to get to the first row of the image, output ahead\n");
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 400);
|
||||
n = 0;
|
||||
/* Get some initial bits from an empty buffer. These should be ones */
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
@@ -131,6 +318,7 @@ int main(int argc, char *argv[])
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Initial ones OK\n");
|
||||
/* Now put some zeros into the buffer, but no EOL. We should continue
|
||||
getting ones out. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
@@ -146,6 +334,7 @@ int main(int argc, char *argv[])
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Continuing initial ones OK\n");
|
||||
/* Now add a one, to make an EOL. We should see the zeros come out. */
|
||||
buf[0] = 0x01;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 1);
|
||||
@@ -160,8 +349,9 @@ int main(int argc, char *argv[])
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" First EOL caused zeros to output OK\n");
|
||||
/* Now add another line. We should see the first line come out. This means just the
|
||||
eighth bit from now will be a one. */
|
||||
23rd bit from now will be a one. */
|
||||
buf[0] = 0x00;
|
||||
buf[4] = 0x01;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 5);
|
||||
@@ -170,12 +360,343 @@ int main(int argc, char *argv[])
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (i != 7 && bit != 0)
|
||||
if ((i == 23 && bit == 0) || (i != 23 && bit != 0))
|
||||
{
|
||||
printf("Tests failed (%d)\n", i);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Second EOL caused the first row to output OK\n");
|
||||
/* Now inject an RTC - 6 EOLs */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
/* T.4 1D style */
|
||||
for (i = 10; i < 19; i += 3)
|
||||
{
|
||||
buf[i] = 0x00;
|
||||
buf[i + 1] = 0x10;
|
||||
buf[i + 2] = 0x01;
|
||||
}
|
||||
/* T.4 2D style */
|
||||
buf[25 + 0] = 0x00;
|
||||
buf[25 + 1] = 0x18;
|
||||
buf[25 + 2] = 0x00;
|
||||
buf[25 + 3] = 0xC0;
|
||||
buf[25 + 4] = 0x06;
|
||||
buf[25 + 5] = 0x00;
|
||||
buf[25 + 6] = 0x30;
|
||||
buf[25 + 7] = 0x01;
|
||||
buf[25 + 8] = 0x80;
|
||||
buf[25 + 9] = 0x0C;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 50);
|
||||
t38_non_ecm_buffer_push(&buffer);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (i == 7
|
||||
||
|
||||
i == 400 + 11 + 0*12
|
||||
||
|
||||
i == 400 + 11 + 1*12
|
||||
||
|
||||
i == 400 + 11 + 2*12
|
||||
||
|
||||
i == 400 + 11 + 3*12
|
||||
||
|
||||
i == 400 + 11 + 4*12
|
||||
||
|
||||
i == 400 + 11 + 5*12
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 0*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 0*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 1*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 1*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 2*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 2*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 3*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 3*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 4*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 4*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 5*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 5*13 + 1)
|
||||
{
|
||||
if (bit == 0)
|
||||
{
|
||||
printf("Tests failed (%d)\n", i);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit == 1)
|
||||
{
|
||||
printf("Tests failed (%d)\n", i);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(" RTC output OK\n");
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
printf("5 - Take some time to get to the first row of the image, output behind\n");
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 400);
|
||||
n = 0;
|
||||
/* Inject some ones. */
|
||||
memset(buf, 0xFF, 100);
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 100);
|
||||
/* Inject some zeros */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 100);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Initial ones OK\n");
|
||||
/* Now add a one, to make an EOL. We should see the zeros come out. */
|
||||
buf[0] = 0x01;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 1);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 0)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" First EOL caused zeros to output OK\n");
|
||||
/* Now add another line. We should see the first line come out. This means just the
|
||||
23rd bit from now will be a one. */
|
||||
buf[0] = 0x00;
|
||||
buf[4] = 0x01;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 5);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if ((i == 23 && bit == 0) || (i != 23 && bit != 0))
|
||||
{
|
||||
printf("Tests failed (%d)\n", i);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Second EOL caused the first row to output OK\n");
|
||||
/* Now inject an RTC - 6 EOLs */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
/* T.4 1D style */
|
||||
for (i = 10; i < 19; i += 3)
|
||||
{
|
||||
buf[i] = 0x00;
|
||||
buf[i + 1] = 0x10;
|
||||
buf[i + 2] = 0x01;
|
||||
}
|
||||
/* T.4 2D style */
|
||||
buf[25 + 0] = 0x00;
|
||||
buf[25 + 1] = 0x18;
|
||||
buf[25 + 2] = 0x00;
|
||||
buf[25 + 3] = 0xC0;
|
||||
buf[25 + 4] = 0x06;
|
||||
buf[25 + 5] = 0x00;
|
||||
buf[25 + 6] = 0x30;
|
||||
buf[25 + 7] = 0x01;
|
||||
buf[25 + 8] = 0x80;
|
||||
buf[25 + 9] = 0x0C;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 50);
|
||||
t38_non_ecm_buffer_push(&buffer);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (i == 7
|
||||
||
|
||||
i == 400 + 11 + 0*12
|
||||
||
|
||||
i == 400 + 11 + 1*12
|
||||
||
|
||||
i == 400 + 11 + 2*12
|
||||
||
|
||||
i == 400 + 11 + 3*12
|
||||
||
|
||||
i == 400 + 11 + 4*12
|
||||
||
|
||||
i == 400 + 11 + 5*12
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 0*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 0*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 1*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 1*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 2*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 2*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 3*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 3*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 4*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 4*13 + 1
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 5*13
|
||||
||
|
||||
i == 400 + 11 + 60 + 400 + 4 + 5*13 + 1)
|
||||
{
|
||||
if (bit == 0)
|
||||
{
|
||||
printf("Tests failed (%d)\n", i);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit == 1)
|
||||
{
|
||||
printf("Tests failed (%d)\n", i);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(" RTC output OK\n");
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
printf("6 - TCF without leading ones\n");
|
||||
t38_non_ecm_buffer_init(&buffer, FALSE, 400);
|
||||
n = 0;
|
||||
/* Get some initial bits from an empty buffer. These should be ones */
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Initial ones from an empty TCF buffer OK\n");
|
||||
/* Now send some TCF through, and see that it comes out */
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 500);
|
||||
t38_non_ecm_buffer_push(&buffer);
|
||||
for (i = 0; i < 500*8; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 0)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Passthrough of TCF OK\n");
|
||||
/* Check the right number of bits was buffered */
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
printf(" End of data seen OK\n");
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
printf("7 - TCF with leading ones\n");
|
||||
t38_non_ecm_buffer_init(&buffer, FALSE, 400);
|
||||
n = 0;
|
||||
/* Get some initial bits from an empty buffer. These should be ones */
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Initial ones from an empty TCF buffer OK\n");
|
||||
|
||||
/* Now send some initial ones, and see that we continue to get all ones
|
||||
as the stuffing. */
|
||||
memset(buf, 0xFF, 500);
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 500);
|
||||
for (i = 0; i < 500*8; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Sustaining ones OK\n");
|
||||
|
||||
/* Now send some initial ones, and some TCF through, and see that only
|
||||
the TCF comes out */
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
memset(buf, 0xFF, 100);
|
||||
/* End the ones mid byte */
|
||||
buf[100] = 0xF0;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 500);
|
||||
t38_non_ecm_buffer_push(&buffer);
|
||||
for (i = 0; i < 400*8; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if ((i < 4 && bit == 0) || (i >= 4 && bit != 0))
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
printf(" Passthrough of TCF OK\n");
|
||||
/* Check the right number of bits was buffered */
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
printf(" End of data seen OK\n");
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_terminal_tests.c,v 1.67 2009/04/25 14:34:45 steveu Exp $
|
||||
* $Id: t38_terminal_tests.c,v 1.67.4.1 2009/12/19 09:47:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -90,7 +90,7 @@ static int phase_b_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B", i);
|
||||
printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_rx_parameters(s, tag);
|
||||
return T30_ERR_OK;
|
||||
@@ -103,7 +103,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D", i);
|
||||
printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
@@ -119,7 +119,7 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E", i);
|
||||
printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_terminal_to_gateway_tests.c,v 1.65 2009/05/30 15:23:14 steveu Exp $
|
||||
* $Id: t38_terminal_to_gateway_tests.c,v 1.65.4.1 2009/12/19 09:47:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -94,7 +94,7 @@ static int phase_b_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase B", i);
|
||||
printf("%c: Phase B handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_rx_parameters(s, tag);
|
||||
return T30_ERR_OK;
|
||||
@@ -107,7 +107,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase D", i);
|
||||
printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
@@ -123,7 +123,7 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
|
||||
char tag[20];
|
||||
|
||||
i = (int) (intptr_t) user_data;
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E:", i);
|
||||
snprintf(tag, sizeof(tag), "%c: Phase E", i);
|
||||
printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
|
||||
log_transfer_statistics(s, tag);
|
||||
log_tx_parameters(s, tag);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t4_tests.c,v 1.69 2009/05/16 03:34:45 steveu Exp $
|
||||
* $Id: t4_tests.c,v 1.69.4.1 2009/12/19 09:47:57 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -129,8 +129,8 @@ static void display_page_stats(t4_state_t *s)
|
||||
|
||||
t4_get_transfer_statistics(s, &stats);
|
||||
printf("Pages = %d\n", stats.pages_transferred);
|
||||
printf("Image size = %d x %d pixels\n", stats.width, stats.length);
|
||||
printf("Image resolution = %d/m x %d/m\n", stats.x_resolution, stats.y_resolution);
|
||||
printf("Image size = %d pels x %d pels\n", stats.width, stats.length);
|
||||
printf("Image resolution = %d pels/m x %d pels/m\n", stats.x_resolution, stats.y_resolution);
|
||||
printf("Bad rows = %d\n", stats.bad_rows);
|
||||
printf("Longest bad row run = %d\n", stats.longest_bad_row_run);
|
||||
printf("Bits per row - min %d, max %d\n", s->min_row_bits, s->max_row_bits);
|
||||
@@ -144,6 +144,7 @@ static int row_read_handler(void *user_data, uint8_t buf[], size_t len)
|
||||
const char *s;
|
||||
static int row = 0;
|
||||
|
||||
/* Send the test pattern. */
|
||||
s = t4_test_patterns[row++];
|
||||
if (row >= 16)
|
||||
return 0;
|
||||
@@ -170,6 +171,7 @@ static int row_write_handler(void *user_data, const uint8_t buf[], size_t len)
|
||||
static int row = 0;
|
||||
uint8_t ref[8192];
|
||||
|
||||
/* Verify that what is received matches the test pattern. */
|
||||
if (len == 0)
|
||||
return 0;
|
||||
s = t4_test_patterns[row++];
|
||||
@@ -280,9 +282,15 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
static const int compression_sequence[] =
|
||||
{
|
||||
//T4_COMPRESSION_NONE,
|
||||
T4_COMPRESSION_ITU_T4_1D,
|
||||
T4_COMPRESSION_ITU_T4_2D,
|
||||
T4_COMPRESSION_ITU_T6
|
||||
T4_COMPRESSION_ITU_T6,
|
||||
//T4_COMPRESSION_ITU_T85,
|
||||
//T4_COMPRESSION_ITU_T43,
|
||||
//T4_COMPRESSION_ITU_T45,
|
||||
//T4_COMPRESSION_ITU_T81,
|
||||
//T4_COMPRESSION_ITU_SYCC_T81
|
||||
};
|
||||
int sends;
|
||||
int page_no;
|
||||
@@ -486,11 +494,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
span_log_set_level(&receive_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
|
||||
t4_rx_set_row_write_handler(&receive_state, row_write_handler, NULL);
|
||||
t4_rx_set_image_width(&receive_state, t4_tx_get_image_width(&send_state));
|
||||
t4_rx_set_x_resolution(&receive_state, t4_tx_get_x_resolution(&send_state));
|
||||
t4_rx_set_y_resolution(&receive_state, t4_tx_get_y_resolution(&send_state));
|
||||
t4_rx_set_image_width(&receive_state, t4_tx_get_image_width(&send_state));
|
||||
|
||||
/* Now send and receive all the pages in the source TIFF file */
|
||||
/* Now send and receive the test data with all compression modes. */
|
||||
page_no = 1;
|
||||
/* If we are stepping around the compression schemes, reset to the start of the sequence. */
|
||||
if (compression_step > 0)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
#
|
||||
# spandsp fax tests
|
||||
#
|
||||
|
||||
+303
-66
@@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v8_tests.c,v 1.33 2009/05/30 15:23:14 steveu Exp $
|
||||
* $Id: v8_tests.c,v 1.36 2009/11/04 16:10:14 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page v8_tests_page V.8 tests
|
||||
@@ -70,30 +70,303 @@ static void handler(void *user_data, v8_result_t *result)
|
||||
printf("%s V.8 negotiation failed\n", s);
|
||||
return;
|
||||
}
|
||||
printf("%s V.8 negotiation result:\n", s);
|
||||
printf(" Call function '%s'\n", v8_call_function_to_str(result->call_function));
|
||||
printf(" Negotiated modulation '%s'\n", v8_modulation_to_str(result->negotiated_modulation));
|
||||
printf(" Protocol '%s'\n", v8_protocol_to_str(result->protocol));
|
||||
printf(" PSTN access '%s'\n", v8_pstn_access_to_str(result->pstn_access));
|
||||
printf(" PCM modem availability '%s'\n", v8_pcm_modem_availability_to_str(result->pcm_modem_availability));
|
||||
if (result->call_function == V8_CALL_V_SERIES
|
||||
&&
|
||||
result->negotiated_modulation == V8_MOD_V90
|
||||
&&
|
||||
result->protocol == V8_PROTOCOL_LAPM_V42)
|
||||
if (result->modem_connect_tone_detected == MODEM_CONNECT_TONES_ANSAM
|
||||
||
|
||||
result->modem_connect_tone_detected == MODEM_CONNECT_TONES_ANSAM_PR
|
||||
||
|
||||
result->modem_connect_tone_detected == MODEM_CONNECT_TONES_NONE)
|
||||
{
|
||||
negotiations_ok++;
|
||||
printf("%s V.8 negotiation result:\n", s);
|
||||
printf(" Modem connect tone '%s'\n", modem_connect_tone_to_str(result->modem_connect_tone_detected));
|
||||
printf(" Call function '%s'\n", v8_call_function_to_str(result->call_function));
|
||||
printf(" Negotiated modulation '%s'\n", v8_modulation_to_str(result->negotiated_modulation));
|
||||
printf(" Protocol '%s'\n", v8_protocol_to_str(result->protocol));
|
||||
printf(" PSTN access '%s'\n", v8_pstn_access_to_str(result->pstn_access));
|
||||
printf(" NSF %d %d\n", result->nsf_seen, result->nsf);
|
||||
printf(" PCM modem availability '%s'\n", v8_pcm_modem_availability_to_str(result->pcm_modem_availability));
|
||||
printf(" T.66 %d %d\n", result->t66_seen, result->t66);
|
||||
if (result->call_function == V8_CALL_V_SERIES
|
||||
&&
|
||||
result->negotiated_modulation == V8_MOD_V90
|
||||
&&
|
||||
result->protocol == V8_PROTOCOL_LAPM_V42)
|
||||
{
|
||||
negotiations_ok++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s V.8 negotiation result:\n", s);
|
||||
printf(" Modem connect tone '%s'\n", modem_connect_tone_to_str(result->modem_connect_tone_detected));
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int v8_calls_v8_tests(SNDFILE *outhandle)
|
||||
{
|
||||
v8_state_t *v8_caller;
|
||||
v8_state_t *v8_answerer;
|
||||
logging_state_t *caller_logging;
|
||||
logging_state_t *answerer_logging;
|
||||
int caller_available_modulations;
|
||||
int answerer_available_modulations;
|
||||
int i;
|
||||
int samples;
|
||||
int remnant;
|
||||
int outframes;
|
||||
int16_t amp[SAMPLES_PER_CHUNK];
|
||||
int16_t out_amp[2*SAMPLES_PER_CHUNK];
|
||||
|
||||
caller_available_modulations = V8_MOD_V17
|
||||
| V8_MOD_V21
|
||||
| V8_MOD_V22
|
||||
| V8_MOD_V23HALF
|
||||
| V8_MOD_V23
|
||||
| V8_MOD_V26BIS
|
||||
| V8_MOD_V26TER
|
||||
| V8_MOD_V27TER
|
||||
| V8_MOD_V29
|
||||
| V8_MOD_V32
|
||||
| V8_MOD_V34HALF
|
||||
| V8_MOD_V34
|
||||
| V8_MOD_V90
|
||||
| V8_MOD_V92;
|
||||
answerer_available_modulations = V8_MOD_V17
|
||||
| V8_MOD_V21
|
||||
| V8_MOD_V22
|
||||
| V8_MOD_V23HALF
|
||||
| V8_MOD_V23
|
||||
| V8_MOD_V26BIS
|
||||
| V8_MOD_V26TER
|
||||
| V8_MOD_V27TER
|
||||
| V8_MOD_V29
|
||||
| V8_MOD_V32
|
||||
| V8_MOD_V34HALF
|
||||
| V8_MOD_V34
|
||||
| V8_MOD_V90
|
||||
| V8_MOD_V92;
|
||||
negotiations_ok = 0;
|
||||
|
||||
v8_caller = v8_init(NULL, TRUE, TRUE, caller_available_modulations, handler, (void *) "caller");
|
||||
v8_answerer = v8_init(NULL, FALSE, TRUE, answerer_available_modulations, handler, (void *) "answerer");
|
||||
caller_logging = v8_get_logging_state(v8_caller);
|
||||
span_log_set_level(caller_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
|
||||
span_log_set_tag(caller_logging, "caller");
|
||||
answerer_logging = v8_get_logging_state(v8_answerer);
|
||||
span_log_set_level(answerer_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
|
||||
span_log_set_tag(answerer_logging, "answerer");
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
samples = v8_tx(v8_caller, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
span_log_bump_samples(caller_logging, samples);
|
||||
remnant = v8_rx(v8_answerer, amp, samples);
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i] = amp[i];
|
||||
|
||||
samples = v8_tx(v8_answerer, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
span_log_bump_samples(answerer_logging, samples);
|
||||
if (v8_rx(v8_caller, amp, samples) && remnant)
|
||||
break;
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i + 1] = amp[i];
|
||||
|
||||
outframes = sf_writef_short(outhandle, out_amp, samples);
|
||||
if (outframes != samples)
|
||||
{
|
||||
fprintf(stderr, " Error writing audio file\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
v8_free(v8_caller);
|
||||
v8_free(v8_answerer);
|
||||
|
||||
if (negotiations_ok != 2)
|
||||
{
|
||||
printf("Tests failed.\n");
|
||||
exit(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int non_v8_calls_v8_tests(SNDFILE *outhandle)
|
||||
{
|
||||
silence_gen_state_t *non_v8_caller_tx;
|
||||
modem_connect_tones_rx_state_t *non_v8_caller_rx;
|
||||
v8_state_t *v8_answerer;
|
||||
logging_state_t *answerer_logging;
|
||||
int answerer_available_modulations;
|
||||
int i;
|
||||
int samples;
|
||||
int remnant;
|
||||
int outframes;
|
||||
int tone;
|
||||
int16_t amp[SAMPLES_PER_CHUNK];
|
||||
int16_t out_amp[2*SAMPLES_PER_CHUNK];
|
||||
|
||||
answerer_available_modulations = V8_MOD_V17
|
||||
| V8_MOD_V21
|
||||
| V8_MOD_V22
|
||||
| V8_MOD_V23HALF
|
||||
| V8_MOD_V23
|
||||
| V8_MOD_V26BIS
|
||||
| V8_MOD_V26TER
|
||||
| V8_MOD_V27TER
|
||||
| V8_MOD_V29
|
||||
| V8_MOD_V32
|
||||
| V8_MOD_V34HALF
|
||||
| V8_MOD_V34
|
||||
| V8_MOD_V90
|
||||
| V8_MOD_V92;
|
||||
negotiations_ok = 0;
|
||||
|
||||
non_v8_caller_tx = silence_gen_init(NULL, 10*SAMPLE_RATE);
|
||||
non_v8_caller_rx = modem_connect_tones_rx_init(NULL, MODEM_CONNECT_TONES_ANS_PR, NULL, NULL);
|
||||
v8_answerer = v8_init(NULL, FALSE, TRUE, answerer_available_modulations, handler, (void *) "answerer");
|
||||
answerer_logging = v8_get_logging_state(v8_answerer);
|
||||
span_log_set_level(answerer_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
|
||||
span_log_set_tag(answerer_logging, "answerer");
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
samples = silence_gen(non_v8_caller_tx, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
remnant = v8_rx(v8_answerer, amp, samples);
|
||||
if (remnant)
|
||||
break;
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i] = amp[i];
|
||||
|
||||
samples = v8_tx(v8_answerer, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
span_log_bump_samples(answerer_logging, samples);
|
||||
modem_connect_tones_rx(non_v8_caller_rx, amp, samples);
|
||||
if ((tone = modem_connect_tones_rx_get(non_v8_caller_rx)) != MODEM_CONNECT_TONES_NONE)
|
||||
{
|
||||
printf("Detected %s (%d)\n", modem_connect_tone_to_str(tone), tone);
|
||||
if (tone == MODEM_CONNECT_TONES_ANSAM_PR)
|
||||
negotiations_ok++;
|
||||
}
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i + 1] = amp[i];
|
||||
|
||||
outframes = sf_writef_short(outhandle, out_amp, samples);
|
||||
if (outframes != samples)
|
||||
{
|
||||
fprintf(stderr, " Error writing audio file\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
silence_gen_free(non_v8_caller_tx);
|
||||
modem_connect_tones_rx_free(non_v8_caller_rx);
|
||||
v8_free(v8_answerer);
|
||||
|
||||
if (negotiations_ok != 1)
|
||||
{
|
||||
printf("Tests failed.\n");
|
||||
exit(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int v8_calls_non_v8_tests(SNDFILE *outhandle)
|
||||
{
|
||||
v8_state_t *v8_caller;
|
||||
modem_connect_tones_tx_state_t *non_v8_answerer_tx;
|
||||
logging_state_t *caller_logging;
|
||||
int caller_available_modulations;
|
||||
int i;
|
||||
int samples;
|
||||
int outframes;
|
||||
int16_t amp[SAMPLES_PER_CHUNK];
|
||||
int16_t out_amp[2*SAMPLES_PER_CHUNK];
|
||||
|
||||
caller_available_modulations = V8_MOD_V17
|
||||
| V8_MOD_V21
|
||||
| V8_MOD_V22
|
||||
| V8_MOD_V23HALF
|
||||
| V8_MOD_V23
|
||||
| V8_MOD_V26BIS
|
||||
| V8_MOD_V26TER
|
||||
| V8_MOD_V27TER
|
||||
| V8_MOD_V29
|
||||
| V8_MOD_V32
|
||||
| V8_MOD_V34HALF
|
||||
| V8_MOD_V34
|
||||
| V8_MOD_V90
|
||||
| V8_MOD_V92;
|
||||
negotiations_ok = 0;
|
||||
|
||||
v8_caller = v8_init(NULL, TRUE, TRUE, caller_available_modulations, handler, (void *) "caller");
|
||||
non_v8_answerer_tx = modem_connect_tones_tx_init(NULL, MODEM_CONNECT_TONES_ANS_PR);
|
||||
caller_logging = v8_get_logging_state(v8_caller);
|
||||
span_log_set_level(caller_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
|
||||
span_log_set_tag(caller_logging, "caller");
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
samples = v8_tx(v8_caller, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
span_log_bump_samples(caller_logging, samples);
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i] = amp[i];
|
||||
|
||||
samples = modem_connect_tones_tx(non_v8_answerer_tx, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
if (v8_rx(v8_caller, amp, samples))
|
||||
break;
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i + 1] = amp[i];
|
||||
|
||||
outframes = sf_writef_short(outhandle, out_amp, samples);
|
||||
if (outframes != samples)
|
||||
{
|
||||
fprintf(stderr, " Error writing audio file\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
v8_free(v8_caller);
|
||||
modem_connect_tones_tx_free(non_v8_answerer_tx);
|
||||
|
||||
#if 0
|
||||
if (negotiations_ok != 1)
|
||||
{
|
||||
printf("Tests failed.\n");
|
||||
exit(2);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
int16_t amp[SAMPLES_PER_CHUNK];
|
||||
int16_t out_amp[2*SAMPLES_PER_CHUNK];
|
||||
v8_state_t *v8_caller;
|
||||
v8_state_t *v8_answerer;
|
||||
int outframes;
|
||||
int samples;
|
||||
int remnant;
|
||||
int caller_available_modulations;
|
||||
@@ -102,6 +375,7 @@ int main(int argc, char *argv[])
|
||||
SNDFILE *outhandle;
|
||||
int opt;
|
||||
char *decode_test_file;
|
||||
v8_state_t *v8_answerer;
|
||||
logging_state_t *logging;
|
||||
|
||||
decode_test_file = NULL;
|
||||
@@ -155,65 +429,28 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
v8_caller = v8_init(NULL, TRUE, caller_available_modulations, handler, (void *) "caller");
|
||||
v8_answerer = v8_init(NULL, FALSE, answerer_available_modulations, handler, (void *) "answerer");
|
||||
logging = v8_get_logging_state(v8_caller);
|
||||
span_log_set_level(logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG);
|
||||
span_log_set_tag(logging, "caller");
|
||||
logging = v8_get_logging_state(v8_answerer);
|
||||
span_log_set_level(logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG);
|
||||
span_log_set_tag(logging, "answerer");
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
samples = v8_tx(v8_caller, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
remnant = v8_rx(v8_answerer, amp, samples);
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i] = amp[i];
|
||||
|
||||
samples = v8_tx(v8_answerer, amp, SAMPLES_PER_CHUNK);
|
||||
if (samples < SAMPLES_PER_CHUNK)
|
||||
{
|
||||
memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
|
||||
samples = SAMPLES_PER_CHUNK;
|
||||
}
|
||||
if (v8_rx(v8_caller, amp, samples) && remnant)
|
||||
break;
|
||||
for (i = 0; i < samples; i++)
|
||||
out_amp[2*i + 1] = amp[i];
|
||||
|
||||
outframes = sf_writef_short(outhandle, out_amp, samples);
|
||||
if (outframes != samples)
|
||||
{
|
||||
fprintf(stderr, " Error writing audio file\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Test 1: V.8 terminal calls V.8 terminal\n");
|
||||
v8_calls_v8_tests(outhandle);
|
||||
|
||||
printf("Test 2: non-V.8 terminal calls V.8 terminal\n");
|
||||
non_v8_calls_v8_tests(outhandle);
|
||||
|
||||
printf("Test 3: V.8 terminal calls non-V.8 terminal\n");
|
||||
v8_calls_non_v8_tests(outhandle);
|
||||
|
||||
if (sf_close(outhandle))
|
||||
{
|
||||
fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
v8_free(v8_caller);
|
||||
v8_free(v8_answerer);
|
||||
|
||||
if (negotiations_ok != 2)
|
||||
{
|
||||
printf("Tests failed.\n");
|
||||
exit(2);
|
||||
}
|
||||
printf("Tests passed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Decode file '%s'\n", decode_test_file);
|
||||
v8_answerer = v8_init(NULL, FALSE, answerer_available_modulations, handler, (void *) "answerer");
|
||||
v8_answerer = v8_init(NULL, FALSE, TRUE, answerer_available_modulations, handler, (void *) "answerer");
|
||||
logging = v8_get_logging_state(v8_answerer);
|
||||
span_log_set_level(logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG);
|
||||
span_log_set_tag(logging, "decoder");
|
||||
|
||||
Reference in New Issue
Block a user