Merge branch 'master' into smgmaster

This commit is contained in:
Moises Silva committed 2011-07-29 16:50:22 -04:00
commit f1dc7b1ddb
398 files changed
+38753 -4037

No files matched your search

+7
View File
@@ -643,7 +643,9 @@
/spandsp/src/at_interpreter_dictionary.h
/spandsp/src/config.h
/spandsp/src/make_at_dictionary
/spandsp/src/make_math_fixed_tables
/spandsp/src/make_modem_filter
/spandsp/src/math_fixed_tables.h
/spandsp/src/spandsp.h
/spandsp/src/stamp-h1
/spandsp/src/v17_v32bis_rx_fixed_rrc.h
@@ -917,6 +919,8 @@
/unimrcp/build/pkgconfig/unimrcpclient.pc
/unimrcp/build/pkgconfig/unimrcpplugin.pc
/unimrcp/build/pkgconfig/unimrcpserver.pc
/unimrcp/build/svnrev/Makefile
/unimrcp/build/svnrev/Makefile.in
/unimrcp/conf/Makefile
/unimrcp/conf/Makefile.in
/unimrcp/config.log
@@ -924,6 +928,7 @@
/unimrcp/configure
/unimrcp/data/Makefile
/unimrcp/data/Makefile.in
/unimrcp/docs/doxygen.conf
/unimrcp/libs/Makefile
/unimrcp/libs/Makefile.in
/unimrcp/libs/apr-toolkit/Makefile
@@ -981,6 +986,8 @@
/unimrcp/plugins/mrcp-pocketsphinx/Makefile.in
/unimrcp/plugins/mrcp-recorder/Makefile
/unimrcp/plugins/mrcp-recorder/Makefile.in
/unimrcp/plugins/demo-verifier/Makefile
/unimrcp/plugins/demo-verifier/Makefile.in
/unimrcp/tests/Makefile
/unimrcp/tests/Makefile.in
/unimrcp/tests/apttest/Makefile
+1 -1
View File
@@ -1284,7 +1284,7 @@ if test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_int"; then
elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_long"; then
size_t_fmt='#define APR_SIZE_T_FMT "ld"'
else
size_t_fmt='#error Can not determine the proper size for size_t'
size_t_fmt='#define APR_SIZE_T_FMT "zu"'
fi
APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], off_t, 8)
+1 -1
View File
@@ -409,7 +409,7 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b);
* @param pool The pool to tag
* @param tag The tag
*/
APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag);
APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag);
#if APR_HAS_THREADS
/**
+6 -2
View File
@@ -1895,9 +1895,13 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b)
return 0;
}
APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag)
APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag)
{
pool->tag = tag;
if (tag) {
pool->tag = tag;
}
return pool->tag;
}
+1 -2
View File
@@ -311,7 +311,6 @@ ESL_DECLARE(esl_status_t) esl_event_del_header_val(esl_event_t *event, const cha
if (hp->idx) {
int i = 0;
hp->value = NULL;
for (i = 0; i < hp->idx; i++) {
FREE(hp->array[i]);
@@ -642,7 +641,7 @@ ESL_DECLARE(void) esl_event_destroy(esl_event_t **event)
if (this->idx) {
int i = 0;
this->value = NULL;
for (i = 0; i < this->idx; i++) {
FREE(this->array[i]);
}
+32
View File
@@ -275,5 +275,37 @@ with the signaling protocols that you can run on top of your I/O interfaces.
-->
</span>
</r2_spans>
<!--
PRI passive tapping spans. Requires patched version from libpri at http://svn.digium.com/svn/libpri/team/moy/tap-1.4
You must also configure FreeTDM with "-with-pritap" (see ./configure help for details)
-->
<pritap_spans>
<span name="tapped1">
<!-- The peer span name used to tap the link -->
<param name="peerspan" value="tapped2"/>
<!--
Whether to mix the audio from the peerspan with the audio from this span
This is most likely what you want (and therefore the default) so you can hear
the full conversation being tapped instead of just one side
-->
<!-- <param name="mixaudio" value="yes"/> -->
<!-- switch parameters (required), where to send calls to -->
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
</span>
<span name="tapped2">
<!-- This span is linked to "tapped1" through its peerspan parameter -->
<param name="peerspan" value="tapped1"/>
<!-- <param name="mixaudio" value="yes"/> -->
<!-- switch parameters (required), where to send calls to -->
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
</span>
</pritap_spans>
</configuration>
+22 -6
View File
@@ -2806,7 +2806,7 @@ static ftdm_status_t ftdmchan_activate_dtmf_buffer(ftdm_channel_t *ftdmchan)
static ftdm_status_t ftdm_insert_dtmf_pause(ftdm_channel_t *ftdmchan, ftdm_size_t pausems)
{
void *data = NULL;
unsigned int datalen = pausems * sizeof(uint16_t);
ftdm_size_t datalen = pausems * sizeof(uint16_t);
data = ftdm_malloc(datalen);
ftdm_assert(data, "Failed to allocate memory\n");
@@ -3800,7 +3800,6 @@ FT_DECLARE(void) ftdm_generate_sln_silence(int16_t *data, uint32_t samples, uint
FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen)
{
ftdm_status_t status = FTDM_FAIL;
fio_codec_t codec_func = NULL;
ftdm_size_t max = *datalen;
@@ -3822,11 +3821,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
}
if (codec_func) {
status = codec_func(data, max, datalen);
codec_func(data, max, datalen);
} else {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "no codec function to perform transcoding from %d to %d\n", ftdmchan->native_codec, ftdmchan->effective_codec);
status = FTDM_FAIL;
}
}
@@ -3861,7 +3859,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
} else {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "invalid effective codec %d\n", ftdmchan->effective_codec);
status = FTDM_FAIL;
goto done;
}
}
@@ -4591,6 +4588,7 @@ static ftdm_status_t load_config(void)
ftdm_analog_start_type_t tmp;
ftdm_size_t len = 0;
ftdm_channel_config_t chan_config;
ftdm_status_t ret = FTDM_SUCCESS;
memset(&chan_config, 0, sizeof(chan_config));
sprintf(chan_config.group_name, "__default");
@@ -4627,6 +4625,13 @@ static ftdm_status_t load_config(void)
*name++ = '\0';
}
/* Verify is trunk_type was specified for previous span */
if (span && span->trunk_type == FTDM_TRUNK_NONE) {
ftdm_log(FTDM_LOG_ERROR, "trunk_type not specified for span %d (%s)\n", span->span_id, span->name);
ret = FTDM_FAIL;
goto done;
}
if (ftdm_span_create(type, name, &span) == FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_DEBUG, "created span %d (%s) of type %s\n", span->span_id, span->name, type);
d = 0;
@@ -4824,11 +4829,22 @@ static ftdm_status_t load_config(void)
ftdm_log(FTDM_LOG_ERROR, "unknown param [%s] '%s' / '%s'\n", cfg.category, var, val);
}
}
/* Verify is trunk_type was specified for the last span */
if (span && span->trunk_type == FTDM_TRUNK_NONE) {
ftdm_log(FTDM_LOG_ERROR, "trunk_type not specified for span %d (%s)\n", span->span_id, span->name);
ret = FTDM_FAIL;
}
done:
ftdm_config_close_file(&cfg);
ftdm_log(FTDM_LOG_INFO, "Configured %u channel(s)\n", configured);
if (!configured) {
ret = FTDM_FAIL;
}
return configured ? FTDM_SUCCESS : FTDM_FAIL;
return ret;
}
static ftdm_status_t process_module_config(ftdm_io_interface_t *fio)
@@ -401,7 +401,7 @@ static void analog_dial(ftdm_channel_t *ftdmchan, uint32_t *state_counter, uint3
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL1] = 1;
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL2] = 1;
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL3] = 1;
*dial_timeout = ((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000;
*dial_timeout = (uint32_t)((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000;
}
}
}
@@ -932,6 +932,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
ftdm_channel_lock(closed_chan);
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Going onhook");
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL);
}
@@ -34,6 +34,10 @@
#include "private/ftdm_core.h"
#include "ftmod_libpri.h"
#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif
static void _ftdm_channel_set_state_force(ftdm_channel_t *chan, const ftdm_channel_state_t state)
{
assert(chan);
@@ -476,7 +480,7 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DOWN, FTDM_END},
{FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_RING, FTDM_END}
{FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_RING, FTDM_END}
},
{
ZSD_INBOUND,
@@ -484,6 +488,12 @@ static ftdm_state_map_t isdn_state_map = {
{FTDM_CHANNEL_STATE_DIALTONE, FTDM_END},
{FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_COLLECT, FTDM_END},
{FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
@@ -656,6 +666,29 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
}
break;
case FTDM_CHANNEL_STATE_COLLECT: /* Overlap receive */
{
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
if (!call) {
ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "No call handle\n");
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
}
else if (pri_need_more_info(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0)) {
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "Failed to send INFORMATION request\n");
/* hangup call */
caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
}
} else {
ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "Overlap receiving on outbound call?\n");
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
}
}
break;
case FTDM_CHANNEL_STATE_RING:
{
/*
@@ -837,11 +870,57 @@ static __inline__ void check_state(ftdm_span_t *span)
*/
static int on_info(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent)
{
ftdm_log(FTDM_LOG_DEBUG, "number is: %s\n", pevent->ring.callednum);
ftdm_span_t *span = spri->span;
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->ring.channel);
ftdm_caller_data_t *caller_data = NULL;
if (strlen(pevent->ring.callednum) > 3) {
ftdm_log(FTDM_LOG_DEBUG, "final number is: %s\n", pevent->ring.callednum);
pri_answer(spri->pri, pevent->ring.call, 0, 1);
if (!chan) {
ftdm_log(FTDM_LOG_CRIT, "-- Info on channel %d:%d %s but it's not in use?\n", ftdm_span_get_id(span), pevent->ring.channel);
return 0;
}
caller_data = ftdm_channel_get_caller_data(chan);
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_COLLECT: /* TE-mode overlap receiving */
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "-- Incoming INFORMATION indication, current called number: '%s', number complete: %s\n",
pevent->ring.callednum, pevent->ring.complete ? "yes" : "no");
/* append digits to dnis */
if (!ftdm_strlen_zero(pevent->ring.callednum)) {
int digits = strlen(pevent->ring.callednum);
int offset = strlen(caller_data->dnis.digits);
int len = MIN(sizeof(caller_data->dnis.digits) - 1 - offset, digits); /* max. length without terminator */
if (len < digits) {
ftdm_log_chan(chan, FTDM_LOG_WARNING, "Length %d of digit string exceeds available space %d of DNIS, truncating!\n",
digits, len);
}
ftdm_copy_string(&caller_data->dnis.digits[offset], (char *)pevent->ring.callednum, len + 1); /* max. length with terminator */
caller_data->dnis.digits[offset + len] = '\0';
}
if (pevent->ring.complete) {
ftdm_log_chan_msg(chan, FTDM_LOG_DEBUG, "Number complete indicated, moving channel to RING state\n");
/* notify switch */
ftdm_set_state(chan, FTDM_CHANNEL_STATE_RING);
}
break;
case FTDM_CHANNEL_STATE_DIALTONE: /* NT-mode overlap receiving */
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "-- Incoming INFORMATION indication, current called number: '%s'\n",
pevent->ring.callednum);
/* Need to add proper support for overlap receiving in NT-mode (requires FreeSWITCH + FreeTDM core support) */
if (strlen(pevent->ring.callednum) > 3) {
ftdm_log(FTDM_LOG_DEBUG, "final number is: %s\n", pevent->ring.callednum);
pri_answer(spri->pri, pevent->ring.call, 0, 1);
}
break;
default:
ftdm_log_chan(chan, FTDM_LOG_ERROR, "-- INFORMATION indication on channel %d:%d in invalid state '%s'\n",
ftdm_channel_get_span_id(chan),
ftdm_channel_get_id(chan),
ftdm_channel_get_state_str(chan));
}
return 0;
}
@@ -878,7 +957,15 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
chan->caller_data.hangup_cause = pevent->hangup.cause;
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_DIALTONE:
case FTDM_CHANNEL_STATE_COLLECT:
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP);
break;
default:
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
}
break;
case LPWRAP_PRI_EVENT_HANGUP_ACK: /* */
@@ -1112,6 +1199,7 @@ out:
static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent)
{
ftdm_span_t *span = spri->span;
ftdm_libpri_data_t *isdn_data = span->signal_data;
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->ring.channel);
ftdm_caller_data_t *caller_data = NULL;
int ret = 0;
@@ -1187,8 +1275,14 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
/* hurr, this is valid as along as nobody releases the call */
chan->call_data = pevent->ring.call;
ftdm_set_state(chan, FTDM_CHANNEL_STATE_RING);
/* only go to RING state if we have the complete called number (indicated via pevent->complete flag) */
if (!pevent->ring.complete && (isdn_data->overlap & FTMOD_LIBPRI_OVERLAP_RECEIVE)) {
ftdm_log(FTDM_LOG_DEBUG, "RING event without complete indicator, waiting for more digits\n");
ftdm_set_state(chan, FTDM_CHANNEL_STATE_COLLECT);
} else {
ftdm_log(FTDM_LOG_DEBUG, "RING event with complete indicator (or overlap receive disabled)\n");
ftdm_set_state(chan, FTDM_CHANNEL_STATE_RING);
}
done:
ftdm_channel_unlock(chan);
return ret;
@@ -1878,6 +1972,25 @@ static int parse_ton(const char *ton)
return PRI_UNKNOWN;
}
/**
* \brief Parse overlap string to value
* \param val String to parse
* \return Overlap flags
*/
static int parse_overlap_dial(const char *val)
{
if (!strcasecmp(val, "yes") || !strcasecmp(val, "both"))
return FTMOD_LIBPRI_OVERLAP_BOTH;
if (!strcasecmp(val, "incoming") || !strcasecmp(val, "receive"))
return FTMOD_LIBPRI_OVERLAP_RECEIVE;
if (!strcasecmp(val, "outgoing") || !strcasecmp(val, "send"))
return FTMOD_LIBPRI_OVERLAP_SEND;
if (!strcasecmp(val, "no"))
return FTMOD_LIBPRI_OVERLAP_NONE;
return -1;
}
/**
* \brief Parses an option string to flags
* \param in String to parse for configuration options
@@ -2034,6 +2147,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
else if (!strcasecmp(var, "l1") || !strcasecmp(var, "layer1")) {
isdn_data->layer1 = parse_layer1(val);
}
else if (!strcasecmp(var, "overlapdial")) {
if ((isdn_data->overlap = parse_overlap_dial(val)) == -1) {
ftdm_log(FTDM_LOG_ERROR, "Invalid overlap flag, ignoring parameter\n");
isdn_data->overlap = FTMOD_LIBPRI_OVERLAP_NONE;
}
}
else if (!strcasecmp(var, "debug")) {
if (parse_debug(val, &isdn_data->debug_mask) == -1) {
ftdm_log(FTDM_LOG_ERROR, "Invalid debug flag, ignoring parameter\n");
@@ -51,6 +51,12 @@ typedef enum {
FTMOD_LIBPRI_RUNNING = (1 << 0)
} ftdm_isdn_flag_t;
typedef enum {
FTMOD_LIBPRI_OVERLAP_NONE = 0,
FTMOD_LIBPRI_OVERLAP_RECEIVE = (1 << 0),
FTMOD_LIBPRI_OVERLAP_SEND = (1 << 1)
#define FTMOD_LIBPRI_OVERLAP_BOTH (FTMOD_LIBPRI_OVERLAP_RECEIVE | FTMOD_LIBPRI_OVERLAP_SEND)
} ftdm_isdn_overlap_t;
struct ftdm_libpri_data {
ftdm_channel_t *dchan;
@@ -60,6 +66,7 @@ struct ftdm_libpri_data {
int mode;
int dialect;
int overlap; /*!< Overlap dial flags */
unsigned int layer1;
unsigned int ton;
@@ -57,6 +57,7 @@ typedef struct pritap {
int32_t flags;
struct pri *pri;
int debug;
uint8_t mixaudio;
ftdm_channel_t *dchan;
ftdm_span_t *span;
ftdm_span_t *peerspan;
@@ -752,6 +753,7 @@ static ftdm_status_t ftdm_pritap_sig_read(ftdm_channel_t *ftdmchan, void *data,
ftdm_status_t status;
fio_codec_t codec_func;
ftdm_channel_t *peerchan = ftdmchan->call_data;
pritap_t *pritap = ftdmchan->span->signal_data;
int16_t chanbuf[size];
int16_t peerbuf[size];
int16_t mixedbuf[size];
@@ -762,6 +764,11 @@ static ftdm_status_t ftdm_pritap_sig_read(ftdm_channel_t *ftdmchan, void *data,
return FTDM_SUCCESS;
}
if (!pritap->mixaudio) {
/* No mixing requested */
return FTDM_SUCCESS;
}
if (ftdmchan->native_codec != peerchan->native_codec) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Invalid peer channel with format %d, ours = %d\n",
peerchan->native_codec, ftdmchan->native_codec);
@@ -829,6 +836,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
uint32_t i;
const char *var, *val;
const char *debug = NULL;
uint8_t mixaudio = 1;
ftdm_channel_t *dchan = NULL;
pritap_t *pritap = NULL;
ftdm_span_t *peerspan = NULL;
@@ -857,6 +865,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
if (!strcasecmp(var, "debug")) {
debug = val;
} else if (!strcasecmp(var, "mixaudio")) {
mixaudio = ftdm_true(val);
} else if (!strcasecmp(var, "peerspan")) {
if (ftdm_span_find_by_name(val, &peerspan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Invalid tapping peer span %s\n", val);
@@ -880,6 +890,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
pritap->debug = parse_debug(debug);
pritap->dchan = dchan;
pritap->peerspan = peerspan;
pritap->mixaudio = mixaudio;
span->start = ftdm_pritap_start;
span->stop = ftdm_pritap_stop;
@@ -344,7 +344,6 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj)
uint8_t data[1000];
unsigned i = 0;
ftdm_status_t status = FTDM_SUCCESS;
ftdm_wait_flag_t wflags = FTDM_READ;
ftdm_span_t *span = (ftdm_span_t*) obj;
ftdm_size_t len = 0;
ftdm_channel_t *ftdmchan = NULL;
@@ -356,10 +355,6 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj)
/* Initialize the d-channel */
ftdm_assert(((sngisdn_span_data_t*)span->signal_data)->dchan, "Span does not have a dchannel");
ftdm_channel_set_feature(((sngisdn_span_data_t*)span->signal_data)->dchan, FTDM_CHANNEL_FEATURE_IO_STATS);
ftdm_sangoma_isdn_dchan_set_queue_size(((sngisdn_span_data_t*)span->signal_data)->dchan);
ftdm_channel_open_chan(((sngisdn_span_data_t*)span->signal_data)->dchan);
chaniter = ftdm_span_get_chan_iterator(span, NULL);
if (!chaniter) {
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
@@ -369,7 +364,6 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj)
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
len = 1000;
waitms = 1000;
wflags = FTDM_READ;
memset(poll_events, 0, sizeof(short)*span->chan_count);
poll_events[i] |= FTDM_EVENTS;
@@ -1039,7 +1033,13 @@ static ftdm_status_t ftdm_sangoma_isdn_dtmf(ftdm_channel_t *ftdmchan, const char
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = span->signal_data;
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
ftdm_channel_set_feature(((sngisdn_span_data_t*)span->signal_data)->dchan, FTDM_CHANNEL_FEATURE_IO_STATS);
ftdm_channel_open_chan(((sngisdn_span_data_t*)span->signal_data)->dchan);
ftdm_sangoma_isdn_dchan_set_queue_size(((sngisdn_span_data_t*)span->signal_data)->dchan);
if (sngisdn_stack_start(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
return FTDM_FAIL;
@@ -1073,6 +1073,11 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
return FTDM_FAIL;
}
if (signal_data->restart_timeout) {
ftdm_log(FTDM_LOG_DEBUG, "%s:Scheduling Restart timeout\n", signal_data->ftdm_span->name);
ftdm_sched_timer(signal_data->sched, "restart_timeout", signal_data->restart_timeout,
sngisdn_restart_timeout, (void*) signal_data, &signal_data->timers[SNGISDN_SPAN_TIMER_RESTART]);
}
ftdm_log(FTDM_LOG_DEBUG,"Finished starting span %s\n", span->name);
return FTDM_SUCCESS;
}
@@ -154,12 +154,18 @@ typedef struct ftdm_sngisdn_prog_ind {
} ftdm_sngisdn_progind_t;
/* Only timers that can be cancelled are listed here */
#define SNGISDN_NUM_TIMERS 2
/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */
typedef enum {
SNGISDN_TIMER_FACILITY = 0,
SNGISDN_TIMER_ATT_TRANSFER,
} ftdm_sngisdn_timer_t;
#define SNGISDN_NUM_CHAN_TIMERS 2
/* Increase SNGISDN_NUM_CHAN_TIMERS as number of ftdm_sngisdn_chan_timer_t increases */
typedef enum {
SNGISDN_CHAN_TIMER_FACILITY,
SNGISDN_CHAN_TIMER_ATT_TRANSFER,
} ftdm_sngisdn_chan_timer_t;
#define SNGISDN_NUM_SPAN_TIMERS 1
/* Increase SNGISDN_NUM_SPAN_TIMERS as number of ftdm_sngisdn_spanan_timer_t increases */
typedef enum {
SNGISDN_SPAN_TIMER_RESTART,
} ftdm_sngisdn_span_timer_t;
typedef struct sngisdn_glare_data {
int16_t suId;
@@ -210,7 +216,7 @@ typedef struct sngisdn_chan_data {
uint8_t globalFlg;
sngisdn_glare_data_t glare;
ftdm_timer_id_t timers[SNGISDN_NUM_TIMERS];
ftdm_timer_id_t timers[SNGISDN_NUM_CHAN_TIMERS];
sngisdn_transfer_data_t transfer_data;
/* variables saved here will be sent to the user application
@@ -252,8 +258,10 @@ typedef struct sngisdn_span_data {
uint8_t raw_trace_q921; /* TODO: combine with trace_flags */
uint8_t timer_t3;
uint8_t restart_opt;
uint8_t restart_timeout;
uint8_t force_sending_complete;
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
ftdm_timer_id_t timers[SNGISDN_NUM_SPAN_TIMERS];
ftdm_sched_t *sched;
ftdm_queue_t *event_queue;
} sngisdn_span_data_t;
@@ -452,8 +460,7 @@ ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display);
ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr);
ftdm_status_t get_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd);
ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
@@ -514,6 +521,7 @@ void sngisdn_delayed_connect(void* p_sngisdn_info);
void sngisdn_delayed_disconnect(void* p_sngisdn_info);
void sngisdn_facility_timeout(void* p_sngisdn_info);
void sngisdn_t3_timeout(void* p_sngisdn_info);
void sngisdn_restart_timeout(void* p_signal_data);
/* Stack management functions */
ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span);
@@ -359,6 +359,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
ftdm_set_bearer_layer1(val, (uint8_t*)&span->default_caller_data.bearer_layer1);
} else if (!strcasecmp(var, "channel-restart-on-link-up")) {
parse_yesno(var, val, &signal_data->restart_opt);
} else if (!strcasecmp(var, "channel-restart-timeout")) {
signal_data->restart_timeout = atoi(val);
} else if (!strcasecmp(var, "local-number")) {
if (add_local_number(val, span) != FTDM_SUCCESS) {
return FTDM_FAIL;
@@ -422,7 +422,7 @@ ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management
cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */
cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */
cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
cfg.t.cfg.s.bdDLSAP.t200Tmr = 3; /* t1 changed from 25 */
cfg.t.cfg.s.bdDLSAP.t203Tmr = 10; /* t3 changed from 50 */
cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */
cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */
@@ -681,12 +681,7 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */
cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE;
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN ||
signal_data->switchtype == SNGISDN_SWITCH_INSNET) {
cfg.t.cfg.s.inDLSAP.rstOpt = FALSE;
} else {
cfg.t.cfg.s.inDLSAP.rstOpt = TRUE;
}
cfg.t.cfg.s.inDLSAP.rstOpt = TRUE;
} else {
cfg.t.cfg.s.inDLSAP.ackOpt = FALSE;
cfg.t.cfg.s.inDLSAP.intType = USER;
@@ -803,8 +798,10 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.tmr.t322.val = 4;
cfg.t.cfg.s.inDLSAP.tmr.t332.enb = FALSE;
cfg.t.cfg.s.inDLSAP.tmr.t332.val = 35;
cfg.t.cfg.s.inDLSAP.tmr.tRst.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.tRst.val = 8;
cfg.t.cfg.s.inDLSAP.tmr.tAns.enb = FALSE; /* non-standard timer */
cfg.t.cfg.s.inDLSAP.tmr.t396.enb = FALSE; /* non-standard timer */
cfg.t.cfg.s.inDLSAP.tmr.t397.enb = TRUE; /* non-standard timer */
@@ -34,8 +34,7 @@
#include "ftmod_sangoma_isdn.h"
static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan);
static ftdm_status_t sngisdn_force_down(ftdm_channel_t *ftdmchan);
static ftdm_status_t sngisdn_bring_down(ftdm_channel_t *ftdmchan);
/* Remote side transmit a SETUP */
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
@@ -135,11 +134,8 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
get_facility_ie(ftdmchan, &conEvnt->facilityStr);
get_calling_name(ftdmchan, conEvnt);
if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) {
get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr);
}
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
if (conEvnt->bearCap[0].eh.pres) {
@@ -185,7 +181,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
/* Launch timer in case we never get a FACILITY msg */
if (signal_data->facility_timeout) {
ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_CHAN_TIMER_FACILITY]);
}
break;
} else if (ret_val == 0) {
@@ -836,7 +832,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
}
if (signal_data->facility_timeout) {
/* Cancel facility timeout */
ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_CHAN_TIMER_FACILITY]);
}
}
@@ -927,7 +923,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
switch(call_state) {
/* Sere ITU-T Q931 for definition of call states */
case 0: /* Remote switch thinks there are no calls on this channel */
if (sngisdn_force_down(ftdmchan) != FTDM_SUCCESS) {
if (sngisdn_bring_down(ftdmchan) != FTDM_SUCCESS) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
}
break;
@@ -1121,29 +1117,12 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
return;
}
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
{
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_RESET:
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
break;
case FTDM_CHANNEL_STATE_DOWN:
/* Do nothing */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n",
ftdm_channel_state2str(ftdmchan->state));
}
return;
}
static ftdm_status_t sngisdn_force_down(ftdm_channel_t *ftdmchan)
static ftdm_status_t sngisdn_bring_down(ftdm_channel_t *ftdmchan)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
ftdm_status_t status = FTDM_SUCCESS;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Forcing channel to DOWN state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Bringing channel to DOWN state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN:
/* Do nothing */
@@ -1196,38 +1175,36 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
return;
}
if (rstEvnt->rstInd.eh.pres != PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres != PRSNT_NODEF) {
ftdm_log(FTDM_LOG_DEBUG, "Received RESTART, but Restart Indicator IE not present\n");
return;
}
switch(rstEvnt->rstInd.rstClass.val) {
case IN_CL_INDCHAN: /* Indicated b-channel */
if (rstEvnt->chanId.eh.pres) {
if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.infoChanSel.val;
}
} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) {
switch(rstEvnt->rstInd.rstClass.val) {
case IN_CL_INDCHAN: /* Indicated b-channel */
if (rstEvnt->chanId.eh.pres) {
if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.infoChanSel.val;
}
} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
}
}
}
}
if (!chan_no) {
ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
if (!chan_no) {
ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
return;
}
break;
case IN_CL_SNGINT: /* Single interface */
case IN_CL_ALLINT: /* All interfaces */
/* In case restart class indicates all interfaces, we will duplicate
this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
so treat it as a single interface anyway */
chan_no = 0;
break;
default:
ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
return;
}
break;
case IN_CL_SNGINT: /* Single interface */
case IN_CL_ALLINT: /* All interfaces */
/* In case restart class indicates all interfaces, we will duplicate
this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
so treat it as a single interface anyway */
break;
default:
ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
return;
}
}
if (chan_no) { /* For a single channel */
@@ -1235,7 +1212,7 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no);
} else {
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
sngisdn_process_restart_confirm(ftdmchan);
sngisdn_bring_down(ftdmchan);
}
} else { /* for all channels */
ftdm_iterator_t *chaniter = NULL;
@@ -1243,7 +1220,7 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
sngisdn_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr));
sngisdn_bring_down((ftdm_channel_t*)ftdm_iterator_current(curr));
}
ftdm_iterator_free(chaniter);
}
@@ -1272,10 +1249,6 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
/* TODO: readjust this when NFAS is implemented as signal_data will not always be the first
* span for that d-channel */
if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
ftdm_log(FTDM_LOG_DEBUG, "Received RESTART IND, but Restart Indicator IE not present\n");
return;
}
signal_data = g_sngisdn_data.dchans[dChan].spans[1];
@@ -1283,46 +1256,48 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on unconfigured span (suId:%d)\n", suId);
return;
}
if (signal_data->restart_timeout) {
ftdm_sched_cancel_timer(signal_data->sched, signal_data->timers[SNGISDN_SPAN_TIMER_RESTART]);
}
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART IND (suId:%u dChan:%d ces:%d %s)\n", suId, dChan, ces,
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART IND (suId:%u dChan:%d ces:%d %s(%d))\n", suId, dChan, ces,
(evntType == IN_LNK_DWN)?"LNK_DOWN":
(evntType == IN_LNK_UP)?"LNK_UP":
(evntType == IN_INDCHAN)?"b-channel":
(evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures":
(evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown");
(evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown", evntType);
if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
ftdm_log(FTDM_LOG_DEBUG, "Received RESTART IND, but Restart Indicator IE not present\n");
return;
}
switch(rstEvnt->rstInd.rstClass.val) {
case IN_CL_INDCHAN: /* Indicated b-channel */
if (rstEvnt->chanId.eh.pres) {
if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.infoChanSel.val;
}
} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) {
switch(rstEvnt->rstInd.rstClass.val) {
case IN_CL_INDCHAN: /* Indicated b-channel */
if (rstEvnt->chanId.eh.pres) {
if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.infoChanSel.val;
}
} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
}
}
}
}
if (!chan_no) {
ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
if (!chan_no) {
ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
return;
}
break;
case IN_CL_SNGINT: /* Single interface */
case IN_CL_ALLINT: /* All interfaces */
/* In case restart class indicates all interfaces, we will duplicate
this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
so treat it as a single interface anyway */
chan_no = 0;
break;
default:
ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
return;
}
break;
case IN_CL_SNGINT: /* Single interface */
case IN_CL_ALLINT: /* All interfaces */
/* In case restart class indicates all interfaces, we will duplicate
this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
so treat it as a single interface anyway */
break;
default:
ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
return;
}
}
if (chan_no) { /* For a single channel */
@@ -1336,7 +1311,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
if (ftdmchan->physical_chan_id == chan_no) {
sngisdn_force_down(ftdmchan);
sngisdn_bring_down(ftdmchan);
}
}
ftdm_iterator_free(chaniter);
@@ -1347,7 +1322,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
sngisdn_force_down((ftdm_channel_t*)ftdm_iterator_current(curr));
sngisdn_bring_down((ftdm_channel_t*)ftdm_iterator_current(curr));
}
ftdm_iterator_free(chaniter);
}
@@ -491,7 +491,18 @@ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
/* Should we trigger congestion here? */
l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
}
#if 0
if (1) {
int i;
char string [2000];
unsigned string_len = 0;
for (i = 0; i < l1_frame.len; i++) {
string_len += sprintf(&string[string_len], "0x%02x ", l1_frame.data[i]);
}
ftdm_log_chan(dchan, FTDM_LOG_CRIT, "\nL1 RX [%s] flags:%x\n", string, l1_frame.flags);
}
#endif
sng_isdn_data_ind(signal_data->dchan_id, &l1_frame);
}
@@ -903,6 +903,17 @@ int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame)
if ((flags & FTDM_WRITE)) {
#if 0
int i;
char string [2000];
unsigned string_len = 0;
for (i = 0; i < length; i++) {
string_len += sprintf(&string[string_len], "0x%02x ", l1_frame->data[i]);
}
ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "\nL1 TX [%s]\n", string);
#endif
status = signal_data->dchan->fio->write(signal_data->dchan, l1_frame->data, (ftdm_size_t*)&length);
if (status != FTDM_SUCCESS) {
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n");
@@ -45,6 +45,9 @@ SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val);
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val);
ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr);
ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display);
ftdm_status_t get_calling_name_from_ntDisplay(ftdm_channel_t *ftdmchan, NtDisplay *display);
extern ftdm_sngisdn_data_t g_sngisdn_data;
@@ -355,6 +358,20 @@ ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *d
return FTDM_SUCCESS;
}
ftdm_status_t get_calling_name_from_ntDisplay(ftdm_channel_t *ftdmchan, NtDisplay *display)
{
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
if (display->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
}
if (display->dispInfo.pres != PRSNT_NODEF) {
return FTDM_FAIL;
}
ftdm_copy_string(caller_data->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1);
return FTDM_SUCCESS;
}
ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr)
{
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
@@ -374,6 +391,24 @@ ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *us
return FTDM_SUCCESS;
}
ftdm_status_t get_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
{
ftdm_status_t status = FTDM_FAIL;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
if (signal_data->switchtype == SNGISDN_SWITCH_DMS100) {
status = get_calling_name_from_ntDisplay(ftdmchan, &conEvnt->ntDisplay[0]);
} else {
status = get_calling_name_from_display(ftdmchan, &conEvnt->display);
}
if (status != FTDM_SUCCESS) {
status = get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr);
}
return status;
}
ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
{
char subaddress[100];
@@ -694,12 +729,22 @@ ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
/* follow through */
case SNGISDN_SWITCH_5ESS:
case SNGISDN_SWITCH_4ESS:
case SNGISDN_SWITCH_DMS100:
conEvnt->display.eh.pres = PRSNT_NODEF;
conEvnt->display.dispInfo.pres = PRSNT_NODEF;
conEvnt->display.dispInfo.len = len;
memcpy(conEvnt->display.dispInfo.val, caller_data->cid_name, len);
break;
case SNGISDN_SWITCH_DMS100:
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
conEvnt->ntDisplay[0].dispTypeNt.pres = PRSNT_NODEF;
conEvnt->ntDisplay[0].dispTypeNt.val = 0x01; /* Calling Party Name */
conEvnt->ntDisplay[0].assocInfo.pres = PRSNT_NODEF;
conEvnt->ntDisplay[0].assocInfo.val = 0x03; /* Included */
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
conEvnt->ntDisplay[0].dispInfo.pres = PRSNT_NODEF;
conEvnt->ntDisplay[0].dispInfo.len = len;
memcpy(conEvnt->ntDisplay[0].dispInfo.val, caller_data->cid_name, len);
break;
case SNGISDN_SWITCH_QSIG:
/* It seems like QSIG does not support Caller ID Name */
break;
@@ -976,7 +1021,7 @@ ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd)
return FTDM_SUCCESS;
}
void sngisdn_t3_timeout(void* p_sngisdn_info)
void sngisdn_t3_timeout(void *p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
@@ -998,7 +1043,31 @@ void sngisdn_t3_timeout(void* p_sngisdn_info)
ftdm_mutex_unlock(ftdmchan->mutex);
}
void sngisdn_delayed_setup(void* p_sngisdn_info)
void sngisdn_restart_timeout(void *p_signal_data)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data;
ftdm_span_t *span = signal_data->ftdm_span;
ftdm_log(FTDM_LOG_DEBUG, "s%d:Did not receive a RESTART from remote switch in %d ms - restarting\n", span->name, signal_data->restart_timeout);
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
ftdm_mutex_lock(ftdmchan->mutex);
if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESET);
}
ftdm_mutex_unlock(ftdmchan->mutex);
}
}
return;
}
void sngisdn_delayed_setup(void *p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
@@ -1009,7 +1078,7 @@ void sngisdn_delayed_setup(void* p_sngisdn_info)
return;
}
void sngisdn_delayed_release(void* p_sngisdn_info)
void sngisdn_delayed_release(void *p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
@@ -1032,7 +1101,7 @@ void sngisdn_delayed_release(void* p_sngisdn_info)
return;
}
void sngisdn_delayed_connect(void* p_sngisdn_info)
void sngisdn_delayed_connect(void *p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
@@ -1047,7 +1116,7 @@ void sngisdn_delayed_connect(void* p_sngisdn_info)
return;
}
void sngisdn_delayed_disconnect(void* p_sngisdn_info)
void sngisdn_delayed_disconnect(void *p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
@@ -1069,7 +1138,7 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info)
return;
}
void sngisdn_facility_timeout(void* p_sngisdn_info)
void sngisdn_facility_timeout(void *p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
@@ -114,7 +114,7 @@ void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace
{
char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */
sngisdn_decode_q921(data_str, data, data_len);
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] %s FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q921] %s FRAME %s:\n%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
ftdm_safe_free(data_str);
}
@@ -144,7 +144,7 @@ void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d
void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len)
{
int str_len;
uint32_t str_len;
uint32_t i;
uint8_t sapi, cr, ea, tei, ns, nr, pf, p, cmd;
uint8_t frame_format = 0;
@@ -211,6 +211,8 @@ void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len)
break;
}
}
print_hex_dump(str, &str_len, (uint8_t*) data, 0, data_len);
return;
}
@@ -219,7 +221,7 @@ void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace
{
char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
sngisdn_decode_q931(data_str, data, data_len);
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] %s FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q931] %s FRAME %s:\n%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
ftdm_safe_free(data_str);
}
@@ -584,11 +586,20 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
break;
case PROT_Q931_IE_DISPLAY:
{
uint8_t displayStrOct=2, j;
uint8_t j;
char displayStr[82];
uint8_t displayNtEnabled = 0;
uint8_t displayStrOct = 2;
uint8_t displayType = 0;
uint8_t assocInfo = 0;
memset(displayStr, 0, sizeof(displayStr));
if(get_bits(OCTET(3),8,8)) {
displayType = get_bits(OCTET(3),1,4);
assocInfo = get_bits(OCTET(3),5,7);
displayNtEnabled = 1;
displayStrOct++;
}
j = 0;
@@ -599,8 +610,15 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
displayStr[j++]=ia5[get_bits(OCTET(displayStrOct),1,4)][get_bits(OCTET(displayStrOct),5,8)];
}
displayStr[j]='\0';
*str_len+= sprintf(&str[*str_len], "%s(l:%d)\n",
displayStr, len);
if (displayNtEnabled) {
*str_len+= sprintf(&str[*str_len], "%s(l:%d) type:%s(%d) info:%s(%d)\n",
displayStr, len,
get_code_2_str(displayType, dcodQ931DisplayTypeTable), displayType,
get_code_2_str(assocInfo, dcodQ931AssocInfoTable), assocInfo);
} else {
*str_len+= sprintf(&str[*str_len], "%s(l:%d)\n",
displayStr, len);
}
}
break;
case PROT_Q931_IE_RESTART_IND:
@@ -578,5 +578,17 @@ struct code2str dcodQ931TypeOfSubaddressTable[] = {
{ -1, "Invalid"},
};
#endif /* __FTMOD_SANGOMA_ISDN_TRACE_H__ */
struct code2str dcodQ931DisplayTypeTable[] = {
{ 0x00, "Calling Party Name"},
{ 0x01, "Connected Party Name"},
{ 0x05, "Original Called Party Name"},
{ -1, "Invalid"},
};
struct code2str dcodQ931AssocInfoTable[] = {
{ 0x00, "Requested"},
{ 0x03, "Included"},
{ -1, "Invalid"},
};
#endif /* __FTMOD_SANGOMA_ISDN_TRACE_H__ */
@@ -164,7 +164,7 @@ static ftdm_status_t att_courtesy_vru(ftdm_channel_t *ftdmchan, sngisdn_transfer
sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_UP);
}
if (signal_data->transfer_timeout) {
ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "courtesy_transfer_timeout", signal_data->transfer_timeout, att_courtesy_transfer_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_ATT_TRANSFER]);
ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "courtesy_transfer_timeout", signal_data->transfer_timeout, att_courtesy_transfer_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_CHAN_TIMER_ATT_TRANSFER]);
}
status = FTDM_SUCCESS;
@@ -260,7 +260,7 @@ ftdm_status_t sngisdn_att_transfer_process_dtmf(ftdm_channel_t *ftdmchan, const
sngisdn_info->transfer_data.response = FTDM_TRANSFER_RESPONSE_INVALID;
}
if (signal_data->transfer_timeout) {
ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_TIMER_ATT_TRANSFER]);
ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_CHAN_TIMER_ATT_TRANSFER]);
}
if (sngisdn_info->transfer_data.response == FTDM_TRANSFER_RESPONSE_OK &&
@@ -29,6 +29,11 @@
* LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
*
* Ricardo Barroetaveña <rbarroetavena@anura.com.ar>
*
*/
/* INCLUDE ********************************************************************/
@@ -950,31 +950,31 @@ if (ftdmchan->state == new_state) { \
#define SS7_FUNC_TRACE_EXIT(a) if (g_ftdm_sngss7_data.function_trace) { \
switch (g_ftdm_sngss7_data.function_trace_level) { \
case 0: \
ftdm_log(FTDM_LOG_EMERG,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_EMERG,"Exiting %s\n", a); \
break; \
case 1: \
ftdm_log(FTDM_LOG_ALERT,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_ALERT,"Exiting %s\n", a); \
break; \
case 2: \
ftdm_log(FTDM_LOG_CRIT,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_CRIT,"Exiting %s\n", a); \
break; \
case 3: \
ftdm_log(FTDM_LOG_ERROR,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_ERROR,"Exiting %s\n", a); \
break; \
case 4: \
ftdm_log(FTDM_LOG_WARNING,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_WARNING,"Exiting %s\n", a); \
break; \
case 5: \
ftdm_log(FTDM_LOG_NOTICE,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_NOTICE,"Exiting %s\n", a); \
break; \
case 6: \
ftdm_log(FTDM_LOG_INFO,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_INFO,"Exiting %s\n", a); \
break; \
case 7: \
ftdm_log(FTDM_LOG_DEBUG,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_DEBUG,"Exiting %s\n", a); \
break; \
default: \
ftdm_log(FTDM_LOG_INFO,"Exitting %s\n", a); \
ftdm_log(FTDM_LOG_INFO,"Exiting %s\n", a); \
break; \
} /* switch (g_ftdm_sngss7_data.function_trace_level) */ \
} /* if(g_ftdm_sngss7_data.function_trace) */
+6 -6
View File
@@ -725,7 +725,7 @@ static FIO_COMMAND_FUNCTION(zt_command)
{
int command = ZT_OFFHOOK;
if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "OFFHOOK Failed");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "OFFHOOK Failed");
return FTDM_FAIL;
}
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK);
@@ -735,7 +735,7 @@ static FIO_COMMAND_FUNCTION(zt_command)
{
int command = ZT_ONHOOK;
if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ONHOOK Failed");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "ONHOOK Failed");
return FTDM_FAIL;
}
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK);
@@ -745,7 +745,7 @@ static FIO_COMMAND_FUNCTION(zt_command)
{
int command = ZT_FLASH;
if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "FLASH Failed");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "FLASH Failed");
return FTDM_FAIL;
}
}
@@ -754,7 +754,7 @@ static FIO_COMMAND_FUNCTION(zt_command)
{
int command = ZT_WINK;
if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "WINK Failed");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "WINK Failed");
return FTDM_FAIL;
}
}
@@ -763,7 +763,7 @@ static FIO_COMMAND_FUNCTION(zt_command)
{
int command = ZT_RING;
if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Ring Failed");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "RING Failed");
return FTDM_FAIL;
}
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING);
@@ -773,7 +773,7 @@ static FIO_COMMAND_FUNCTION(zt_command)
{
int command = ZT_RINGOFF;
if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Ring-off failed");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Ring-off Failed");
return FTDM_FAIL;
}
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING);
+2 -2
View File
@@ -48,7 +48,7 @@
#define FTDM_MAX_CHANNELS_PHYSICAL_SPAN 32
/*! \brief Max number of physical spans per logical span */
#define FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN 32
#define FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN 128
/*! \brief Max number of channels a logical span can contain */
#define FTDM_MAX_CHANNELS_SPAN FTDM_MAX_CHANNELS_PHYSICAL_SPAN * FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN
@@ -57,7 +57,7 @@
#define FTDM_MAX_SPANS_INTERFACE 128
/*! \brief Max number of channels per hunting group */
#define FTDM_MAX_CHANNELS_GROUP 1024
#define FTDM_MAX_CHANNELS_GROUP 2048
/*! \brief Max number of groups */
#define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE
+3 -1
View File
@@ -607,7 +607,9 @@ static int on_disco_default(void *user_data, ikspak *pak)
int all = 0;
iks_insert_attrib(iq, "from", handle->login);
iks_insert_attrib(iq, "to", pak->from->full);
if (pak->from) {
iks_insert_attrib(iq, "to", pak->from->full);
}
iks_insert_attrib(iq, "id", pak->id);
iks_insert_attrib(iq, "type", "result");
+1 -1
View File
@@ -1 +1 @@
Wed Apr 27 11:49:37 CDT 2011
Wed Jul 6 15:11:41 CDT 2011
+25 -21
View File
@@ -110,6 +110,7 @@ nua_handle_t *nh_create_handle(nua_t *nua,
assert(nua->nua_home);
if ((nh = su_home_clone(nua->nua_home, sizeof(*nh)))) {
//if ((nh = su_home_new(sizeof(*nh)))) {
nh->nh_valid = nua_valid_handle_cookie;
nh->nh_nua = nua;
nh->nh_magic = hmagic;
@@ -171,10 +172,16 @@ _nua_handle_ref_by(nua_handle_t *nh,
char const *file, unsigned line,
char const *function)
{
if (nh)
SU_DEBUG_0(("%p - nua_handle_ref() => "MOD_ZU" by %s:%u: %s()\n",
nh, su_home_refcount((su_home_t *)nh) + 1, file, line, by));
return (nua_handle_t *)su_home_ref((su_home_t *)nh);
#if (HAVE_MEMLEAK_LOG == 1)
if (nh)
SU_DEBUG_0(("%p - nua_handle_ref() => "MOD_ZU" by %s:%u: %s()\n",
nh, su_home_refcount((su_home_t *)nh) + 1, file, line, function));
return (nua_handle_t *)su_home_ref((su_home_t *)nh);
#else
return (nua_handle_t *)_su_home_ref_by((su_home_t *)nh, file, line, function);
#endif
}
int
@@ -182,26 +189,23 @@ _nua_handle_unref_by(nua_handle_t *nh,
char const *file, unsigned line,
char const *function)
{
if (nh) {
size_t refcount = su_home_refcount((su_home_t *)nh) - 1;
int freed = su_home_unref((su_home_t *)nh);
if (freed) refcount = 0;
SU_DEBUG_0(("%p - nua_handle_unref() => "MOD_ZU" by %s:%u: %s()\n",
nh, refcount, file, line, by));
return freed;
}
return 0;
}
#if (HAVE_MEMLEAK_LOG == 1)
nua_handle_t *nua_handle_ref(nua_handle_t *nh)
{
return _nua_handle_ref_by(nh, "<app>", 0, "<app>")
}
if (nh) {
size_t refcount = su_home_refcount((su_home_t *)nh) - 1;
int freed = su_home_unref((su_home_t *)nh);
int nua_handle_unref(nua_handle_t *nh)
{
return _nua_handle_unref_by(nh, "<app>", 0, "<app>")
if (freed) refcount = 0;
SU_DEBUG_0(("%p - nua_handle_unref() => "MOD_ZU" by %s:%u: %s()\n",
nh, refcount, file, line, function));
return freed;
}
return 0;
#else
return _su_home_unref_by((su_home_t *)nh, file, line, function);
#endif
}
#else
@@ -373,11 +373,14 @@ nua_dialog_usage_remove_at(nua_owner_t *own,
nua_client_request_t *cr0,
nua_server_request_t *sr0)
{
int unref = 0;
nua_dialog_usage_t *du = NULL;
if (*at) {
nua_dialog_usage_t *du = *at;
sip_event_t const *o = NULL;
nua_client_request_t *cr, *cr_next;
nua_server_request_t *sr, *sr_next;
du = *at;
*at = du->du_next;
@@ -409,8 +412,7 @@ nua_dialog_usage_remove_at(nua_owner_t *own,
}
}
su_home_unref(own);
su_free(own, du);
unref = 1;
}
/* Zap dialog if there are no more usages */
@@ -419,11 +421,20 @@ nua_dialog_usage_remove_at(nua_owner_t *own,
else if (ds->ds_usage == NULL) {
nua_dialog_remove(own, ds, NULL);
ds->ds_has_events = 0;
if (unref) {
su_home_unref(own);
su_free(own, du);
}
return;
}
else {
nua_dialog_log_usage(own, ds);
}
if (unref) {
su_home_unref(own);
su_free(own, du);
}
}
static
@@ -3721,6 +3721,9 @@ static int nua_bye_client_init(nua_client_request_t *cr,
static int nua_bye_client_request(nua_client_request_t *cr,
msg_t *msg, sip_t *sip,
tagi_t const *tags);
static int nua_bye_client_response(nua_client_request_t *cr,
int status, char const *phrase,
sip_t const *sip);
static int nua_bye_client_report(nua_client_request_t *cr,
int status, char const *phrase,
sip_t const *sip,
@@ -3739,7 +3742,7 @@ nua_client_methods_t const nua_bye_client_methods = {
nua_bye_client_init, /* crm_init */
nua_bye_client_request, /* crm_send */
NULL, /* crm_check_restart */
NULL, /* crm_recv */
nua_bye_client_response, /* crm_recv */
NULL, /* crm_preliminary */
nua_bye_client_report, /* crm_report */
NULL, /* crm_complete */
@@ -3818,6 +3821,18 @@ static int nua_bye_client_request(nua_client_request_t *cr,
return error;
}
static int nua_bye_client_response(nua_client_request_t *cr,
int status, char const *phrase,
sip_t const *sip) {
nua_dialog_usage_t *du = cr->cr_usage;
nua_session_usage_t *ss = nua_dialog_usage_private(du);
if (ss && ss->ss_reporting && status >= 900)
return 1;
return nua_base_client_response(cr, status, phrase, sip, NULL);
}
/** @NUA_EVENT nua_r_bye
*
+34 -3
View File
@@ -396,7 +396,9 @@ void nua_application_event(nua_t *dummy, su_msg_r sumsg, nua_ee_data_t *ee)
e->e_msg ? sip_object(e->e_msg) : NULL,
e->e_tags);
su_msg_destroy(frame->nf_saved);
if (su_msg_is_non_null(frame->nf_saved)) {
su_msg_destroy(frame->nf_saved);
}
nua->nua_current = frame->nf_next;
}
@@ -417,6 +419,23 @@ msg_t *nua_current_request(nua_t const *nua)
return NULL;
}
su_msg_t *nua_current_msg(nua_t const *nua, int clear)
{
if (nua && nua->nua_current && su_msg_is_non_null(nua->nua_current->nf_saved)) {
su_msg_t *r = nua->nua_current->nf_saved[0];
if (clear) {
nua->nua_current->nf_saved[0] = NULL;
}
return r;
//return su_msg_data(nua->nua_current->nf_saved)->ee_data->e_msg;
}
return NULL;
}
/** Get request message from saved nua event. @NEW_1_12_4.
*
* @sa nua_save_event(), nua_respond(), NUTAG_WITH_SAVED(),
@@ -638,8 +657,10 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_ee_data_t *ee)
nua_stack_respond(nua, nh, e->e_status, e->e_phrase, tags);
break;
case nua_r_destroy:
nua_stack_destroy_handle(nua, nh, tags);
su_msg_destroy(nua->nua_signal);
if (!nh->nh_destroyed) {
nua_stack_destroy_handle(nua, nh, tags);
su_msg_destroy(nua->nua_signal);
}
return;
default:
break;
@@ -912,6 +933,10 @@ nua_handle_t *nh_validate(nua_t *nua, nua_handle_t *maybe)
void nua_stack_destroy_handle(nua_t *nua, nua_handle_t *nh, tagi_t const *tags)
{
if (nh->nh_destroyed) {
return;
}
if (nh->nh_notifier)
nua_stack_terminate(nua, nh, (enum nua_event_e)0, NULL);
@@ -949,6 +974,12 @@ void nh_destroy(nua_t *nua, nua_handle_t *nh)
{
assert(nh); assert(nh != nua->nua_dhandle);
if (nh->nh_destroyed) {
return;
}
nh->nh_destroyed = 1;
if (nh->nh_notifier)
nea_server_destroy(nh->nh_notifier), nh->nh_notifier = NULL;
@@ -150,6 +150,7 @@ struct nua_handle_s
unsigned nh_ref_by_user:1; /**< Has user used the handle? */
unsigned nh_init:1; /**< Handle has been initialized */
unsigned nh_used_ptags:1; /**< Ptags has been used */
unsigned nh_destroyed:1; /**< nh_destroy already called */
unsigned :0;
nua_dialog_state_t nh_ds[1];
@@ -338,6 +339,8 @@ int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg,
nua_event_t event, int status, char const *phrase,
tagi_t const *tags);
su_msg_t *nua_current_msg(nua_t const *nua, int clear);
void nua_move_event(nua_saved_event_t a[1], nua_saved_event_t b[1]);
nua_handle_t *nh_create_handle(nua_t *nua, nua_hmagic_t *hmagic, tagi_t *tags);
@@ -64,8 +64,33 @@ struct su_home_s {
SU_DLL void *su_home_new(isize_t size)
__attribute__((__malloc__));
#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
int _su_home_mutex_lock(su_home_t *home, const char *file, unsigned int line, const char *function);
int _su_home_mutex_lock(su_home_t *home, const char *file, unsigned int line, const char *function);
#define su_home_mutex_lock(home) \
_su_home_mutex_lock((home), __FILE__, __LINE__, __func__)
#define su_home_mutex_unlock(home) \
_su_home_mutex_unlock((home), __FILE__, __LINE__, __func__)
su_home_t *_su_home_ref_by(
su_home_t *home, char const *file, unsigned line, char const *by);
int _su_home_unref_by(
su_home_t *home, char const *file, unsigned line, char const *by);
#define su_home_ref(home) \
_su_home_ref_by((home), __FILE__, __LINE__, __func__)
#define su_home_unref(home) \
_su_home_unref_by((home), __FILE__, __LINE__, __func__)
#else
SU_DLL void *su_home_ref(su_home_t const *);
SU_DLL int su_home_unref(su_home_t *);
#endif
SU_DLL size_t su_home_refcount(su_home_t *home);
@@ -107,9 +132,11 @@ SU_DLL void su_home_check(su_home_t const *home);
SU_DLL int su_home_check_alloc(su_home_t const *home, void const *data);
#if (!defined(HAVE_MEMLEAK_LOG) || (HAVE_MEMLEAK_LOG != 1))
SU_DLL int su_home_mutex_lock(su_home_t *home);
SU_DLL int su_home_mutex_unlock(su_home_t *home);
#endif
SU_DLL int su_home_lock(su_home_t *home);
SU_DLL int su_home_trylock(su_home_t *home);
+137 -22
View File
@@ -569,28 +569,6 @@ void *su_home_new(isize_t size)
return home;
}
/** Create a new reference to a home object. */
void *su_home_ref(su_home_t const *home)
{
if (home) {
su_block_t *sub = MEMLOCK(home);
if (sub == NULL || sub->sub_ref == 0) {
assert(sub && sub->sub_ref != 0);
UNLOCK(home);
return NULL;
}
if (sub->sub_ref != REF_MAX)
sub->sub_ref++;
UNLOCK(home);
}
else
su_seterrno(EFAULT);
return (void *)home;
}
/** Set destructor function.
*
* The destructor function is called after the reference count of a
@@ -637,6 +615,123 @@ int su_home_desctructor(su_home_t *home, void (*destructor)(void *))
return su_home_destructor(home, destructor);
}
#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
#include "sofia-sip/su_debug.h"
static void *real_su_home_ref(su_home_t const *home)
{
if (home) {
su_block_t *sub = MEMLOCK(home);
if (sub == NULL || sub->sub_ref == 0) {
assert(sub && sub->sub_ref != 0);
UNLOCK(home);
return NULL;
}
if (sub->sub_ref != REF_MAX)
sub->sub_ref++;
UNLOCK(home);
}
else
su_seterrno(EFAULT);
return (void *)home;
}
static int real_su_home_unref(su_home_t *home)
{
su_block_t *sub;
if (home == NULL)
return 0;
sub = MEMLOCK(home);
if (sub == NULL) {
/* Xyzzy */
return 0;
}
else if (sub->sub_ref == REF_MAX) {
UNLOCK(home);
return 0;
}
else if (--sub->sub_ref > 0) {
UNLOCK(home);
return 0;
}
else if (sub->sub_parent) {
su_home_t *parent = sub->sub_parent;
UNLOCK(home);
su_free(parent, home);
return 1;
}
else {
int hauto = sub->sub_hauto;
_su_home_deinit(home);
if (!hauto)
safefree(home);
/* UNLOCK(home); */
return 1;
}
}
su_home_t *
_su_home_ref_by(su_home_t *home,
char const *file, unsigned line,
char const *function)
{
if (home)
SU_DEBUG_0(("%ld %p - su_home_ref() => "MOD_ZU" by %s:%u: %s()\n", pthread_self(),
home, su_home_refcount(home) + 1, file, line, function));
return (su_home_t *)real_su_home_ref(home);
}
int
_su_home_unref_by(su_home_t *home,
char const *file, unsigned line,
char const *function)
{
if (home) {
size_t refcount = su_home_refcount(home) - 1;
int freed = real_su_home_unref(home);
if (freed) refcount = 0;
SU_DEBUG_0(("%ld %p - su_home_unref() => "MOD_ZU" by %s:%u: %s()\n", pthread_self(),
home, refcount, file, line, function));
return freed;
}
return 0;
}
#else
/** Create a new reference to a home object. */
void *su_home_ref(su_home_t const *home)
{
if (home) {
su_block_t *sub = MEMLOCK(home);
if (sub == NULL || sub->sub_ref == 0) {
assert(sub && sub->sub_ref != 0);
UNLOCK(home);
return NULL;
}
if (sub->sub_ref != REF_MAX)
sub->sub_ref++;
UNLOCK(home);
}
else
su_seterrno(EFAULT);
return (void *)home;
}
/**Unreference a su_home_t object.
*
* Decrements the reference count on home object and destroys and frees it
@@ -683,6 +778,7 @@ int su_home_unref(su_home_t *home)
return 1;
}
}
#endif
/** Return reference count of home. */
size_t su_home_refcount(su_home_t *home)
@@ -1546,14 +1642,24 @@ int su_home_is_threadsafe(su_home_t const *home)
* Otherwise the su_home_mutex_lock() will just increase the reference
* count.
*/
#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
int _su_home_mutex_lock(su_home_t *home, const char *file, unsigned int line, const char *function)
#else
int su_home_mutex_lock(su_home_t *home)
#endif
{
int error;
if (home == NULL)
return su_seterrno(EFAULT);
#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
if (home->suh_blocks == NULL || !_su_home_ref_by(home, file, line, function))
#else
if (home->suh_blocks == NULL || !su_home_ref(home))
#endif
return su_seterrno(EINVAL); /* Uninitialized home */
if (!home->suh_lock)
@@ -1570,7 +1676,12 @@ int su_home_mutex_lock(su_home_t *home)
*
* @sa su_home_unlock().
*/
#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
int _su_home_mutex_unlock(su_home_t *home, const char *file, unsigned int line, const char *function)
#else
int su_home_mutex_unlock(su_home_t *home)
#endif
{
if (home == NULL)
return su_seterrno(EFAULT);
@@ -1584,7 +1695,11 @@ int su_home_mutex_unlock(su_home_t *home)
if (home->suh_blocks == NULL)
return su_seterrno(EINVAL), -1; /* Uninitialized home */
#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
_su_home_unref_by(home, file, line, function);
#else
su_home_unref(home);
#endif
return 0;
}
@@ -69,6 +69,8 @@ SPAN_DECLARE(SNDFILE *) sf_open_telephony_read(const char *name, int channels);
SPAN_DECLARE(SNDFILE *) sf_open_telephony_write(const char *name, int channels);
SPAN_DECLARE(int) sf_close_telephony(SNDFILE *handle);
#ifdef __cplusplus
}
#endif
+69 -2
View File
@@ -70,6 +70,16 @@ static int circle_init = FALSE;
static complex_t icircle[MAX_FFT_LEN/2];
static int icircle_init = FALSE;
#define SF_MAX_HANDLE 32
static int sf_close_at_exit_registered = FALSE;
static SNDFILE *sf_close_at_exit_list[SF_MAX_HANDLE] =
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
SPAN_DECLARE(complexify_state_t *) complexify_init(void)
{
complexify_state_t *s;
@@ -349,6 +359,42 @@ SPAN_DECLARE(void) codec_munge(codec_munge_state_t *s, int16_t amp[], int len)
}
/*- End of function --------------------------------------------------------*/
static void sf_close_at_exit(void)
{
int i;
for (i = 0; i < SF_MAX_HANDLE; i++)
{
if (sf_close_at_exit_list[i])
{
sf_close(sf_close_at_exit_list[i]);
sf_close_at_exit_list[i] = NULL;
}
}
}
/*- End of function --------------------------------------------------------*/
static int sf_record_handle(SNDFILE *handle)
{
int i;
for (i = 0; i < SF_MAX_HANDLE; i++)
{
if (sf_close_at_exit_list[i] == NULL)
break;
}
if (i >= SF_MAX_HANDLE)
return -1;
sf_close_at_exit_list[i] = handle;
if (!sf_close_at_exit_registered)
{
atexit(sf_close_at_exit);
sf_close_at_exit_registered = TRUE;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(SNDFILE *) sf_open_telephony_read(const char *name, int channels)
{
SNDFILE *handle;
@@ -370,7 +416,7 @@ SPAN_DECLARE(SNDFILE *) sf_open_telephony_read(const char *name, int channels)
printf(" Unexpected number of channels in audio file '%s'\n", name);
exit(2);
}
sf_record_handle(handle);
return handle;
}
/*- End of function --------------------------------------------------------*/
@@ -393,8 +439,29 @@ SPAN_DECLARE(SNDFILE *) sf_open_telephony_write(const char *name, int channels)
fprintf(stderr, " Cannot open audio file '%s' for writing\n", name);
exit(2);
}
sf_record_handle(handle);
return handle;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) sf_close_telephony(SNDFILE *handle)
{
int res;
int i;
if ((res = sf_close(handle)) == 0)
{
for (i = 0; i < SF_MAX_HANDLE; i++)
{
if (sf_close_at_exit_list[i] == handle)
{
sf_close(sf_close_at_exit_list[i]);
sf_close_at_exit_list[i] = NULL;
break;
}
}
}
return res;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
+14
View File
@@ -22,6 +22,7 @@ AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
MAINTAINERCLEANFILES = Makefile.in
DISTCLEANFILES = $(srcdir)/at_interpreter_dictionary.h \
$(srcdir)/math_fixed_tables.h \
$(srcdir)/v17_v32bis_rx_fixed_rrc.h \
$(srcdir)/v17_v32bis_rx_floating_rrc.h \
$(srcdir)/v17_v32bis_tx_fixed_rrc.h \
@@ -55,6 +56,7 @@ EXTRA_DIST = floating_fudge.h \
libtiff.2008.vcproj \
filter_tools.c \
make_at_dictionary.c \
make_math_fixed_tables.c \
make_modem_filter.c \
msvc/config.h \
msvc/Download_TIFF.2005.vcproj \
@@ -123,6 +125,7 @@ libspandsp_la_SOURCES = adsi.c \
lpc10_encode.c \
lpc10_placev.c \
lpc10_voicing.c \
math_fixed.c \
modem_echo.c \
modem_connect_tones.c \
noise.c \
@@ -204,6 +207,7 @@ nobase_include_HEADERS = spandsp/adsi.h \
spandsp/image_translate.h \
spandsp/logging.h \
spandsp/lpc10.h \
spandsp/math_fixed.h \
spandsp/modem_echo.h \
spandsp/modem_connect_tones.h \
spandsp/noise.h \
@@ -329,6 +333,9 @@ 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_math_fixed_tables$(EXEEXT): $(top_srcdir)/src/make_math_fixed_tables.c
$(CC_FOR_BUILD) -o make_math_fixed_tables$(EXEEXT) $(top_srcdir)/src/make_math_fixed_tables.c -DHAVE_CONFIG_H -I$(top_builddir)/src -lm
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
@@ -342,6 +349,13 @@ at_interpreter.lo: at_interpreter_dictionary.h
at_interpreter_dictionary.h: make_at_dictionary$(EXEEXT)
./make_at_dictionary$(EXEEXT) >at_interpreter_dictionary.h
math_fixed.$(OBJEXT): math_fixed_tables.h
math_fixed.lo: math_fixed_tables.h
math_fixed_tables.h: make_math_fixed_tables$(EXEEXT)
./make_math_fixed_tables$(EXEEXT) >math_fixed_tables.h
t4_rx.$(OBJEXT): spandsp/version.h
t4_rx.lo: spandsp/version.h
+6
View File
@@ -69,6 +69,12 @@ SPAN_DECLARE(const char *) signal_status_to_str(int status)
return "Poor signal quality";
case SIG_STATUS_MODEM_RETRAIN_OCCURRED:
return "Modem retrain occurred";
case SIG_STATUS_LINK_CONNECTED:
return "Link connected";
case SIG_STATUS_LINK_DISCONNECTED:
return "Link disconnected";
case SIG_STATUS_LINK_ERROR:
return "Link error";
}
return "???";
}
+2 -2
View File
@@ -5311,7 +5311,7 @@ static const char *at_cmd_plus_WSTL(at_state_t *s, const char *t)
#include "at_interpreter_dictionary.h"
static int command_search(const char *u, int len, int *matched)
static int command_search(const char *u, int *matched)
{
int i;
int index;
@@ -5445,7 +5445,7 @@ SPAN_DECLARE(void) at_interpreter(at_state_t *s, const char *cmd, int len)
t = s->line + 2;
while (t && *t)
{
if ((entry = command_search(t, 15, &matched)) <= 0)
if ((entry = command_search(t, &matched)) <= 0)
break;
if ((t = at_commands[entry - 1](s, t)) == NULL)
break;
+10 -9
View File
@@ -56,7 +56,7 @@
/* This is a simple set of direct digital synthesis (DDS) functions to generate sine
waves. This version uses a 128 entry sin/cos table to cover one quadrant. */
static const int16_t sine_table[DDS_STEPS] =
static const int16_t sine_table[DDS_STEPS + 1] =
{
201,
603,
@@ -186,6 +186,7 @@ static const int16_t sine_table[DDS_STEPS] =
32753,
32762,
32767,
32767
};
SPAN_DECLARE(int32_t) dds_phase_rate(float frequency)
@@ -220,7 +221,7 @@ SPAN_DECLARE(int16_t) dds_lookup(uint32_t phase)
phase >>= DDS_SHIFT;
step = phase & (DDS_STEPS - 1);
if ((phase & DDS_STEPS))
step = (DDS_STEPS - 1) - step;
step = DDS_STEPS - step;
amp = sine_table[step];
if ((phase & (2*DDS_STEPS)))
amp = -amp;
@@ -254,7 +255,7 @@ SPAN_DECLARE(int16_t) dds_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t s
{
int16_t amp;
amp = (int16_t) (((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15);
amp = (int16_t) (((int32_t) dds_lookup(*phase_acc + phase)*scale) >> 15);
*phase_acc += phase_rate;
return amp;
}
@@ -280,8 +281,8 @@ SPAN_DECLARE(complexi_t) dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rat
{
complexi_t amp;
amp = complex_seti(((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*(int32_t) scale) >> 15,
((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15);
amp = complex_seti(((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15,
((int32_t) dds_lookup(*phase_acc + phase)*scale) >> 15);
*phase_acc += phase_rate;
return amp;
}
@@ -307,8 +308,8 @@ SPAN_DECLARE(complexi16_t) dds_complexi16_mod(uint32_t *phase_acc, int32_t phase
{
complexi16_t amp;
amp = complex_seti16((int16_t) (((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*(int32_t) scale) >> 15),
(int16_t) (((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15));
amp = complex_seti16((int16_t) (((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15),
(int16_t) (((int32_t) dds_lookup(*phase_acc + phase)*scale) >> 15));
*phase_acc += phase_rate;
return amp;
}
@@ -334,8 +335,8 @@ SPAN_DECLARE(complexi32_t) dds_complexi32_mod(uint32_t *phase_acc, int32_t phase
{
complexi32_t amp;
amp = complex_seti32(((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*(int32_t) scale) >> 15,
((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15);
amp = complex_seti32(((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15,
((int32_t) dds_lookup(*phase_acc + phase)*scale) >> 15);
*phase_acc += phase_rate;
return amp;
}
+2 -2
View File
@@ -220,7 +220,7 @@ SPAN_DECLARE(void) fsk_tx_set_get_bit(fsk_tx_state_t *s, get_bit_func_t get_bit,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
@@ -248,7 +248,7 @@ SPAN_DECLARE(void) fsk_rx_set_put_bit(fsk_rx_state_t *s, put_bit_func_t put_bit,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
+4 -3
View File
@@ -91,15 +91,16 @@ void gsm0610_preprocess(gsm0610_state_t *s, const int16_t amp[GSM0610_FRAME_LEN]
/* 4.2.1 Downscaling of the input signal */
SO = (amp[k] >> 1) & ~3;
assert(SO >= -0x4000); // downscaled by
assert(SO <= 0x3FFC); // previous routine.
/* This is supposed to have been downscaled by previous routine. */
assert(SO >= -0x4000);
assert(SO <= 0x3FFC);
/* 4.2.2 Offset compensation */
/* This part implements a high-pass filter and requires extended
arithmetic precision for the recursive part of this filter.
The input of this procedure is the array so[0...159] and the
output the array sof[ 0...159 ].
output the array sof[0...159].
*/
/* Compute the non-recursive part */
s1 = SO - z1;
+1 -1
View File
@@ -332,7 +332,7 @@ SPAN_DECLARE(void) hdlc_rx_set_frame_handler(hdlc_rx_state_t *s, hdlc_frame_hand
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) hdlc_rx_set_status_handler(hdlc_rx_state_t *s, modem_rx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) hdlc_rx_set_status_handler(hdlc_rx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
+3 -3
View File
@@ -144,14 +144,14 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t le
int output_length;
int input_width;
int input_length;
int x;
double c1;
double c2;
double int_part;
int x;
#if defined(SPANDSP_USE_FIXED_POINT)
int frac_row;
int frac_col;
#else
double int_part;
double frac_row;
double frac_col;
#endif
@@ -198,7 +198,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t le
x = i*input_width/output_width;
frac_col = x - x*output_width;
c1 = s->raw_pixel_row[0][x] + (s->raw_pixel_row[0][x + 1] - s->raw_pixel_row[0][x])*frac_col;
c1 = s->raw_pixel_row[1][x] + (s->raw_pixel_row[1][x + 1] - s->raw_pixel_row[1][x])*frac_col;
c2 = s->raw_pixel_row[1][x] + (s->raw_pixel_row[1][x + 1] - s->raw_pixel_row[1][x])*frac_col;
buf[i] = saturateu8(c1 + (c2 - c1)*frac_row);
}
#else
+1 -1
View File
@@ -86,7 +86,7 @@ static __inline__ int32_t pow_ii(int32_t x, int32_t n)
if (n == 0 || x == 1)
return 1;
if (x != -1)
return (x == 0) ? 1/x : 0;
return (x != 0) ? 1/x : 0;
n = -n;
}
u = n;
+116
View File
@@ -0,0 +1,116 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* make_fixed_point_math_tables.c - Generate lookup tables for some of the
* fixed point maths functions.
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2010 Steve Underwood
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <memory.h>
#include <math.h>
int main(int argc, char *argv[])
{
int i;
double val;
int ival;
printf("static const uint16_t fixed_reciprocal_table[129] =\n");
printf("{\n");
for (i = 0; i < 129; i++)
{
val = 32768.0*128.0/(128 + i) + 0.5;
ival = val;
if (i < 128)
printf(" %6d,\n", ival);
else
printf(" %6d\n", ival);
}
printf("};\n\n");
printf("static const uint16_t fixed_sqrt_table[193] =\n");
printf("{\n");
for (i = 64; i <= 256; i++)
{
ival = sqrt(i/256.0)*65536.0 + 0.5;
if (ival > 65535)
ival = 65535;
if (i < 256)
printf(" %6d,\n", ival);
else
printf(" %6d\n", ival);
}
printf("};\n\n");
printf("static const int16_t fixed_log10_table[129] =\n");
printf("{\n");
for (i = 128; i <= 256; i++)
{
ival = log10(i/256.0)*32768.0 - 0.5;
if (i <= 255)
printf(" %6d,\n", ival);
else
printf(" %6d\n", ival);
}
printf("};\n\n");
printf("static const int16_t fixed_sine_table[257] =\n");
printf("{\n");
for (i = 0; i <= 256; i++)
{
val = sin(i*3.1415926535/512.0)*32768.0;
ival = val + 0.5;
if (ival > 32767)
ival = 32767;
if (i <= 255)
printf(" %6d,\n", ival);
else
printf(" %6d\n", ival);
}
printf("};\n\n");
printf("static const uint16_t fixed_arctan_table[257] =\n");
printf("{\n");
for (i = 0; i <= 256; i++)
{
val = atan(i/256.0)*65536.0/(2.0*3.1415926535);
ival = val + 0.5;
/* Nudge the result away from zero, so things sit consistently on
the correct side of the axes. */
if (ival == 0)
ival = 1;
if (i <= 255)
printf(" %6d,\n", ival);
else
printf(" %6d\n", ival);
}
printf("};\n\n");
return 0;
}
+255
View File
@@ -0,0 +1,255 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* math_fixed.c
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2010 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.
*/
/*! \file */
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <float.h>
#if defined(HAVE_TGMATH_H)
#include <tgmath.h>
#endif
#if defined(HAVE_MATH_H)
#include <math.h>
#endif
#include "floating_fudge.h"
#include <assert.h>
#include "math_fixed_tables.h"
#include "spandsp/telephony.h"
#include "spandsp/bit_operations.h"
#include "spandsp/math_fixed.h"
#if defined(SPANDSP_USE_FIXED_POINT)
SPAN_DECLARE(uint16_t) sqrtu32_u16(uint32_t x)
{
uint16_t zz;
uint16_t z;
uint16_t i;
z = 0;
for (i = 0x8000; i; i >>= 1)
{
zz = z | i;
if (((int32_t) zz*zz) <= x)
z = zz;
}
return z;
}
/*- End of function --------------------------------------------------------*/
#endif
SPAN_DECLARE(uint16_t) fixed_reciprocal16(uint16_t x, int *shift)
{
if (x == 0)
{
*shift = 0;
return 0xFFFF;
}
*shift = 15 - top_bit(x);
x <<= *shift;
return fixed_reciprocal_table[((x + 0x80) >> 8) - 128];
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(uint16_t) fixed_divide16(uint16_t y, uint16_t x)
{
int shift;
uint32_t z;
uint16_t recip;
if (x == 0)
return 0xFFFF;
recip = fixed_reciprocal16(x, &shift);
z = (((uint32_t) y*recip) >> 15) << shift;
return z;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(uint16_t) fixed_divide32(uint32_t y, uint16_t x)
{
int shift;
uint32_t z;
uint16_t recip;
if (x == 0)
return 0xFFFF;
recip = fixed_reciprocal16(x, &shift);
z = (((uint32_t) y*recip) >> 15) << shift;
return z;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int16_t) fixed_log10_16(uint16_t x)
{
int shift;
if (x == 0)
return 0;
shift = 14 - top_bit(x);
x <<= shift;
return (fixed_log10_table[((x + 0x40) >> 7) - 128] >> 3) - shift*1233;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int32_t) fixed_log10_32(uint32_t x)
{
int shift;
if (x == 0)
return 0;
shift = 30 - top_bit(x);
x <<= shift;
return (fixed_log10_table[((x + 0x400000) >> 23) - 128] >> 3) - shift*1233;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(uint16_t) fixed_sqrt16(uint16_t x)
{
int shift;
if (x == 0)
return 0;
shift = 14 - (top_bit(x) & ~1);
x <<= shift;
//return fixed_sqrt_table[(((x + 0x80) >> 8) & 0xFF) - 64] >> (shift >> 1);
return fixed_sqrt_table[((x >> 8) & 0xFF) - 64] >> (shift >> 1);
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(uint16_t) fixed_sqrt32(uint32_t x)
{
int shift;
if (x == 0)
return 0;
shift = 30 - (top_bit(x) & ~1);
x <<= shift;
//return fixed_sqrt_table[(((x + 0x800000) >> 24) & 0xFF) - 64] >> (shift >> 1);
return fixed_sqrt_table[((x >> 24) & 0xFF) - 64] >> (shift >> 1);
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int16_t) fixed_sin(uint16_t x)
{
int step;
int step_after;
int16_t frac;
int16_t z;
step = (x & 0x3FFF) >> 6;
frac = x & 0x3F;
if ((x & 0x4000))
{
step = 256 - step;
step_after = step - 1;
}
else
{
step_after = step + 1;
}
z = fixed_sine_table[step] + ((frac*(fixed_sine_table[step_after] - fixed_sine_table[step])) >> 6);
if ((x & 0x8000))
z = -z;
return z;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int16_t) fixed_cos(uint16_t x)
{
int step;
int step_after;
int16_t frac;
int16_t z;
x += 0x4000;
step = (x & 0x3FFF) >> 6;
frac = x & 0x3F;
if ((x & 0x4000))
{
step = 256 - step;
step_after = step - 1;
}
else
{
step_after = step + 1;
}
z = fixed_sine_table[step] + ((frac*(fixed_sine_table[step_after] - fixed_sine_table[step])) >> 6);
if ((x & 0x8000))
z = -z;
return z;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(uint16_t) fixed_atan2(int16_t y, int16_t x)
{
int16_t abs_x;
int16_t abs_y;
uint16_t angle;
uint16_t recip;
uint32_t z;
int step;
int shift;
if (y == 0)
return (x & 0x8000);
if (x == 0)
return ((y & 0x8000) | 0x4000);
abs_x = abs(x);
abs_y = abs(y);
if (abs_y < abs_x)
{
recip = fixed_reciprocal16(abs_x, &shift);
z = (((uint32_t) recip*abs_y) >> 15) << shift;
step = z >> 7;
angle = fixed_arctan_table[step];
}
else
{
recip = fixed_reciprocal16(abs_y, &shift);
z = (((uint32_t) recip*abs_x) >> 15) << shift;
step = z >> 7;
angle = 0x4000 - fixed_arctan_table[step];
}
/* If we are in quadrant II or III, flip things around */
if (x < 0)
angle = 0x8000 - angle;
/* If we are in quadrant III or IV, negate to return an
answer in the full circle range. */
if (y < 0)
angle = -angle;
return (uint16_t) angle;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
-2
View File
@@ -165,10 +165,8 @@ SPAN_DECLARE(int) plc_fillin(plc_state_t *s, int16_t amp[], int len)
float old_weight;
float new_weight;
float gain;
//int16_t *orig_amp;
int orig_len;
//orig_amp = amp;
orig_len = len;
if (s->missing_samples == 0)
{
+2 -2
View File
@@ -122,7 +122,7 @@ SPAN_DECLARE(float) power_meter_current_dbm0(power_meter_t *s)
if (s->reading <= 0)
return -96.329f + DBM0_MAX_POWER;
/* This is based on A-law, but u-law is only 0.03dB different, so don't worry. */
return log10f((float) s->reading/(32767.0f*32767.0f))*10.0f + DBM0_MAX_POWER;
return 10.0f*log10f((float) s->reading/(32767.0f*32767.0f) + 1.0e-10f) + DBM0_MAX_POWER;
}
/*- End of function --------------------------------------------------------*/
@@ -130,7 +130,7 @@ SPAN_DECLARE(float) power_meter_current_dbov(power_meter_t *s)
{
if (s->reading <= 0)
return -96.329f;
return log10f((float) s->reading/(32767.0f*32767.0f))*10.0f;
return 10.0f*log10f((float) s->reading/(32767.0f*32767.0f) + 1.0e-10f);
}
/*- End of function --------------------------------------------------------*/
+1 -1
View File
@@ -108,7 +108,7 @@ SPAN_DECLARE(int) silence_gen_generated(silence_gen_state_t *s)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) silence_gen_status_handler(silence_gen_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) silence_gen_status_handler(silence_gen_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
+25 -5
View File
@@ -49,9 +49,19 @@ static __inline__ int32_t arctan2(float y, float x)
float abs_y;
float angle;
if (x == 0.0f || y == 0.0f)
return 0;
if (y == 0.0f)
{
if (x < 0.0f)
return 0x80000000;
return 0x00000000;
}
if (x == 0.0f)
{
if (y < 0.0f)
return 0xc0000000;
return 0x40000000;
}
abs_y = fabsf(y);
/* If we are in quadrant II or III, flip things around */
@@ -77,8 +87,18 @@ static __inline__ float arctan2f(float y, float x)
float fx;
float fy;
if (x == 0.0f || y == 0.0f)
return 0;
if (y == 0.0f)
{
if (x < 0.0f)
return 3.1415926f;
return 0.0f;
}
if (x == 0.0f)
{
if (y < 0.0f)
return 3.1415926f*1.5f;
return 3.1415926f*0.5f;
}
fx = fabsf(x);
fy = fabsf(y);
/* Deal with the octants */
+9 -6
View File
@@ -80,7 +80,13 @@ enum
/*! \brief Notification that a modem has detected signal quality degradation. */
SIG_STATUS_POOR_SIGNAL_QUALITY = -12,
/*! \brief Notification that a modem retrain has occurred. */
SIG_STATUS_MODEM_RETRAIN_OCCURRED = -13
SIG_STATUS_MODEM_RETRAIN_OCCURRED = -13,
/*! \brief The link protocol (e.g. V.42) has connected. */
SIG_STATUS_LINK_CONNECTED = -14,
/*! \brief The link protocol (e.g. V.42) has disconnected. */
SIG_STATUS_LINK_DISCONNECTED = -15,
/*! \brief An error has occurred in the link protocol (e.g. V.42). */
SIG_STATUS_LINK_ERROR = -16
};
/*! Message put function for data pumps */
@@ -101,11 +107,8 @@ typedef void (*put_bit_func_t)(void *user_data, int bit);
/*! Bit get function for data pumps */
typedef int (*get_bit_func_t)(void *user_data);
/*! Completion callback function for tx data pumps */
typedef void (*modem_tx_status_func_t)(void *user_data, int status);
/*! Completion callback function for rx data pumps */
typedef void (*modem_rx_status_func_t)(void *user_data, int status);
/*! Status change callback function for data pumps */
typedef void (*modem_status_func_t)(void *user_data, int status);
enum
{
+1 -1
View File
@@ -225,7 +225,7 @@ SPAN_DECLARE(uint32_t) bit_reverse_4bytes(uint32_t data);
SPAN_DECLARE(uint64_t) bit_reverse_8bytes(uint64_t data);
#endif
/*! \brief Bit reverse each bytes in a buffer.
/*! \brief Bit reverse each byte in a buffer.
\param to The buffer to place the reversed data in.
\param from The buffer containing the data to be reversed.
\param len The length of the data in the buffer. */
+6
View File
@@ -477,6 +477,12 @@ static __inline__ complexi32_t complex_conji32(const complexi32_t *x)
}
/*- End of function --------------------------------------------------------*/
static __inline__ int32_t poweri16(const complexi16_t *x)
{
return (int32_t) x->re*x->re + (int32_t) x->im*x->im;
}
/*- End of function --------------------------------------------------------*/
static __inline__ float powerf(const complexf_t *x)
{
return x->re*x->re + x->im*x->im;
+2
View File
@@ -77,6 +77,8 @@
#include <spandsp/private/t4_t6_encode.h>
/*#include <spandsp/private/t81_t82_arith_coding.h>*/
/*#include <spandsp/private/t85.h>*/
/*#include <spandsp/private/t42.h>*/
/*#include <spandsp/private/t43.h>*/
#include <spandsp/private/t4_rx.h>
#include <spandsp/private/t4_tx.h>
#include <spandsp/private/t30.h>
+2 -2
View File
@@ -175,7 +175,7 @@ SPAN_DECLARE(void) fsk_tx_set_get_bit(fsk_tx_state_t *s, get_bit_func_t get_bit,
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, modem_tx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Generate a block of FSK modem audio samples.
\brief Generate a block of FSK modem audio samples.
@@ -243,7 +243,7 @@ SPAN_DECLARE(void) fsk_rx_set_put_bit(fsk_rx_state_t *s, put_bit_func_t put_bit,
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, modem_rx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, modem_status_func_t handler, void *user_data);
#if defined(__cplusplus)
}
+1 -1
View File
@@ -113,7 +113,7 @@ SPAN_DECLARE(void) hdlc_rx_set_frame_handler(hdlc_rx_state_t *s, hdlc_frame_hand
\param handler The callback routine used to report status changes.
\param user_data An opaque parameter for the callback routine.
*/
SPAN_DECLARE(void) hdlc_rx_set_status_handler(hdlc_rx_state_t *s, modem_rx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) hdlc_rx_set_status_handler(hdlc_rx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Release an HDLC receiver context.
\brief Release an HDLC receiver context.
+83
View File
@@ -0,0 +1,83 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* math_fixed.h
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2010 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.
*/
#if !defined(_MATH_FIXED_H_)
#define _MATH_FIXED_H_
/*! \page math_fixed_page Fixed point math functions
\section math_fixed_page_sec_1 What does it do?
\section math_fixed_page_sec_2 How does it work?
*/
#if defined(__cplusplus)
extern "C"
{
#endif
#if defined(SPANDSP_USE_FIXED_POINT)
SPAN_DECLARE(uint16_t) sqrtu32_u16(uint32_t x);
#endif
SPAN_DECLARE(uint16_t) fixed_reciprocal16(uint16_t x, int *shift);
SPAN_DECLARE(uint16_t) fixed_divide16(uint16_t y, uint16_t x);
SPAN_DECLARE(uint16_t) fixed_divide32(uint32_t y, uint16_t x);
SPAN_DECLARE(int16_t) fixed_log10_16(uint16_t x);
SPAN_DECLARE(int32_t) fixed_log10_32(uint32_t x);
SPAN_DECLARE(uint16_t) fixed_sqrt16(uint16_t x);
SPAN_DECLARE(uint16_t) fixed_sqrt32(uint32_t x);
/*! Evaluate an approximate 16 bit fixed point sine.
\brief Evaluate an approximate 16 bit fixed point sine.
\param x A 16 bit unsigned angle, in 360/65536 degree steps.
\return sin(x)*32767. */
SPAN_DECLARE(int16_t) fixed_sin(uint16_t x);
/*! Evaluate an approximate 16 bit fixed point cosine.
\brief Evaluate an approximate 16 bit fixed point cosine.
\param x A 16 bit unsigned angle, in 360/65536 degree steps.
\return cos(x)*32767. */
SPAN_DECLARE(int16_t) fixed_cos(uint16_t x);
/*! Evaluate an approximate 16 bit fixed point sine.
\brief Evaluate an approximate 16 bit fixed point sine.
\param y .
\param x .
\return The 16 bit unsigned angle, in 360/65536 degree steps. */
SPAN_DECLARE(uint16_t) fixed_atan2(int16_t y, int16_t x);
#if defined(__cplusplus)
}
#endif
#endif
/*- End of file ------------------------------------------------------------*/
+2 -2
View File
@@ -39,7 +39,7 @@ struct fsk_tx_state_s
void *get_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_tx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
@@ -66,7 +66,7 @@ struct fsk_rx_state_s
void *put_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_tx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
+1 -1
View File
@@ -40,7 +40,7 @@ struct hdlc_rx_state_s
/*! \brief An opaque parameter passed to the frame callback routine. */
void *frame_user_data;
/*! \brief The callback routine called to report status changes. */
modem_rx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief An opaque parameter passed to the status callback routine. */
void *status_user_data;
/*! \brief TRUE if bad frames are to be reported. */
@@ -29,7 +29,7 @@
struct silence_gen_state_s
{
/*! \brief The callback function used to report status changes. */
modem_tx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
@@ -66,7 +66,7 @@
#define T30_DCS_BIT_200_200 15
#define T30_DIS_BIT_2D_CAPABLE 16
#define T30_DCS_BIT_2D_CODING 16
#define T30_DCS_BIT_2D_MODE 16
/* Standard facsimile terminals conforming to ITU-T Rec. T.4 must have the following capability:
Paper length = 297 mm. */
@@ -101,7 +101,7 @@
#define T30_DIS_BIT_POLLED_SUBADDRESSING_CAPABLE 35
#define T30_DIS_BIT_T43_CAPABLE 36
#define T30_DCS_BIT_T43_CODING 36
#define T30_DCS_BIT_T43_MODE 36
#define T30_DIS_BIT_PLANE_INTERLEAVE_CAPABLE 37
#define T30_DCS_BIT_PLANE_INTERLEAVE 37
@@ -270,11 +270,11 @@
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"
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"
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
+4
View File
@@ -42,6 +42,10 @@ struct t4_state_s
/*! \brief The time at which handling of the current page began. */
time_t page_start_time;
/*! \brief TRUE for FAX page headers to overlay (i.e. replace) the beginning of the
page image. FALSE for FAX page headers to add to the overall length of
the page. */
int header_overlays_image;
/*! \brief The text which will be used in FAX page header. No text results
in no header line. */
const char *header_info;
+2 -2
View File
@@ -61,7 +61,7 @@ struct v17_rx_state_s
void *put_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_rx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
@@ -86,7 +86,7 @@ struct v17_rx_state_s
/*! \brief The register for the data scrambler. */
uint32_t scramble_reg;
/*! \brief Scrambler tap */
//int scrambler_tap;
int scrambler_tap;
/*! \brief TRUE if the short training sequence is to be used. */
int short_train;
+8 -4
View File
@@ -45,7 +45,7 @@ struct v17_tx_state_s
void *get_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_tx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
@@ -58,9 +58,13 @@ struct v17_tx_state_s
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
#if defined(SPANDSP_USE_FIXED_POINT)
complexi16_t rrc_filter[2*V17_TX_FILTER_STEPS];
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
int16_t rrc_filter_re[V17_TX_FILTER_STEPS];
int16_t rrc_filter_im[V17_TX_FILTER_STEPS];
#else
complexf_t rrc_filter[2*V17_TX_FILTER_STEPS];
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
float rrc_filter_re[V17_TX_FILTER_STEPS];
float rrc_filter_im[V17_TX_FILTER_STEPS];
#endif
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
int rrc_filter_step;
@@ -75,7 +79,7 @@ struct v17_tx_state_s
/*! \brief The register for the data scrambler. */
uint32_t scramble_reg;
/*! \brief Scrambler tap */
//int scrambler_tap;
int scrambler_tap;
/*! \brief TRUE if transmitting the training sequence. FALSE if transmitting user data. */
int in_training;
/*! \brief TRUE if the short training sequence is to be used. */
+1 -1
View File
@@ -84,7 +84,7 @@ struct v22bis_state_s
/*! \brief A user specified opaque pointer passed to the put_bit callback routine. */
void *put_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_rx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
+1 -1
View File
@@ -58,7 +58,7 @@ struct v27ter_rx_state_s
void *put_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_rx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
+1 -1
View File
@@ -43,7 +43,7 @@ struct v27ter_tx_state_s
void *get_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_tx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
+1 -1
View File
@@ -50,7 +50,7 @@ struct v29_rx_state_s
void *put_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_rx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
+2 -2
View File
@@ -43,7 +43,7 @@ struct v29_tx_state_s
void *get_bit_user_data;
/*! \brief The callback function used to report modem status changes. */
modem_tx_status_func_t status_handler;
modem_status_func_t status_handler;
/*! \brief A user specified opaque pointer passed to the status function. */
void *status_user_data;
@@ -68,7 +68,7 @@ struct v29_tx_state_s
int rrc_filter_step;
/*! \brief The register for the data scrambler. */
unsigned int scramble_reg;
uint32_t scramble_reg;
/*! \brief The register for the training scrambler. */
uint8_t training_scramble_reg;
/*! \brief TRUE if transmitting the training sequence, or shutting down transmission.
+99 -61
View File
@@ -5,7 +5,7 @@
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2003 Steve Underwood
* Copyright (C) 2003, 2011 Steve Underwood
*
* All rights reserved.
*
@@ -26,75 +26,94 @@
#if !defined(_SPANDSP_PRIVATE_V42_H_)
#define _SPANDSP_PRIVATE_V42_H_
/*! Max retries (9.2.2) */
#define V42_DEFAULT_N_400 5
/*! Default for max octets in an information field (9.2.3) */
#define V42_DEFAULT_N_401 128
/*! Maximum supported value for max octets in an information field */
#define V42_MAX_N_401 128
/*! Default window size (k) (9.2.4) */
#define V42_DEFAULT_WINDOW_SIZE_K 15
/*! Maximum supported window size (k) */
#define V42_MAX_WINDOW_SIZE_K 15
/*! The number of info frames to allocate */
#define V42_INFO_FRAMES (V42_MAX_WINDOW_SIZE_K + 1)
/*! The number of control frames to allocate */
#define V42_CTRL_FRAMES 8
typedef struct
{
/* V.42 LAP.M parameters */
uint8_t v42_tx_window_size_k;
uint8_t v42_rx_window_size_k;
uint16_t v42_tx_n401;
uint16_t v42_rx_n401;
/* V.42bis compressor parameters */
uint8_t comp;
int comp_dict_size;
int comp_max_string;
} v42_config_parameters_t;
typedef struct frame_s
{
int len;
uint8_t buf[4 + V42_MAX_N_401];
} v42_frame_t;
/*!
LAP-M descriptor. This defines the working state for a single instance of LAP-M.
*/
struct lapm_state_s
typedef struct
{
int handle;
get_msg_func_t iframe_get;
void *iframe_get_user_data;
put_msg_func_t iframe_put;
void *iframe_put_user_data;
modem_status_func_t status_handler;
void *status_user_data;
hdlc_rx_state_t hdlc_rx;
hdlc_tx_state_t hdlc_tx;
v42_frame_handler_t iframe_receive;
void *iframe_receive_user_data;
v42_status_func_t status_callback;
void *status_callback_user_data;
/*! Negotiated values for the window and maximum info sizes */
uint8_t tx_window_size_k;
uint8_t rx_window_size_k;
uint16_t tx_n401;
uint16_t rx_n401;
uint8_t cmd_addr;
uint8_t rsp_addr;
uint8_t vs;
uint8_t va;
uint8_t vr;
int state;
int tx_waiting;
int debug;
/*! TRUE if originator. FALSE if answerer */
int we_are_originator;
/*! Remote network type (unknown, answerer. originator) */
int peer_is_originator;
/*! Next N(S) for transmission */
int next_tx_frame;
/*! The last of our frames which the peer acknowledged */
int last_frame_peer_acknowledged;
/*! Next N(R) for reception */
int next_expected_frame;
/*! The last of the peer's frames which we acknowledged */
int last_frame_we_acknowledged;
/*! TRUE if we sent an I or S frame with the F-bit set */
int solicit_f_bit;
/*! Retransmission count */
int retransmissions;
/*! TRUE if peer is busy */
int busy;
int configuring;
int local_busy;
int far_busy;
int rejected;
int retry_count;
/*! Acknowledgement timer */
int t401_timer;
/*! Reply delay timer - optional */
int t402_timer;
/*! Inactivity timer - optional */
int t403_timer;
/*! Maximum number of octets in an information field */
int n401;
/*! Window size */
int window_size_k;
lapm_frame_queue_t *txqueue;
lapm_frame_queue_t *tx_next;
lapm_frame_queue_t *tx_last;
queue_state_t *tx_queue;
span_sched_state_t sched;
/*! \brief Error and flow logging control */
logging_state_t logging;
};
/* The control frame buffer, and its pointers */
int ctrl_put;
int ctrl_get;
v42_frame_t ctrl_buf[V42_CTRL_FRAMES];
/*!
V.42 descriptor. This defines the working state for a single instance of V.42.
*/
struct v42_state_s
/* The info frame buffer, and its pointers */
int info_put;
int info_get;
int info_acked;
v42_frame_t info_buf[V42_INFO_FRAMES];
void (*packer_process)(v42_state_t *m, int bits);
} lapm_state_t;
/*! V.42 support negotiation parameters */
typedef struct
{
/*! TRUE if we are the calling party, otherwise FALSE */
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;
/*! Stage in negotiating V.42 support */
int rx_negotiation_step;
int rxbits;
@@ -104,11 +123,30 @@ struct v42_state_s
int txbits;
int txstream;
int txadps;
/*! The LAP.M context */
} v42_negotiation_t;
/*!
V.42 descriptor. This defines the working state for a single
instance of a V.42 error corrector.
*/
struct v42_state_s
{
/*! TRUE if we are the calling party, otherwise FALSE. */
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;
/*! The bit rate, used to time events */
int tx_bit_rate;
v42_config_parameters_t config;
v42_negotiation_t neg;
lapm_state_t lapm;
/*! V.42 support detection timer */
int t400_timer;
int bit_timer;
void (*bit_timer_func)(v42_state_t *m);
/*! \brief Error and flow logging control */
logging_state_t logging;
};
+65 -87
View File
@@ -28,100 +28,85 @@
/*!
V.42bis dictionary node.
Note that 0 is not a valid node to point to (0 is always a control code), so 0 is used
as a "no such value" marker in this structure.
*/
typedef struct
{
/*! \brief The prior code for each defined code. */
uint16_t parent_code;
/*! \brief The number of leaf nodes this node has */
int16_t leaves;
/*! \brief This leaf octet for each defined code. */
/*! \brief The value of the octet represented by the current dictionary node */
uint8_t node_octet;
/*! \brief Bit map of the children which exist */
uint32_t children[8];
/*! \brief The parent of this node */
uint16_t parent;
/*! \brief The first child of this node */
uint16_t child;
/*! \brief The next node at the same depth */
uint16_t next;
} v42bis_dict_node_t;
/*!
V.42bis compression. This defines the working state for a single instance
of V.42bis compression.
V.42bis compression or decompression. This defines the working state for a single instance
of V.42bis compression or decompression.
*/
typedef struct
{
/*! \brief Compression enabled. */
int v42bis_parm_p0;
/*! \brief Compression mode. */
int compression_mode;
/*! \brief Callback function to handle received frames. */
v42bis_frame_handler_t handler;
/*! \brief An opaque pointer passed in calls to frame_handler. */
/*! \brief Callback function to handle output data. */
put_msg_func_t handler;
/*! \brief An opaque pointer passed in calls to the data handler. */
void *user_data;
/*! \brief The maximum frame length allowed */
int max_len;
/*! \brief The maximum amount to be passed to the data handler. */
int max_output_len;
uint32_t string_code;
uint32_t latest_code;
/*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */
int transparent;
/*! \brief Next empty dictionary entry */
uint16_t v42bis_parm_c1;
/*! \brief Current codeword size */
uint16_t v42bis_parm_c2;
/*! \brief Threshold for codeword size change */
uint16_t v42bis_parm_c3;
/*! \brief The current update point in the dictionary */
uint16_t update_at;
/*! \brief The last entry matched in the dictionary */
uint16_t last_matched;
/*! \brief The last entry added to the dictionary */
uint16_t last_added;
/*! \brief Total number of codewords in the dictionary */
int v42bis_parm_n2;
/*! \brief Maximum permitted string length */
int v42bis_parm_n7;
/*! \brief The dictionary */
v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS];
/*! \brief The octet string in progress */
uint8_t string[V42BIS_MAX_STRING_SIZE];
/*! \brief The current length of the octet string in progress */
int string_length;
uint32_t output_bit_buffer;
int output_bit_count;
/*! \brief The amount of the octet string in progress which has already
been flushed out of the buffer */
int flushed_length;
/*! \brief Compression performance metric */
uint16_t compression_performance;
/*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */
uint32_t bit_buffer;
/*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */
int bit_count;
/*! \brief The output composition buffer */
uint8_t output_buf[V42BIS_MAX_OUTPUT_LENGTH];
/*! \brief The length of the contents of the output composition buffer */
int output_octet_count;
uint8_t output_buf[1024];
v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS];
/*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */
int transparent;
int change_transparency;
/*! \brief IIR filter state, used in assessing compressibility. */
int compressibility_filter;
int compressibility_persistence;
/*! \brief Next empty dictionary entry */
uint32_t v42bis_parm_c1;
/*! \brief Current codeword size */
int v42bis_parm_c2;
/*! \brief Threshold for codeword size change */
uint32_t v42bis_parm_c3;
/*! \brief Mark that this is the first octet/code to be processed */
int first;
uint8_t escape_code;
} v42bis_compress_state_t;
/*!
V.42bis decompression. This defines the working state for a single instance
of V.42bis decompression.
*/
typedef struct
{
/*! \brief Callback function to handle decompressed data. */
v42bis_data_handler_t handler;
/*! \brief An opaque pointer passed in calls to data_handler. */
void *user_data;
/*! \brief The maximum decompressed data block length allowed */
int max_len;
uint32_t old_code;
uint32_t last_old_code;
uint32_t input_bit_buffer;
int input_bit_count;
int octet;
int last_length;
int output_octet_count;
uint8_t output_buf[1024];
v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS];
/*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */
int transparent;
int last_extra_octet;
/*! \brief Next empty dictionary entry */
uint32_t v42bis_parm_c1;
/*! \brief Current codeword size */
int v42bis_parm_c2;
/*! \brief Threshold for codeword size change */
uint32_t v42bis_parm_c3;
/*! \brief Mark that this is the first octet/code to be processed */
int first;
/*! \brief The current value of the escape code */
uint8_t escape_code;
/*! \brief TRUE if we just hit an escape code, and are waiting for the following octet */
int escaped;
} v42bis_decompress_state_t;
} v42bis_comp_state_t;
/*!
V.42bis compression/decompression descriptor. This defines the working state for a
@@ -129,20 +114,13 @@ typedef struct
*/
struct v42bis_state_s
{
/*! \brief V.42bis data compression directions. */
int v42bis_parm_p0;
/*! \brief Compression state. */
v42bis_compress_state_t compress;
v42bis_comp_state_t compress;
/*! \brief Decompression state. */
v42bis_decompress_state_t decompress;
/*! \brief Maximum codeword size (bits) */
int v42bis_parm_n1;
/*! \brief Total number of codewords */
uint32_t v42bis_parm_n2;
/*! \brief Maximum string length */
int v42bis_parm_n7;
v42bis_comp_state_t decompress;
/*! \brief Error and flow logging control */
logging_state_t logging;
};
#endif
+1 -1
View File
@@ -84,7 +84,7 @@ SPAN_DECLARE(int) silence_gen_generated(silence_gen_state_t *s);
\param s The silence generator context.
\param handler The callback routine used to report status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) silence_gen_status_handler(silence_gen_state_t *s, modem_tx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) silence_gen_status_handler(silence_gen_state_t *s, modem_status_func_t handler, void *user_data);
/*! Initialise a timed silence generator context.
\brief Initialise a timed silence generator context.
+1 -3
View File
@@ -261,7 +261,7 @@ enum
T30_ERR_RX_GOTDCS, /*! DCS received while waiting for DTC */
T30_ERR_RX_INVALCMD, /*! Unexpected command after page received */
T30_ERR_RX_NOCARRIER, /*! Carrier lost during fax receive */
T30_ERR_RX_NOEOL, /*! Timed out while waiting for EOL (end Of line) */
T30_ERR_RX_NOEOL, /*! Timed out while waiting for EOL (end of line) */
T30_ERR_RX_NOFAX, /*! Timed out while waiting for first line */
T30_ERR_RX_T2EXPDCN, /*! Timer T2 expired while waiting for DCN */
T30_ERR_RX_T2EXPD, /*! Timer T2 expired while waiting for phase D */
@@ -547,12 +547,10 @@ typedef struct
int error_correcting_mode_retries;
/*! \brief Current status. */
int current_status;
#if 0
/*! \brief The number of RTP events in this call. */
int rtp_events;
/*! \brief The number of RTN events in this call. */
int rtn_events;
#endif
} t30_stats_t;
#if defined(__cplusplus)
+6
View File
@@ -144,6 +144,12 @@ SPAN_DECLARE(void) t4_tx_set_header_info(t4_state_t *s, const char *info);
\param info A POSIX timezone description string. */
SPAN_DECLARE(void) t4_tx_set_header_tz(t4_state_t *s, const char *tzstring);
/*! Set page header extends or overlays the image mode.
\brief Set page header overlay mode.
\param s The T.4 context.
\param header_overlays_image TRUE for overlay, or FALSE for extend the page. */
SPAN_DECLARE(void) t4_tx_set_header_overlays_image(t4_state_t *s, int header_overlays_image);
/*! \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.
+21
View File
@@ -77,6 +77,27 @@ typedef int (span_tx_handler_t)(void *s, int16_t amp[], int max_len);
#define TRUE (!FALSE)
#endif
/* Fixed point constant macros */
#define FP_Q_9_7(x) ((int16_t) (128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_8_8(x) ((int16_t) (256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_7_9(x) ((int16_t) (512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_6_10(x) ((int16_t) (1024.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_5_11(x) ((int16_t) (2048.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_4_12(x) ((int16_t) (4096.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_3_13(x) ((int16_t) (8192.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_2_14(x) ((int16_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_1_15(x) ((int16_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_9_23(x) ((int32_t) (65536.0*128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_8_24(x) ((int32_t) (65536.0*256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_7_25(x) ((int32_t) (65536.0*512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_6_26(x) ((int32_t) (65536.0*1024.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_5_27(x) ((int32_t) (65536.0*2048.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_4_28(x) ((int32_t) (65536.0*4096.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_3_29(x) ((int32_t) (65536.0*8192.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_2_30(x) ((int32_t) (65536.0*16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_1_31(x) ((int32_t) (65536.0*32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#if defined(__cplusplus)
/* C++ doesn't seem to have sane rounding functions/macros yet */
#if !defined(WIN32)
+1 -1
View File
@@ -267,7 +267,7 @@ SPAN_DECLARE(void) v17_rx_set_put_bit(v17_rx_state_t *s, put_bit_func_t put_bit,
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) v17_rx_set_modem_status_handler(v17_rx_state_t *s, modem_rx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) v17_rx_set_modem_status_handler(v17_rx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Process a block of received V.17 modem audio samples.
\brief Process a block of received V.17 modem audio samples.
+1 -1
View File
@@ -146,7 +146,7 @@ SPAN_DECLARE(void) v17_tx_set_get_bit(v17_tx_state_t *s, get_bit_func_t get_bit,
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) v17_tx_set_modem_status_handler(v17_tx_state_t *s, modem_tx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) v17_tx_set_modem_status_handler(v17_tx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Generate a block of V.17 modem audio samples.
\brief Generate a block of V.17 modem audio samples.
+1 -1
View File
@@ -213,7 +213,7 @@ SPAN_DECLARE(void) v22bis_set_put_bit(v22bis_state_t *s, put_bit_func_t put_bit,
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) v22bis_set_modem_status_handler(v22bis_state_t *s, modem_rx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) v22bis_set_modem_status_handler(v22bis_state_t *s, modem_status_func_t handler, void *user_data);
#if defined(__cplusplus)
}
+1 -1
View File
@@ -102,7 +102,7 @@ SPAN_DECLARE(void) v27ter_rx_set_put_bit(v27ter_rx_state_t *s, put_bit_func_t pu
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) v27ter_rx_set_modem_status_handler(v27ter_rx_state_t *s, modem_rx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) v27ter_rx_set_modem_status_handler(v27ter_rx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Process a block of received V.27ter modem audio samples.
\brief Process a block of received V.27ter modem audio samples.
+1 -1
View File
@@ -127,7 +127,7 @@ SPAN_DECLARE(void) v27ter_tx_set_get_bit(v27ter_tx_state_t *s, get_bit_func_t ge
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) v27ter_tx_set_modem_status_handler(v27ter_tx_state_t *s, modem_tx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) v27ter_tx_set_modem_status_handler(v27ter_tx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Generate a block of V.27ter modem audio samples.
\brief Generate a block of V.27ter modem audio samples.
+1 -1
View File
@@ -178,7 +178,7 @@ SPAN_DECLARE(void) v29_rx_set_put_bit(v29_rx_state_t *s, put_bit_func_t put_bit,
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) v29_rx_set_modem_status_handler(v29_rx_state_t *s, modem_rx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) v29_rx_set_modem_status_handler(v29_rx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Process a block of received V.29 modem audio samples.
\brief Process a block of received V.29 modem audio samples.
+1 -1
View File
@@ -158,7 +158,7 @@ SPAN_DECLARE(void) v29_tx_set_get_bit(v29_tx_state_t *s, get_bit_func_t get_bit,
\param s The modem context.
\param handler The callback routine used to report modem status changes.
\param user_data An opaque pointer. */
SPAN_DECLARE(void) v29_tx_set_modem_status_handler(v29_tx_state_t *s, modem_tx_status_func_t handler, void *user_data);
SPAN_DECLARE(void) v29_tx_set_modem_status_handler(v29_tx_state_t *s, modem_status_func_t handler, void *user_data);
/*! Generate a block of V.29 modem audio samples.
\brief Generate a block of V.29 modem audio samples.
+27 -76
View File
@@ -5,7 +5,7 @@
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2003 Steve Underwood
* Copyright (C) 2003, 2011 Steve Underwood
*
* All rights reserved.
*
@@ -36,45 +36,8 @@ far modem supports V.42 is also defined.
#if !defined(_SPANDSP_V42_H_)
#define _SPANDSP_V42_H_
enum
{
LAPM_DETECT = 0,
LAPM_ESTABLISH = 1,
LAPM_DATA = 2,
LAPM_RELEASE = 3,
LAPM_SIGNAL = 4,
LAPM_SETPARM = 5,
LAPM_TEST = 6,
LAPM_UNSUPPORTED = 7
};
typedef void (*v42_status_func_t)(void *user_data, int status);
typedef void (*v42_frame_handler_t)(void *user_data, const uint8_t *pkt, int len);
typedef struct lapm_frame_queue_s
{
struct lapm_frame_queue_s *next;
int len;
uint8_t frame[];
} lapm_frame_queue_t;
/*!
LAP-M descriptor. This defines the working state for a single instance of LAP-M.
*/
typedef struct lapm_state_s lapm_state_t;
/*!
V.42 descriptor. This defines the working state for a single instance of V.42.
*/
typedef struct v42_state_s v42_state_t;
/*! Log the raw HDLC frames */
#define LAPM_DEBUG_LAPM_RAW (1 << 0)
/*! Log the interpreted frames */
#define LAPM_DEBUG_LAPM_DUMP (1 << 1)
/*! Log state machine changes */
#define LAPM_DEBUG_LAPM_STATE (1 << 2)
#if defined(__cplusplus)
extern "C"
{
@@ -82,58 +45,46 @@ extern "C"
SPAN_DECLARE(const char *) lapm_status_to_str(int status);
/*! Dump LAP.M frames in a raw and/or decoded forms
\param frame The frame itself
\param len The length of the frame, in octets
\param showraw TRUE if the raw octets should be dumped
\param txrx TRUE if tx, FALSE if rx. Used to highlight the packet's direction.
*/
SPAN_DECLARE(void) lapm_dump(lapm_state_t *s, const uint8_t *frame, int len, int showraw, int txrx);
SPAN_DECLARE_NONSTD(void) lapm_receive(void *user_data, const uint8_t *frame, int len, int ok);
/*! Accept an HDLC packet
*/
SPAN_DECLARE_NONSTD(void) lapm_receive(void *user_data, const uint8_t *buf, int len, int ok);
SPAN_DECLARE(void) v42_start(v42_state_t *s);
/*! Transmit a LAP.M frame
*/
SPAN_DECLARE(int) lapm_tx(lapm_state_t *s, const void *buf, int len);
SPAN_DECLARE(void) v42_stop(v42_state_t *s);
/*! Transmit a LAP.M information frame
/*! Set the busy status of the local end of a V.42 context.
\param s The V.42 context.
\param busy The new local end busy status.
\return The previous local end busy status.
*/
SPAN_DECLARE(int) lapm_tx_iframe(lapm_state_t *s, const void *buf, int len, int cr);
SPAN_DECLARE(int) v42_set_local_busy_status(v42_state_t *s, int busy);
/*! Send a break over a LAP.M connection
/*! Get the busy status of the far end of a V.42 context.
\param s The V.42 context.
\return The far end busy status.
*/
SPAN_DECLARE(int) lapm_break(lapm_state_t *s, int enable);
SPAN_DECLARE(int) v42_get_far_busy_status(v42_state_t *s);
/*! Initiate an orderly release of a LAP.M connection
*/
SPAN_DECLARE(int) lapm_release(lapm_state_t *s);
/*! Enable or disable loopback of a LAP.M connection
*/
SPAN_DECLARE(int) lapm_loopback(lapm_state_t *s, int enable);
/*! Assign or remove a callback routine used to deal with V.42 status changes.
*/
SPAN_DECLARE(void) v42_set_status_callback(v42_state_t *s, v42_status_func_t callback, void *user_data);
/*! Process a newly received bit for a V.42 context.
*/
SPAN_DECLARE(void) v42_rx_bit(void *user_data, int bit);
/*! Get the next transmit bit for a V.42 context.
*/
SPAN_DECLARE(int) v42_tx_bit(void *user_data);
SPAN_DECLARE(void) v42_set_status_callback(v42_state_t *s, modem_status_func_t callback, void *user_data);
/*! Initialise a V.42 context.
\param s The V.42 context.
\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.
\param detect TRUE to perform the V.42 detection, else go straight into LAP.M
\param iframe_get A callback function to handle received frames of data.
\param iframe_put A callback function to get frames of data for transmission.
\param user_data An opaque pointer passed to the frame handler routines.
\return ???
*/
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);
SPAN_DECLARE(v42_state_t *) v42_init(v42_state_t *s,
int calling_party,
int detect,
get_msg_func_t iframe_get,
put_msg_func_t iframe_put,
void *user_data);
/*! Restart a V.42 context.
\param s The V.42 context.
@@ -143,12 +94,12 @@ SPAN_DECLARE(void) v42_restart(v42_state_t *s);
/*! Release a V.42 context.
\param s The V.42 context.
\return 0 if OK */
SPAN_DECLARE(int) v42_release(v42_state_t *s);
SPAN_DECLARE(void) v42_release(v42_state_t *s);
/*! Free a V.42 context.
\param s The V.42 context.
\return 0 if OK */
SPAN_DECLARE(int) v42_free(v42_state_t *s);
SPAN_DECLARE(void) v42_free(v42_state_t *s);
#if defined(__cplusplus)
}
+16 -19
View File
@@ -5,7 +5,7 @@
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2005 Steve Underwood
* Copyright (C) 2005, 2011 Steve Underwood
*
* All rights reserved.
*
@@ -39,7 +39,7 @@ conjunction with the error correction scheme defined in V.42.
#define V42BIS_MIN_DICTIONARY_SIZE 512
#define V42BIS_MAX_BITS 12
#define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */
#define V42BIS_TABLE_SIZE 5021 /* This should be a prime >(2^V42BIS_MAX_BITS) */
#define V42BIS_MAX_OUTPUT_LENGTH 1024
enum
{
@@ -56,9 +56,6 @@ enum
V42BIS_COMPRESSION_MODE_NEVER
};
typedef void (*v42bis_frame_handler_t)(void *user_data, const uint8_t *pkt, int len);
typedef void (*v42bis_data_handler_t)(void *user_data, const uint8_t *buf, int len);
/*!
V.42bis compression/decompression descriptor. This defines the working state for a
single instance of V.42bis compress/decompression.
@@ -75,7 +72,7 @@ extern "C"
\param buf The data to be compressed.
\param len The length of the data buffer.
\return 0 */
SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *s, const uint8_t *buf, int len);
SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *s, const uint8_t buf[], int len);
/*! Flush out any data remaining in a compression buffer.
\param s The V.42bis context.
@@ -87,7 +84,7 @@ SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *s);
\param buf The data to be decompressed.
\param len The length of the data buffer.
\return 0 */
SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t *buf, int len);
SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t buf[], int len);
/*! Flush out any data remaining in the decompression buffer.
\param s The V.42bis context.
@@ -107,23 +104,23 @@ SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode);
\param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec.
\param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec.
\param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec.
\param frame_handler Frame callback handler.
\param frame_user_data An opaque pointer passed to the frame callback handler.
\param max_frame_len The maximum length that should be passed to the frame handler.
\param data_handler data callback handler.
\param data_user_data An opaque pointer passed to the data callback handler.
\param max_data_len The maximum length that should be passed to the data handler.
\param encode_handler Encode callback handler.
\param encode_user_data An opaque pointer passed to the encode callback handler.
\param max_encode_len The maximum length that should be passed to the encode handler.
\param decode_handler Decode callback handler.
\param decode_user_data An opaque pointer passed to the decode callback handler.
\param max_decode_len The maximum length that should be passed to the decode handler.
\return The V.42bis context. */
SPAN_DECLARE(v42bis_state_t *) v42bis_init(v42bis_state_t *s,
int negotiated_p0,
int negotiated_p1,
int negotiated_p2,
v42bis_frame_handler_t frame_handler,
void *frame_user_data,
int max_frame_len,
v42bis_data_handler_t data_handler,
void *data_user_data,
int max_data_len);
put_msg_func_t encode_handler,
void *encode_user_data,
int max_encode_len,
put_msg_func_t decode_handler,
void *decode_user_data,
int max_decode_len);
/*! Release a V.42bis context.
\param s The V.42bis context.
+106 -8
View File
@@ -60,10 +60,18 @@
#include "spandsp/v27ter_tx.h"
#include "spandsp/t4_rx.h"
#include "spandsp/t4_tx.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/t43.h"
#endif
#include "spandsp/t4_t6_decode.h"
#include "spandsp/t4_t6_encode.h"
#include "spandsp/t30_fcf.h"
@@ -73,10 +81,18 @@
#include "spandsp/t30_logging.h"
#include "spandsp/private/logging.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/private/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/private/t43.h"
#endif
#include "spandsp/private/t4_t6_decode.h"
#include "spandsp/private/t4_t6_encode.h"
#include "spandsp/private/t4_rx.h"
@@ -387,6 +403,7 @@ static void repeat_last_command(t30_state_t *s);
static void disconnect(t30_state_t *s);
static void decode_20digit_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt, int len);
static int set_min_scan_time_code(t30_state_t *s);
static int send_cfr_sequence(t30_state_t *s, int start);
static void timer_t2_start(t30_state_t *s);
@@ -1312,6 +1329,19 @@ static int build_dcs(t30_state_t *s)
/* Select the compression to use. */
switch (s->line_encoding)
{
#if defined(SPANDSP_SUPPORT_T42)
case T4_COMPRESSION_ITU_T42:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE);
set_ctrl_bits(s->dcs_frame, T30_MIN_SCAN_0MS, 21);
break;
#endif
#if defined(SPANDSP_SUPPORT_T43)
case T4_COMPRESSION_ITU_T43:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_T43_MODE);
set_ctrl_bits(s->dcs_frame, T30_MIN_SCAN_0MS, 21);
break;
#endif
#if defined(SPANDSP_SUPPORT_T85)
case T4_COMPRESSION_ITU_T85:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_T85_MODE);
clr_ctrl_bit(s->dcs_frame, T30_DCS_BIT_T85_L0_MODE);
@@ -1322,12 +1352,13 @@ static int build_dcs(t30_state_t *s)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_T85_L0_MODE);
set_ctrl_bits(s->dcs_frame, T30_MIN_SCAN_0MS, 21);
break;
#endif
case T4_COMPRESSION_ITU_T6:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_T6_MODE);
set_ctrl_bits(s->dcs_frame, T30_MIN_SCAN_0MS, 21);
break;
case T4_COMPRESSION_ITU_T4_2D:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_2D_CODING);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_2D_MODE);
set_ctrl_bits(s->dcs_frame, s->min_scan_time_code, 21);
break;
case T4_COMPRESSION_ITU_T4_1D:
@@ -1515,7 +1546,7 @@ static int build_dcs(t30_state_t *s)
if (bad != T30_ERR_OK)
{
s->current_status = bad;
span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not an acceptable FAX image width\n", s->image_width);
span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) is not an acceptable FAX image width\n", s->image_width);
return -1;
}
switch (s->image_width)
@@ -1557,7 +1588,7 @@ static int build_dcs(t30_state_t *s)
if (bad != T30_ERR_OK)
{
s->current_status = bad;
span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) not an acceptable FAX image width\n", s->image_width);
span_log(&s->logging, SPAN_LOG_FLOW, "Image width (%d pixels) is not an acceptable FAX image width\n", s->image_width);
return -1;
}
/* Deal with the image length */
@@ -2132,6 +2163,60 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
return -1;
}
}
#if 0
/* T.4 1D is always available */
bi_level_support = T30_SUPPORT_T4_1D_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_2D_CAPABLE))
bi_level_support |= T30_SUPPORT_T4_2D_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T6_CAPABLE))
bi_level_support |= T30_SUPPORT_T6_COMPRESSION;
/* Bit 79 set with bit 78 clear is invalid, so let's completely ignore 79
if 78 is clear. */
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T85_CAPABLE))
{
bi_level_support |= T30_SUPPORT_T85_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T85_L0_CAPABLE)
bi_level_support |= T30_SUPPORT_T85_L0_COMPRESSION;
}
gray_support = 0;
colour_support = 0;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_200_200_CAPABLE) && test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T81_CAPABLE))
{
/* Multi-level coding available */
gray_support |= T30_SUPPORT_T81_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_12BIT_CAPABLE))
gray_support |= T30_SUPPORT_T81_12BIT_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T43_CAPABLE))
{
gray_support |= T30_SUPPORT_T43_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_12BIT_CAPABLE))
gray_support |= T30_SUPPORT_T43_COMPRESSION_12BIT;
}
if (test_ctrl_bit(s->far_dis_dtc_frame, bit69))
{
/* Colour coding available */
colour_support |= T30_SUPPORT_T81_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_12BIT_CAPABLE))
colour_support |= T30_SUPPORT_T81_12BIT_COMPRESSION;
if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_NO_SUBSAMPLING))
{
colour_support |= T30_SUPPORT_T81_SUBSAMPLING_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_12BIT_CAPABLE))
colour_support |= T30_SUPPORT_T81_SUBSAMPLING_COMPRESSION_12BIT;
}
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T43_CAPABLE))
{
colour_support |= T30_SUPPORT_T43_COMPRESSION;
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_12BIT_CAPABLE))
colour_support |= T30_SUPPORT_T43_12BIT_COMPRESSION;
}
}
/* bit74 custom illuminant */
/* bit75 custom gamut range */
}
#endif
queue_phase(s, T30_PHASE_B_TX);
/* Try to send something */
if (s->tx_file[0])
@@ -2289,7 +2374,7 @@ static int process_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
{
s->line_encoding = T4_COMPRESSION_ITU_T6;
}
else if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_2D_CODING))
else if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_2D_MODE))
{
s->line_encoding = T4_COMPRESSION_ITU_T4_2D;
}
@@ -4415,11 +4500,13 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
span_log(&s->logging, SPAN_LOG_FLOW, "The remote was made by '%s'\n", s->vendor);
if (s->model)
span_log(&s->logging, SPAN_LOG_FLOW, "The remote is a '%s'\n", s->model);
s->rx_info.nsf_len = decode_nsf_nss_nsc(s, &s->rx_info.nsf, &msg[2], len - 2);
}
else
{
/* NSC - Non-standard facilities command */
/* OK in (NSC) (CIG) DTC */
s->rx_info.nsc_len = decode_nsf_nss_nsc(s, &s->rx_info.nsc, &msg[2], len - 2);
}
break;
case (T30_PWD & 0xFE):
@@ -4487,6 +4574,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
break;
case (T30_NSS & 0xFE):
/* Non-standard facilities set-up */
s->rx_info.nss_len = decode_nsf_nss_nsc(s, &s->rx_info.nss, &msg[2], len - 2);
break;
case (T30_SUB & 0xFE):
/* Sub-address */
@@ -5209,6 +5297,18 @@ static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int le
}
/*- End of function --------------------------------------------------------*/
static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt, int len)
{
uint8_t *t;
if ((t = malloc(len - 1)) == NULL)
return 0;
memcpy(t, pkt + 1, len - 1);
*msg = t;
return len - 1;
}
/*- End of function --------------------------------------------------------*/
static void t30_non_ecm_rx_status(void *user_data, int status)
{
t30_state_t *s;
@@ -6175,10 +6275,8 @@ SPAN_DECLARE(void) t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t)
t->encoding = stats.encoding;
t->image_size = stats.line_image_size;
t->current_status = s->current_status;
#if 0
t->rtn_events = s->rtn_events;
t->rtp_events = s->rtp_events;
#endif
}
/*- End of function --------------------------------------------------------*/
+26 -7
View File
@@ -60,10 +60,18 @@
#include "spandsp/v27ter_tx.h"
#include "spandsp/t4_rx.h"
#include "spandsp/t4_tx.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/t43.h"
#endif
#include "spandsp/t4_t6_decode.h"
#include "spandsp/t4_t6_encode.h"
#include "spandsp/t30_fcf.h"
@@ -73,10 +81,18 @@
#include "spandsp/t30_logging.h"
#include "spandsp/private/logging.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/private/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/private/t43.h"
#endif
#include "spandsp/private/t4_t6_decode.h"
#include "spandsp/private/t4_t6_encode.h"
#include "spandsp/private/t4_rx.h"
@@ -548,10 +564,8 @@ SPAN_DECLARE(size_t) t30_get_rx_csa(t30_state_t *s, int *type, const char *addre
SPAN_DECLARE(int) t30_set_tx_page_header_overlays_image(t30_state_t *s, int header_overlays_image)
{
#if 0
s->header_overlays_image = header_overlays_image;
t4_tx_set_header_overlays_image(&s->t4.tx, s->header_overlays_image);
#endif
return 0;
}
/*- End of function --------------------------------------------------------*/
@@ -686,12 +700,17 @@ SPAN_DECLARE(int) t30_set_supported_compressions(t30_state_t *s, int supported_c
mask = T30_SUPPORT_T4_1D_COMPRESSION
| T30_SUPPORT_T4_2D_COMPRESSION
| T30_SUPPORT_T6_COMPRESSION
#if defined(SPANDSP_SUPPORT_T42)
| T30_SUPPORT_T42_COMPRESSION
#endif
#if defined(SPANDSP_SUPPORT_T43)
| T30_SUPPORT_T43_COMPRESSION
#endif
#if defined(SPANDSP_SUPPORT_T85)
| T30_SUPPORT_T85_COMPRESSION
| T30_SUPPORT_T85_L0_COMPRESSION;
#else
| 0;
| T30_SUPPORT_T85_L0_COMPRESSION
#endif
| 0;
s->supported_compressions = supported_compressions & mask;
t30_build_dis_or_dtc(s);
return 0;
+18 -2
View File
@@ -60,10 +60,18 @@
#include "spandsp/v27ter_tx.h"
#include "spandsp/t4_rx.h"
#include "spandsp/t4_tx.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/t43.h"
#endif
#include "spandsp/t4_t6_decode.h"
#include "spandsp/t4_t6_encode.h"
#include "spandsp/t30_fcf.h"
@@ -72,10 +80,18 @@
#include "spandsp/t30_logging.h"
#include "spandsp/private/logging.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/private/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/private/t43.h"
#endif
#include "spandsp/private/t4_t6_decode.h"
#include "spandsp/private/t4_t6_encode.h"
#include "spandsp/private/t4_rx.h"
+3
View File
@@ -2167,6 +2167,9 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
}
dle_unstuff(s, t, len);
break;
case AT_MODE_CONNECTED:
/* TODO: Implement for data modem operation */
break;
}
return len;
}
+20 -4
View File
@@ -73,10 +73,18 @@
#include "spandsp/modem_connect_tones.h"
#include "spandsp/t4_rx.h"
#include "spandsp/t4_tx.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/t43.h"
#endif
#include "spandsp/t4_t6_decode.h"
#include "spandsp/t4_t6_encode.h"
#include "spandsp/t30_fcf.h"
@@ -100,10 +108,18 @@
#include "spandsp/private/modem_connect_tones.h"
#include "spandsp/private/hdlc.h"
#include "spandsp/private/fax_modems.h"
#if defined(SPANDSP_SUPPORT_T85)
#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t81_t82_arith_coding.h"
#endif
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t85.h"
#endif
#if defined(SPANDSP_SUPPORT_T42)
#include "spandsp/private/t42.h"
#endif
#if defined(SPANDSP_SUPPORT_T43)
#include "spandsp/private/t43.h"
#endif
#include "spandsp/private/t4_t6_decode.h"
#include "spandsp/private/t4_t6_encode.h"
#include "spandsp/private/t4_rx.h"
@@ -519,7 +535,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
t->tx_bit_rate = 2400;
break;
case T38_IND_V27TER_4800_TRAINING:
t->tx_bit_rate = 2400;
t->tx_bit_rate = 4800;
break;
}
/*endswitch*/
@@ -930,7 +946,7 @@ static void monitor_control_messages(t38_gateway_state_t *s,
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. */
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;
+10 -2
View File
@@ -399,7 +399,7 @@ static void make_header(t4_state_t *s, char *header)
}
/*- End of function --------------------------------------------------------*/
static int t4_tx_put_fax_header(t4_state_t *s)
static int t4_tx_put_fax_header(t4_state_t *s, int *rows)
{
int row;
int i;
@@ -435,6 +435,7 @@ static int t4_tx_put_fax_header(t4_state_t *s)
repeats = 1;
break;
}
*rows = 16*repeats;
for (row = 0; row < 16; row++)
{
t = header;
@@ -1285,6 +1286,7 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_state_t *s)
int run_space;
int len;
int old_image_width;
int header_rows;
uint8_t *bufptr8;
uint32_t *bufptr;
@@ -1336,7 +1338,7 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_state_t *s)
if (s->header_info && s->header_info[0])
{
if (t4_tx_put_fax_header(s))
if (t4_tx_put_fax_header(s, &header_rows))
return -1;
}
if (s->t4_t6_tx.row_read_handler)
@@ -1501,6 +1503,12 @@ SPAN_DECLARE(void) t4_tx_set_min_bits_per_row(t4_state_t *s, int bits)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) t4_tx_set_header_overlays_image(t4_state_t *s, int header_overlays_image)
{
s->header_overlays_image = header_overlays_image;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) t4_tx_set_local_ident(t4_state_t *s, const char *ident)
{
s->tiff.local_ident = (ident && ident[0]) ? ident : NULL;
+7 -8
View File
@@ -114,11 +114,11 @@ static const int year_lengths[2] =
static int increment_overflow(int *number, int delta)
{
int number0;
int last_number;
number0 = *number;
last_number = *number;
*number += delta;
return (*number < number0) != (delta < 0);
return (*number < last_number) != (delta < 0);
}
/*- End of function --------------------------------------------------------*/
@@ -164,6 +164,10 @@ static struct tm *time_sub(const time_t * const timep, const long int offset, co
int y;
int hit;
int i;
int newy;
time_t tdelta;
int idelta;
int leapdays;
corr = 0;
hit = 0;
@@ -198,11 +202,6 @@ static struct tm *time_sub(const time_t * const timep, const long int offset, co
rem = *timep - tdays*SECS_PER_DAY;
while (tdays < 0 || tdays >= year_lengths[isleap(y)])
{
int newy;
time_t tdelta;
int idelta;
int leapdays;
tdelta = tdays / DAYS_PER_LEAP_YEAR;
idelta = tdelta;
if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
+8 -6
View File
@@ -44,6 +44,9 @@
#include "spandsp/telephony.h"
#include "spandsp/logging.h"
#include "spandsp/fast_convert.h"
#include "spandsp/math_fixed.h"
#include "spandsp/saturated.h"
#include "spandsp/complex.h"
#include "spandsp/vector_float.h"
#include "spandsp/complex_vector_float.h"
@@ -62,13 +65,13 @@
#include "spandsp/private/logging.h"
#include "spandsp/private/v17rx.h"
#include "v17_v32bis_tx_constellation_maps.h"
#include "v17_v32bis_rx_constellation_maps.h"
#if defined(SPANDSP_USE_FIXED_POINT)
#include "v17_v32bis_rx_fixed_rrc.h"
#else
#include "v17_v32bis_rx_floating_rrc.h"
#endif
#include "v17_v32bis_tx_constellation_maps.h"
#include "v17_v32bis_rx_constellation_maps.h"
/*! The nominal frequency of the carrier, in Hertz */
#define CARRIER_NOMINAL_FREQ 1800.0f
@@ -295,8 +298,7 @@ static int descramble(v17_rx_state_t *s, int in_bit)
{
int out_bit;
//out_bit = (in_bit ^ (s->scramble_reg >> s->scrambler_tap) ^ (s->scramble_reg >> (23 - 1))) & 1;
out_bit = (in_bit ^ (s->scramble_reg >> (18 - 1)) ^ (s->scramble_reg >> (23 - 1))) & 1;
out_bit = (in_bit ^ (s->scramble_reg >> s->scrambler_tap) ^ (s->scramble_reg >> (23 - 1))) & 1;
s->scramble_reg <<= 1;
if (s->training_stage > TRAINING_STAGE_NORMAL_OPERATION && s->training_stage < TRAINING_STAGE_TCM_WINDUP)
s->scramble_reg |= out_bit;
@@ -1248,7 +1250,7 @@ SPAN_DECLARE(void) v17_rx_set_put_bit(v17_rx_state_t *s, put_bit_func_t put_bit,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v17_rx_set_modem_status_handler(v17_rx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) v17_rx_set_modem_status_handler(v17_rx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
@@ -1425,7 +1427,7 @@ SPAN_DECLARE(v17_rx_state_t *) v17_rx_init(v17_rx_state_t *s, int bit_rate, put_
s->put_bit = put_bit;
s->put_bit_user_data = user_data;
s->short_train = FALSE;
//s->scrambler_tap = 18 - 1;
s->scrambler_tap = 18 - 1;
v17_rx_signal_cutoff(s, -45.5f);
s->carrier_phase_rate_save = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
v17_rx_restart(s, bit_rate, s->short_train);
+33 -33
View File
@@ -100,8 +100,7 @@ static __inline__ int scramble(v17_tx_state_t *s, int in_bit)
{
int out_bit;
//out_bit = (in_bit ^ (s->scramble_reg >> s->scrambler_tap) ^ (s->scramble_reg >> (23 - 1))) & 1;
out_bit = (in_bit ^ (s->scramble_reg >> (18 - 1)) ^ (s->scramble_reg >> (23 - 1))) & 1;
out_bit = (in_bit ^ (s->scramble_reg >> s->scrambler_tap) ^ (s->scramble_reg >> (23 - 1))) & 1;
s->scramble_reg = (s->scramble_reg << 1) | out_bit;
return out_bit;
}
@@ -287,13 +286,16 @@ static __inline__ complexf_t getbaud(v17_tx_state_t *s)
SPAN_DECLARE_NONSTD(int) v17_tx(v17_tx_state_t *s, int16_t amp[], int len)
{
#if defined(SPANDSP_USE_FIXED_POINT)
complexi_t x;
complexi_t z;
complexi16_t v;
complexi32_t x;
complexi32_t z;
int16_t iamp;
#else
complexf_t v;
complexf_t x;
complexf_t z;
float famp;
#endif
int i;
int sample;
if (s->training_step >= V17_TRAINING_SHUTDOWN_END)
@@ -306,37 +308,30 @@ SPAN_DECLARE_NONSTD(int) v17_tx(v17_tx_state_t *s, int16_t amp[], int len)
if ((s->baud_phase += 3) >= 10)
{
s->baud_phase -= 10;
s->rrc_filter[s->rrc_filter_step] =
s->rrc_filter[s->rrc_filter_step + V17_TX_FILTER_STEPS] = getbaud(s);
v = getbaud(s);
s->rrc_filter_re[s->rrc_filter_step] = v.re;
s->rrc_filter_im[s->rrc_filter_step] = v.im;
if (++s->rrc_filter_step >= V17_TX_FILTER_STEPS)
s->rrc_filter_step = 0;
}
/* Root raised cosine pulse shaping at baseband */
#if defined(SPANDSP_USE_FIXED_POINT)
x = complex_seti(0, 0);
for (i = 0; i < V17_TX_FILTER_STEPS; i++)
{
x.re += (int32_t) tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].re;
x.im += (int32_t) tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].im;
}
/* Root raised cosine pulse shaping at baseband */
x.re = vec_circular_dot_prodi16(s->rrc_filter_re, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V17_TX_FILTER_STEPS, s->rrc_filter_step) >> 4;
x.im = vec_circular_dot_prodi16(s->rrc_filter_im, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V17_TX_FILTER_STEPS, s->rrc_filter_step) >> 4;
/* Now create and modulate the carrier */
x.re >>= 4;
x.im >>= 4;
z = dds_complexi(&(s->carrier_phase), s->carrier_phase_rate);
z = dds_complexi32(&s->carrier_phase, s->carrier_phase_rate);
iamp = ((int32_t) x.re*z.re - x.im*z.im) >> 15;
/* Don't bother saturating. We should never clip. */
i = (x.re*z.re - x.im*z.im) >> 15;
amp[sample] = (int16_t) ((i*s->gain) >> 15);
amp[sample] = (int16_t) (((int32_t) iamp*s->gain) >> 11);
#else
x = complex_setf(0.0f, 0.0f);
for (i = 0; i < V17_TX_FILTER_STEPS; i++)
{
x.re += tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].re;
x.im += tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].im;
}
/* Root raised cosine pulse shaping at baseband */
x.re = vec_circular_dot_prodf(s->rrc_filter_re, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V17_TX_FILTER_STEPS, s->rrc_filter_step);
x.im = vec_circular_dot_prodf(s->rrc_filter_im, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V17_TX_FILTER_STEPS, s->rrc_filter_step);
/* Now create and modulate the carrier */
z = dds_complexf(&(s->carrier_phase), s->carrier_phase_rate);
z = dds_complexf(&s->carrier_phase, s->carrier_phase_rate);
famp = x.re*z.re - x.im*z.im;
/* Don't bother saturating. We should never clip. */
amp[sample] = (int16_t) lfastrintf((x.re*z.re - x.im*z.im)*s->gain);
amp[sample] = (int16_t) lfastrintf(famp*s->gain);
#endif
}
return sample;
@@ -345,12 +340,15 @@ SPAN_DECLARE_NONSTD(int) v17_tx(v17_tx_state_t *s, int16_t amp[], int len)
SPAN_DECLARE(void) v17_tx_power(v17_tx_state_t *s, float power)
{
float gain;
/* The constellation design seems to keep the average power the same, regardless
of which bit rate is in use. */
gain = 0.223f*powf(10.0f, (power - DBM0_MAX_POWER)/20.0f)*32768.0f/TX_PULSESHAPER_GAIN;
#if defined(SPANDSP_USE_FIXED_POINT)
s->gain = 0.223f*powf(10.0f, (power - DBM0_MAX_POWER)/20.0f)*16.0f*(32767.0f/30672.52f)*32768.0f/TX_PULSESHAPER_GAIN;
s->gain = (int16_t) gain;
#else
s->gain = 0.223f*powf(10.0f, (power - DBM0_MAX_POWER)/20.0f)*32768.0f/TX_PULSESHAPER_GAIN;
s->gain = gain;
#endif
}
/*- End of function --------------------------------------------------------*/
@@ -364,7 +362,7 @@ SPAN_DECLARE(void) v17_tx_set_get_bit(v17_tx_state_t *s, get_bit_func_t get_bit,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v17_tx_set_modem_status_handler(v17_tx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) v17_tx_set_modem_status_handler(v17_tx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
@@ -410,9 +408,11 @@ SPAN_DECLARE(int) v17_tx_restart(v17_tx_state_t *s, int bit_rate, int tep, int s
/* NB: some modems seem to use 3 instead of 1 for long training */
s->diff = (short_train) ? 0 : 1;
#if defined(SPANDSP_USE_FIXED_POINT)
cvec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
vec_zeroi16(s->rrc_filter_re, sizeof(s->rrc_filter_re)/sizeof(s->rrc_filter_re[0]));
vec_zeroi16(s->rrc_filter_im, sizeof(s->rrc_filter_im)/sizeof(s->rrc_filter_im[0]));
#else
cvec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
vec_zerof(s->rrc_filter_re, sizeof(s->rrc_filter_re)/sizeof(s->rrc_filter_re[0]));
vec_zerof(s->rrc_filter_im, sizeof(s->rrc_filter_im)/sizeof(s->rrc_filter_im[0]));
#endif
s->rrc_filter_step = 0;
s->convolution = 0;
@@ -452,7 +452,7 @@ SPAN_DECLARE(v17_tx_state_t *) v17_tx_init(v17_tx_state_t *s, int bit_rate, int
span_log_set_protocol(&s->logging, "V.17 TX");
s->get_bit = get_bit;
s->get_bit_user_data = user_data;
//s->scrambler_tap = 18 - 1;
s->scrambler_tap = 18 - 1;
s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
v17_tx_power(s, -14.0f);
v17_tx_restart(s, bit_rate, tep, FALSE);
+1 -1
View File
@@ -552,7 +552,7 @@ SPAN_DECLARE(void) v22bis_set_put_bit(v22bis_state_t *s, put_bit_func_t put_bit,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v22bis_set_modem_status_handler(v22bis_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) v22bis_set_modem_status_handler(v22bis_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
+1 -1
View File
@@ -1019,7 +1019,7 @@ SPAN_DECLARE(void) v27ter_rx_set_put_bit(v27ter_rx_state_t *s, put_bit_func_t pu
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v27ter_rx_set_modem_status_handler(v27ter_rx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) v27ter_rx_set_modem_status_handler(v27ter_rx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
+1 -1
View File
@@ -374,7 +374,7 @@ SPAN_DECLARE(void) v27ter_tx_set_get_bit(v27ter_tx_state_t *s, get_bit_func_t ge
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v27ter_tx_set_modem_status_handler(v27ter_tx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) v27ter_tx_set_modem_status_handler(v27ter_tx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
+1 -1
View File
@@ -1052,7 +1052,7 @@ SPAN_DECLARE(void) v29_rx_set_put_bit(v29_rx_state_t *s, put_bit_func_t put_bit,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v29_rx_set_modem_status_handler(v29_rx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) v29_rx_set_modem_status_handler(v29_rx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
+1 -1
View File
@@ -316,7 +316,7 @@ SPAN_DECLARE(void) v29_tx_set_get_bit(v29_tx_state_t *s, get_bit_func_t get_bit,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v29_tx_set_modem_status_handler(v29_tx_state_t *s, modem_tx_status_func_t handler, void *user_data)
SPAN_DECLARE(void) v29_tx_set_modem_status_handler(v29_tx_state_t *s, modem_status_func_t handler, void *user_data)
{
s->status_handler = handler;
s->status_user_data = user_data;
Loaded 100 of 398 files, more files were not shown because too many files have changed in this diff. Show more