提交 1d289b36 authored 作者: Steve Underwood's avatar Steve Underwood

Chnaged T.30 x-rex, y-res, width vetting to be more rigorous.

Various little tweaks to spandsp
上级 7a29ef95
......@@ -84,7 +84,7 @@ Receiver now waits
Sender waits 250-300ms after end of 2300Hz tone
Send ACCT MT QXYZ GG CCC
Send ACCT MT QXYZ GG CCC S
ACCT = 4 digit account code (0-9, B-F)
MT = 2 digit message type (18 preferred, 98 optional)
......@@ -124,6 +124,74 @@ If kissoff doesn't start within 1.25s of the end of the DTMF, repeat the DTMF me
Receiver sends 750-1000ms of 1400Hz as the kissoff tone
Sender shall make 4 attempts before giving up. One successful kissoff resets the attempt counter
Ademco Express 4/1
ACCT MT C
ACCT = 4 digit account code (0-9, B-F)
MT = 2 digit message type (17)
C = alarm code
S = 1 digit hex checksum
Ademco Express 4/2
ACCT MT C Z S
ACCT = 4 digit account code (0-9, B-F)
MT = 2 digit message type (27)
C = 1 digit alarm code
Z = 1 digit zone or user number
S = 1 digit hex checksum
Ademco High speed
ACCT MT PPPPPPPP X S
ACCT = 4 digit account code (0-9, B-F)
MT = 2 digit message type (55)
PPPPPPPP = 8 digit status of each zone
X = 1 digit type of information in the PPPPPPPP field
S = 1 digit hex checksum
Each P digit contains one of the following values:
1 new alarm
2 new opening
3 new restore
4 new closing
5 normal
6 outstanding
The X field contains one of the following values:
0 AlarmNet messages
1 ambush or duress
2 opening by user (the first P field contains the user number)
3 bypass (the P fields indicate which zones are bypassed)
4 closing by user (the first P field contain the user number)
5 trouble (the P fields contain which zones are in trouble)
6 system trouble
7 normal message (the P fields indicate zone status)
8 low battery (the P fields indicate zone status)
9 test (the P fields indicate zone status)
Ademco Super fast
ACCT MT PPPPPPPP X S
ACCT = 4 digit account code (0-9, B-F)
MT = 2 digit message type (56)
There are versions somewhat like the above, with 8, 16 or 24 'P' digits,
and no message type
ACCT PPPPPPPP X
ACCT PPPPPPPPPPPPPPPP X
ACCT PPPPPPPPPPPPPPPPPPPPPPPP X
ACCT = 4 digit account code (0-9, B-F)
PPPPPPPP = 8, 16 or 24 digit status of each zone
X = 1 digit status of the communicator
S = 1 digit hex checksum
*/
struct ademco_code_s
......@@ -1040,7 +1108,7 @@ SPAN_DECLARE(ademco_contactid_sender_state_t *) ademco_contactid_sender_init(ade
s->step = 0;
s->remaining_samples = ms_to_samples(100);
dtmf_tx_init(&s->dtmf);
dtmf_tx_init(&s->dtmf, NULL, NULL);
/* The specified timing is 50-60ms on, 50-60ms off */
dtmf_tx_set_timing(&s->dtmf, 55, 55);
return s;
......
......@@ -373,19 +373,19 @@ static void start_tx(adsi_tx_state_t *s)
switch (s->standard)
{
case ADSI_STANDARD_CLASS:
fsk_tx_init(&(s->fsktx), &preset_fsk_specs[FSK_BELL202], adsi_tx_get_bit, s);
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_BELL202], adsi_tx_get_bit, s);
break;
case ADSI_STANDARD_CLIP:
case ADSI_STANDARD_ACLIP:
case ADSI_STANDARD_JCLIP:
fsk_tx_init(&(s->fsktx), &preset_fsk_specs[FSK_V23CH1], adsi_tx_get_bit, s);
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V23CH1], adsi_tx_get_bit, s);
break;
case ADSI_STANDARD_CLIP_DTMF:
dtmf_tx_init(&(s->dtmftx));
dtmf_tx_init(&s->dtmftx, NULL, NULL);
break;
case ADSI_STANDARD_TDD:
fsk_tx_init(&(s->fsktx), &preset_fsk_specs[FSK_WEITBRECHT], async_tx_get_bit, &(s->asynctx));
async_tx_init(&(s->asynctx), 5, ASYNC_PARITY_NONE, 2, FALSE, adsi_tdd_get_async_byte, s);
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_WEITBRECHT], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 5, ASYNC_PARITY_NONE, 2, FALSE, adsi_tdd_get_async_byte, s);
/* Schedule an explicit shift at the start of baudot transmission */
s->baudot_shift = 2;
break;
......@@ -403,10 +403,10 @@ SPAN_DECLARE(int) adsi_rx(adsi_rx_state_t *s, const int16_t amp[], int len)
s->in_progress -= len;
if (s->in_progress <= 0)
s->msg_len = 0;
dtmf_rx(&(s->dtmfrx), amp, len);
dtmf_rx(&s->dtmfrx, amp, len);
break;
default:
fsk_rx(&(s->fskrx), amp, len);
fsk_rx(&s->fskrx, amp, len);
break;
}
return 0;
......@@ -435,20 +435,20 @@ SPAN_DECLARE(adsi_rx_state_t *) adsi_rx_init(adsi_rx_state_t *s,
switch (standard)
{
case ADSI_STANDARD_CLASS:
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_BELL202], FSK_FRAME_MODE_ASYNC, adsi_rx_put_bit, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_BELL202], FSK_FRAME_MODE_ASYNC, adsi_rx_put_bit, s);
break;
case ADSI_STANDARD_CLIP:
case ADSI_STANDARD_ACLIP:
case ADSI_STANDARD_JCLIP:
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_V23CH1], FSK_FRAME_MODE_ASYNC, adsi_rx_put_bit, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V23CH1], FSK_FRAME_MODE_ASYNC, adsi_rx_put_bit, s);
break;
case ADSI_STANDARD_CLIP_DTMF:
dtmf_rx_init(&(s->dtmfrx), adsi_rx_dtmf, s);
dtmf_rx_init(&s->dtmfrx, adsi_rx_dtmf, s);
break;
case ADSI_STANDARD_TDD:
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
ride over the fraction. */
fsk_rx_init(&(s->fskrx), &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, adsi_tdd_put_async_byte, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, adsi_tdd_put_async_byte, s);
break;
}
s->standard = standard;
......@@ -475,19 +475,19 @@ SPAN_DECLARE(int) adsi_tx(adsi_tx_state_t *s, int16_t amp[], int max_len)
int len;
int lenx;
len = tone_gen(&(s->alert_tone_gen), amp, max_len);
len = tone_gen(&s->alert_tone_gen, amp, max_len);
if (s->tx_signal_on)
{
switch (s->standard)
{
case ADSI_STANDARD_CLIP_DTMF:
if (len < max_len)
len += dtmf_tx(&(s->dtmftx), amp, max_len - len);
len += dtmf_tx(&s->dtmftx, amp, max_len - len);
break;
default:
if (len < max_len)
{
if ((lenx = fsk_tx(&(s->fsktx), amp + len, max_len - len)) <= 0)
if ((lenx = fsk_tx(&s->fsktx, amp + len, max_len - len)) <= 0)
s->tx_signal_on = FALSE;
len += lenx;
}
......@@ -500,7 +500,7 @@ SPAN_DECLARE(int) adsi_tx(adsi_tx_state_t *s, int16_t amp[], int max_len)
SPAN_DECLARE(void) adsi_tx_send_alert_tone(adsi_tx_state_t *s)
{
tone_gen_init(&(s->alert_tone_gen), &(s->alert_tone_desc));
tone_gen_init(&s->alert_tone_gen, &s->alert_tone_desc);
}
/*- End of function --------------------------------------------------------*/
......@@ -583,7 +583,7 @@ SPAN_DECLARE(int) adsi_tx_put_message(adsi_tx_state_t *s, const uint8_t *msg, in
case ADSI_STANDARD_CLIP_DTMF:
if (len >= 128)
return -1;
len -= (int) dtmf_tx_put(&(s->dtmftx), (char *) msg, len);
len -= (int) dtmf_tx_put(&s->dtmftx, (char *) msg, len);
break;
case ADSI_STANDARD_JCLIP:
if (len > 128 - 9)
......@@ -662,7 +662,7 @@ SPAN_DECLARE(adsi_tx_state_t *) adsi_tx_init(adsi_tx_state_t *s, int standard)
return NULL;
}
memset(s, 0, sizeof(*s));
tone_gen_descriptor_init(&(s->alert_tone_desc),
tone_gen_descriptor_init(&s->alert_tone_desc,
2130,
-13,
2750,
......
......@@ -35,6 +35,7 @@
#include <assert.h>
#include "spandsp/telephony.h"
#include "spandsp/bit_operations.h"
#include "spandsp/async.h"
#include "spandsp/private/async.h"
......@@ -75,55 +76,13 @@ SPAN_DECLARE(const char *) signal_status_to_str(int status)
return "Link disconnected";
case SIG_STATUS_LINK_ERROR:
return "Link error";
case SIG_STATUS_LINK_IDLE:
return "Link idle";
}
return "???";
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(async_rx_state_t *) async_rx_init(async_rx_state_t *s,
int data_bits,
int parity,
int stop_bits,
int use_v14,
put_byte_func_t put_byte,
void *user_data)
{
if (s == NULL)
{
if ((s = (async_rx_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
s->data_bits = data_bits;
s->parity = parity;
s->stop_bits = stop_bits;
s->use_v14 = use_v14;
s->put_byte = put_byte;
s->user_data = user_data;
s->byte_in_progress = 0;
s->bitpos = 0;
s->parity_bit = 0;
s->parity_errors = 0;
s->framing_errors = 0;
return s;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) async_rx_release(async_rx_state_t *s)
{
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) async_rx_free(async_rx_state_t *s)
{
free(s);
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit)
{
async_rx_state_t *s;
......@@ -205,45 +164,44 @@ SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(async_tx_state_t *) async_tx_init(async_tx_state_t *s,
SPAN_DECLARE(async_rx_state_t *) async_rx_init(async_rx_state_t *s,
int data_bits,
int parity,
int stop_bits,
int use_v14,
get_byte_func_t get_byte,
put_byte_func_t put_byte,
void *user_data)
{
if (s == NULL)
{
if ((s = (async_tx_state_t *) malloc(sizeof(*s))) == NULL)
if ((s = (async_rx_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
/* We have a use_v14 parameter for completeness, but right now V.14 only
applies to the receive side. We are unlikely to have an application where
flow control does not exist, so V.14 stuffing is not needed. */
s->data_bits = data_bits;
s->parity = parity;
s->stop_bits = stop_bits;
if (parity != ASYNC_PARITY_NONE)
s->stop_bits++;
s->get_byte = get_byte;
s->use_v14 = use_v14;
s->put_byte = put_byte;
s->user_data = user_data;
s->byte_in_progress = 0;
s->bitpos = 0;
s->parity_bit = 0;
s->parity_errors = 0;
s->framing_errors = 0;
return s;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) async_tx_release(async_tx_state_t *s)
SPAN_DECLARE(int) async_rx_release(async_rx_state_t *s)
{
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) async_tx_free(async_tx_state_t *s)
SPAN_DECLARE(int) async_rx_free(async_rx_state_t *s)
{
free(s);
return 0;
......@@ -295,4 +253,56 @@ SPAN_DECLARE_NONSTD(int) async_tx_get_bit(void *user_data)
return bit;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) async_tx_presend_bits(async_tx_state_t *s, int bits)
{
s->presend_bits = bits;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(async_tx_state_t *) async_tx_init(async_tx_state_t *s,
int data_bits,
int parity,
int stop_bits,
int use_v14,
get_byte_func_t get_byte,
void *user_data)
{
if (s == NULL)
{
if ((s = (async_tx_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
/* We have a use_v14 parameter for completeness, but right now V.14 only
applies to the receive side. We are unlikely to have an application where
flow control does not exist, so V.14 stuffing is not needed. */
s->data_bits = data_bits;
s->parity = parity;
s->stop_bits = stop_bits;
if (parity != ASYNC_PARITY_NONE)
s->stop_bits++;
s->get_byte = get_byte;
s->user_data = user_data;
s->byte_in_progress = 0;
s->bitpos = 0;
s->parity_bit = 0;
s->presend_bits = 0;
return s;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) async_tx_release(async_tx_state_t *s)
{
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) async_tx_free(async_tx_state_t *s)
{
free(s);
return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
......@@ -508,21 +508,31 @@ SPAN_DECLARE(int) dtmf_tx(dtmf_tx_state_t *s, int16_t amp[], int max_samples)
if (s->tones.current_section >= 0)
{
/* Deal with the fragment left over from last time */
len = tone_gen(&(s->tones), amp, max_samples);
len = tone_gen(&s->tones, amp, max_samples);
}
while (len < max_samples && (digit = queue_read_byte(&s->queue.queue)) >= 0)
while (len < max_samples)
{
/* Step to the next digit */
if ((digit = queue_read_byte(&s->queue.queue)) < 0)
{
/* See if we can get some more digits */
if (s->callback == NULL)
break;
s->callback(s->callback_data);
if ((digit = queue_read_byte(&s->queue.queue)) < 0)
break;
}
if (digit == 0)
continue;
if ((cp = strchr(dtmf_positions, digit)) == NULL)
continue;
tone_gen_init(&(s->tones), &dtmf_digit_tones[cp - dtmf_positions]);
tone_gen_init(&s->tones, &dtmf_digit_tones[cp - dtmf_positions]);
s->tones.tone[0].gain = s->low_level;
s->tones.tone[1].gain = s->high_level;
s->tones.duration[0] = s->on_time;
s->tones.duration[1] = s->off_time;
len += tone_gen(&(s->tones), amp + len, max_samples - len);
len += tone_gen(&s->tones, amp + len, max_samples - len);
}
return len;
}
......@@ -562,7 +572,9 @@ SPAN_DECLARE(void) dtmf_tx_set_timing(dtmf_tx_state_t *s, int on_time, int off_t
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s)
SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s,
digits_tx_callback_t callback,
void *user_data)
{
if (s == NULL)
{
......@@ -572,7 +584,9 @@ SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s)
memset(s, 0, sizeof(*s));
if (!dtmf_tx_inited)
dtmf_tx_initialise();
tone_gen_init(&(s->tones), &dtmf_digit_tones[0]);
s->callback = callback;
s->callback_data = user_data;
tone_gen_init(&s->tones, &dtmf_digit_tones[0]);
dtmf_tx_set_level(s, DEFAULT_DTMF_TX_LEVEL, 0);
dtmf_tx_set_timing(s, -1, -1);
queue_init(&s->queue.queue, MAX_DTMF_DIGITS, QUEUE_READ_ATOMIC | QUEUE_WRITE_ATOMIC);
......
......@@ -117,7 +117,7 @@ const fsk_spec_t preset_fsk_specs[] =
4545
},
{
"Weitbrecht 50", /* Used for Internatioal TDD (Telecoms Device for the Deaf) */
"Weitbrecht 50", /* Used for international TDD (Telecoms Device for the Deaf) */
1600 + 200,
1600 - 200,
-14,
......
......@@ -86,7 +86,9 @@ enum
/*! \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
SIG_STATUS_LINK_ERROR = -16,
/*! \brief Keep the link in an idle state, as there is nothing to send. */
SIG_STATUS_LINK_IDLE = -17
};
/*! Message put function for data pumps */
......@@ -145,27 +147,44 @@ extern "C"
\return A pointer to the description. */
SPAN_DECLARE(const char *) signal_status_to_str(int status);
/*! Initialise an asynchronous data transmit context.
\brief Initialise an asynchronous data transmit context.
\param s The transmitter context.
\param data_bits The number of data bit.
/*! Accept a bit from a received serial bit stream
\brief Accept a bit from a received serial bit stream
\param user_data An opaque point which must point to a receiver context.
\param bit The new bit. Some special values are supported for this field.
- SIG_STATUS_CARRIER_UP
- SIG_STATUS_CARRIER_DOWN
- SIG_STATUS_TRAINING_SUCCEEDED
- SIG_STATUS_TRAINING_FAILED
- SIG_STATUS_END_OF_DATA */
SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit);
/*! Initialise an asynchronous data receiver context.
\brief Initialise an asynchronous data receiver context.
\param s The receiver context.
\param data_bits The number of data bits.
\param parity_bits The type of parity.
\param stop_bits The number of stop bits.
\param use_v14 TRUE if V.14 rate adaption processing should be used.
\param get_byte The callback routine used to get the data to be transmitted.
\param put_byte The callback routine used to put the received data.
\param user_data An opaque pointer.
\return A pointer to the initialised context, or NULL if there was a problem. */
SPAN_DECLARE(async_tx_state_t *) async_tx_init(async_tx_state_t *s,
SPAN_DECLARE(async_rx_state_t *) async_rx_init(async_rx_state_t *s,
int data_bits,
int parity_bits,
int stop_bits,
int use_v14,
get_byte_func_t get_byte,
put_byte_func_t put_byte,
void *user_data);
SPAN_DECLARE(int) async_tx_release(async_tx_state_t *s);
SPAN_DECLARE(int) async_rx_release(async_rx_state_t *s);
SPAN_DECLARE(int) async_tx_free(async_tx_state_t *s);
SPAN_DECLARE(int) async_rx_free(async_rx_state_t *s);
/*! Set a minimum number of bit times of stop bit state before character transmission commences.
\brief Set a minimum number of bit times of stop bit state before character transmission commences.
\param user_data An opaque point which must point to a transmitter context.
\param the number of bits. */
SPAN_DECLARE(void) async_tx_presend_bits(async_tx_state_t *s, int bits);
/*! Get the next bit of a transmitted serial bit stream.
\brief Get the next bit of a transmitted serial bit stream.
......@@ -173,38 +192,27 @@ SPAN_DECLARE(int) async_tx_free(async_tx_state_t *s);
\return the next bit, or PUTBIT_END_OF_DATA to indicate the data stream has ended. */
SPAN_DECLARE_NONSTD(int) async_tx_get_bit(void *user_data);
/*! Initialise an asynchronous data receiver context.
\brief Initialise an asynchronous data receiver context.
\param s The receiver context.
\param data_bits The number of data bits.
/*! Initialise an asynchronous data transmit context.
\brief Initialise an asynchronous data transmit context.
\param s The transmitter context.
\param data_bits The number of data bit.
\param parity_bits The type of parity.
\param stop_bits The number of stop bits.
\param use_v14 TRUE if V.14 rate adaption processing should be used.
\param put_byte The callback routine used to put the received data.
\param get_byte The callback routine used to get the data to be transmitted.
\param user_data An opaque pointer.
\return A pointer to the initialised context, or NULL if there was a problem. */
SPAN_DECLARE(async_rx_state_t *) async_rx_init(async_rx_state_t *s,
SPAN_DECLARE(async_tx_state_t *) async_tx_init(async_tx_state_t *s,
int data_bits,
int parity_bits,
int stop_bits,
int use_v14,
put_byte_func_t put_byte,
get_byte_func_t get_byte,
void *user_data);
SPAN_DECLARE(int) async_rx_release(async_rx_state_t *s);
SPAN_DECLARE(int) async_rx_free(async_rx_state_t *s);
SPAN_DECLARE(int) async_tx_release(async_tx_state_t *s);
/*! Accept a bit from a received serial bit stream
\brief Accept a bit from a received serial bit stream
\param user_data An opaque point which must point to a receiver context.
\param bit The new bit. Some special values are supported for this field.
- SIG_STATUS_CARRIER_UP
- SIG_STATUS_CARRIER_DOWN
- SIG_STATUS_TRAINING_SUCCEEDED
- SIG_STATUS_TRAINING_FAILED
- SIG_STATUS_END_OF_DATA */
SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit);
SPAN_DECLARE(int) async_tx_free(async_tx_state_t *s);
#if defined(__cplusplus)
}
......
......@@ -74,6 +74,7 @@ repertoire of 16 DTMF dual tones.
#define MAX_DTMF_DIGITS 128
typedef void (*digits_rx_callback_t)(void *user_data, const char *digits, int len);
typedef void (*digits_tx_callback_t)(void *user_data);
/*!
DTMF generator state descriptor. This defines the state of a single
......@@ -122,8 +123,13 @@ SPAN_DECLARE(void) dtmf_tx_set_timing(dtmf_tx_state_t *s, int on_time, int off_t
/*! \brief Initialise a DTMF tone generator context.
\param s The DTMF generator context.
\param callback An optional callback routine, used to get more digits.
\param user_data An opaque pointer which is associated with the context,
and supplied in callbacks.
\return A pointer to the DTMF generator context. */
SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s);
SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s,
digits_tx_callback_t callback,
void *user_data);
/*! \brief Release a DTMF tone generator context.
\param s The DTMF tone generator context.
......
......@@ -43,9 +43,11 @@ struct async_tx_state_s
get_byte_func_t get_byte;
/*! \brief An opaque pointer passed when calling get_byte. */
void *user_data;
/*! \brief The minimum number of stop bits to send before character transmission begins. */
int presend_bits;
/*! \brief A current, partially transmitted, character. */
unsigned int byte_in_progress;
int32_t byte_in_progress;
/*! \brief The current bit position within a partially transmitted character. */
int bitpos;
/*! \brief Parity bit. */
......@@ -73,7 +75,7 @@ struct async_rx_state_s
void *user_data;
/*! \brief A current, partially complete, character. */
unsigned int byte_in_progress;
int32_t byte_in_progress;
/*! \brief The current bit position within a partially complete character. */
int bitpos;
/*! \brief Parity bit. */
......
......@@ -32,6 +32,10 @@
*/
struct dtmf_tx_state_s
{
/*! Optional callback funcion to get more digits. */
digits_tx_callback_t callback;
/*! An opaque pointer passed to the callback function. */
void *callback_data;
tone_gen_state_t tones;
float low_level;
float high_level;
......
......@@ -66,6 +66,10 @@ typedef struct
{
/*! \brief The FAX modem set for the audio side fo the gateway. */
fax_modems_state_t modems;
/*! \brief CED detector */
modem_connect_tones_rx_state_t connect_rx_ced;
/*! \brief CNG detector */
modem_connect_tones_rx_state_t connect_rx_cng;
} t38_gateway_audio_state_t;
/*!
......
......@@ -138,7 +138,7 @@ struct v22bis_state_s
int constellation_state;
#if defined(SPANDSP_USE_FIXED_POINT)
/*! \brief The scaling factor accessed by the AGC algorithm. */
/*! \brief The scaling factor assessed by the AGC algorithm. */
int16_t agc_scaling;
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
int16_t rrc_filter[V22BIS_RX_FILTER_STEPS];
......@@ -158,7 +158,7 @@ struct v22bis_state_s
/*! \brief The integral part of the carrier tracking filter. */
int32_t carrier_track_i;
#else
/*! \brief The scaling factor accessed by the AGC algorithm. */
/*! \brief The scaling factor assessed by the AGC algorithm. */
float agc_scaling;
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
float rrc_filter[V22BIS_RX_FILTER_STEPS];
......
......@@ -363,16 +363,24 @@ static __inline__ int32_t saturated_sub32(int32_t a, int32_t b)
static __inline__ int16_t saturated_mul16(int16_t a, int16_t b)
{
if (a == INT16_MIN && b == INT16_MIN)
int32_t product;
product = (int32_t) a*b;
if (product == 0x40000000)
return INT16_MAX;
/*endif*/
return (int16_t) (((int32_t) a*(int32_t) b) >> 15);
return product >> 15;
}
/*- End of function --------------------------------------------------------*/
static __inline__ int32_t saturated_mul16_32(int16_t a, int16_t b)
{
return ((int32_t) a*(int32_t) b) << 1;
int32_t product;
product = (int32_t) a*b;
if (product == 0x40000000)
return INT32_MAX;
return product << 1;
}
/*- End of function --------------------------------------------------------*/
......
......@@ -140,9 +140,19 @@ SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t amp[], int max_len);
\param s The V.18 context.
\param amp The audio sample buffer.
\param len The number of samples in the buffer.
\return The number of unprocessed samples.
*/
SPAN_DECLARE_NONSTD(int) v18_rx(v18_state_t *s, const int16_t amp[], int len);
/*! Fake processing of a missing block of received V.18 audio samples.
(e.g due to packet loss).
\brief Fake processing of a missing block of received V.18 audio samples.
\param s The V.18 context.
\param len The number of samples to fake.
\return The number of unprocessed samples.
*/
SPAN_DECLARE_NONSTD(int) v18_rx_fillin(v18_state_t *s, int len);
/*! \brief Put a string to a V.18 context's input buffer.
\param s The V.18 context.
\param msg The string to be added.
......
......@@ -100,12 +100,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(void) v42_release(v42_state_t *s);
SPAN_DECLARE(int) v42_release(v42_state_t *s);
/*! Free a V.42 context.
\param s The V.42 context.
\return 0 if OK */
SPAN_DECLARE(void) v42_free(v42_state_t *s);
SPAN_DECLARE(int) v42_free(v42_state_t *s);
#if defined(__cplusplus)
}
......
差异被折叠。
......@@ -387,9 +387,9 @@ static int cmp(const void *s, const void *t)
SPAN_DECLARE(int) v18_encode_dtmf(v18_state_t *s, char dtmf[], const char msg[])
{
const char *t;
char *u;
const char *v;
char *u;
t = msg;
u = dtmf;
while (*t)
......@@ -685,7 +685,8 @@ static void v18_tdd_put_async_byte(void *user_data, int byte)
{
/* Whatever we have to date constitutes the message */
s->rx_msg[s->rx_msg_len] = '\0';
s->put_msg(s->user_data, s->rx_msg, s->rx_msg_len);
if (s->put_msg)
s->put_msg(s->user_data, s->rx_msg, s->rx_msg_len);
s->rx_msg_len = 0;
}
break;
......@@ -701,7 +702,8 @@ static void v18_tdd_put_async_byte(void *user_data, int byte)
if (s->rx_msg_len >= 256)
{
s->rx_msg[s->rx_msg_len] = '\0';
s->put_msg(s->user_data, s->rx_msg, s->rx_msg_len);
if (s->put_msg)
s->put_msg(s->user_data, s->rx_msg, s->rx_msg_len);
s->rx_msg_len = 0;
}
}
......@@ -815,6 +817,33 @@ SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(const char *) v18_mode_to_str(int mode)
{
switch (mode & 0xFF)
{
case V18_MODE_NONE:
return "None";
case V18_MODE_5BIT_45:
return "Weitbrecht TDD (45.45bps)";
case V18_MODE_5BIT_50:
return "Weitbrecht TDD (50bps)";
case V18_MODE_DTMF:
return "DTMF";
case V18_MODE_EDT:
return "EDT";
case V18_MODE_BELL103:
return "Bell 103";
case V18_MODE_V23VIDEOTEX:
return "Videotex";
case V18_MODE_V21TEXTPHONE:
return "V.21";
case V18_MODE_V18TEXTPHONE:
return "V.18 text telephone";
}
return "???";
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(logging_state_t *) v18_get_logging_state(v18_state_t *s)
{
return &s->logging;
......@@ -863,7 +892,7 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
s->repeat_shifts = mode & 0x100;
break;
case V18_MODE_DTMF:
dtmf_tx_init(&s->dtmftx);
dtmf_tx_init(&s->dtmftx, NULL, NULL);
dtmf_rx_init(&s->dtmfrx, v18_rx_dtmf, s);
break;
case V18_MODE_EDT:
......@@ -909,31 +938,4 @@ SPAN_DECLARE(int) v18_free(v18_state_t *s)
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(const char *) v18_mode_to_str(int mode)
{
switch (mode & 0xFF)
{
case V18_MODE_NONE:
return "None";
case V18_MODE_5BIT_45:
return "Weitbrecht TDD (45.45bps)";
case V18_MODE_5BIT_50:
return "Weitbrecht TDD (50bps)";
case V18_MODE_DTMF:
return "DTMF";
case V18_MODE_EDT:
return "EDT";
case V18_MODE_BELL103:
return "Bell 103";
case V18_MODE_V23VIDEOTEX:
return "Videotex";
case V18_MODE_V21TEXTPHONE:
return "V.21";
case V18_MODE_V18TEXTPHONE:
return "V.18 text telephone";
}
return "???";
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
......@@ -1554,16 +1554,18 @@ SPAN_DECLARE(v42_state_t *) v42_init(v42_state_t *ss,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v42_release(v42_state_t *s)
SPAN_DECLARE(int) v42_release(v42_state_t *s)
{
reset_lapm(s);
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) v42_free(v42_state_t *s)
SPAN_DECLARE(int) v42_free(v42_state_t *s)
{
v42_release(s);
free(s);
return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论