mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-25 12:10:18 +00:00
freetdm: First GSM working version
- Manually merging latest code from gideon.gsm branch after review/inspection/modifications
This commit is contained in:
parent
cf9f937079
commit
f316f9307f
@ -26,7 +26,7 @@
|
|||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Moises Silva <moy@sangoma.com>
|
* Moises Silva <moy@sangoma.com>
|
||||||
* David Yat Sin <dyatsin@sangoma.com>
|
* David Yat Sin <dyatsin@sangoma.com>
|
||||||
*
|
* Gideon Sadan <gsadan@sangoma.com>
|
||||||
*
|
*
|
||||||
* mod_freetdm.c -- FreeTDM Endpoint Module
|
* mod_freetdm.c -- FreeTDM Endpoint Module
|
||||||
*
|
*
|
||||||
@ -1887,6 +1887,24 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
|||||||
|
|
||||||
switch (sigmsg->event_id) {
|
switch (sigmsg->event_id) {
|
||||||
|
|
||||||
|
case FTDM_SIGEVENT_SMS:
|
||||||
|
{
|
||||||
|
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
|
||||||
|
ftdm_sms_data_t *sms = (ftdm_sms_data_t*) caller_data->priv;
|
||||||
|
|
||||||
|
|
||||||
|
ftdm_log(FTDM_LOG_INFO,"FTDM_SIGEVENT_SMS from %s: %s", sms->from, sms->body);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "failed to create SMS event\n");
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", sms->from);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "body", sms->body);
|
||||||
|
alarmbits = 0;
|
||||||
|
}
|
||||||
|
//return FTDM_BREAK;
|
||||||
|
break;
|
||||||
|
|
||||||
case FTDM_SIGEVENT_ALARM_CLEAR:
|
case FTDM_SIGEVENT_ALARM_CLEAR:
|
||||||
case FTDM_SIGEVENT_ALARM_TRAP:
|
case FTDM_SIGEVENT_ALARM_TRAP:
|
||||||
{
|
{
|
||||||
@ -1936,6 +1954,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
|||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTDM_SIGEVENT_RELEASED:
|
case FTDM_SIGEVENT_RELEASED:
|
||||||
case FTDM_SIGEVENT_INDICATION_COMPLETED:
|
case FTDM_SIGEVENT_INDICATION_COMPLETED:
|
||||||
case FTDM_SIGEVENT_DIALING:
|
case FTDM_SIGEVENT_DIALING:
|
||||||
@ -1964,6 +1983,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
|
|
||||||
|
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
|
||||||
@ -2898,7 +2919,7 @@ static void parse_gsm_spans(switch_xml_t cfg, switch_xml_t spans)
|
|||||||
"gsm",
|
"gsm",
|
||||||
on_clear_channel_signal,
|
on_clear_channel_signal,
|
||||||
spanparameters) != FTDM_SUCCESS) {
|
spanparameters) != FTDM_SUCCESS) {
|
||||||
CONFIG_ERROR("Error configuring Sangoma ISDN FreeTDM span %d\n", span_id);
|
CONFIG_ERROR("Error configuring Sangoma GSM FreeTDM span %d\n", span_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SPAN_CONFIG[span_id].span = span;
|
SPAN_CONFIG[span_id].span = span;
|
||||||
|
848
libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c
Normal file → Executable file
848
libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
38
libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
Normal file → Executable file
38
libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
Normal file → Executable file
@ -36,9 +36,9 @@
|
|||||||
* David Yat Sin <davidy@sangoma.com>
|
* David Yat Sin <davidy@sangoma.com>
|
||||||
* Nenad Corbic <ncorbic@sangoma.com>
|
* Nenad Corbic <ncorbic@sangoma.com>
|
||||||
* Arnaldo Pereira <arnaldo@sangoma.com>
|
* Arnaldo Pereira <arnaldo@sangoma.com>
|
||||||
|
* Gideon Sadan <gsadan@sangoma.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef WP_DEBUG_IO
|
#ifdef WP_DEBUG_IO
|
||||||
#define _BSD_SOURCE
|
#define _BSD_SOURCE
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
@ -121,6 +121,16 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
|||||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event);
|
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event);
|
||||||
FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event);
|
FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event);
|
||||||
|
|
||||||
|
static void wp_swap16(char *data, int datalen)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
uint16_t *samples = data;
|
||||||
|
for (i = 0; i < datalen/2; i++) {
|
||||||
|
uint16_t sample = ((samples[i] & 0x00FF) << 8) | ((samples[i] & 0xFF00) >> 8);
|
||||||
|
samples[i] = sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Poll for event on a wanpipe socket
|
* \brief Poll for event on a wanpipe socket
|
||||||
* \param fd Wanpipe socket descriptor
|
* \param fd Wanpipe socket descriptor
|
||||||
@ -305,12 +315,21 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
|||||||
|
|
||||||
err = sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);
|
err = sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
|
if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
|
||||||
chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW;
|
chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW;
|
||||||
} else {
|
} else {
|
||||||
chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW;
|
chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((span->trunk_type == FTDM_TRUNK_GSM) && (chan->type == FTDM_CHAN_TYPE_B)) {
|
||||||
|
chan->native_codec = FTDM_CODEC_SLIN;
|
||||||
|
chan->native_interval = 20;
|
||||||
|
chan->packet_len = 320;
|
||||||
|
}
|
||||||
|
|
||||||
err = sangoma_tdm_get_hw_dtmf(chan->sockfd, &tdm_api);
|
err = sangoma_tdm_get_hw_dtmf(chan->sockfd, &tdm_api);
|
||||||
if (err > 0) {
|
if (err > 0) {
|
||||||
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
|
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
|
||||||
@ -580,8 +599,9 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
|
|||||||
|
|
||||||
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL);
|
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL);
|
||||||
ftdmchan->effective_interval = ftdmchan->native_interval = wp_globals.codec_ms;
|
ftdmchan->effective_interval = ftdmchan->native_interval = wp_globals.codec_ms;
|
||||||
ftdmchan->packet_len = ftdmchan->native_interval * 8;
|
|
||||||
|
|
||||||
|
/* The packet len will depend on the codec and interval */
|
||||||
|
ftdmchan->packet_len = ftdmchan->native_interval * ((ftdmchan->native_codec==FTDM_CODEC_SLIN) ? 16 : 8);
|
||||||
if (wp_globals.txqueue_size > 0) {
|
if (wp_globals.txqueue_size > 0) {
|
||||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &wp_globals.txqueue_size);
|
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &wp_globals.txqueue_size);
|
||||||
}
|
}
|
||||||
@ -772,6 +792,7 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
|
|||||||
case FTDM_COMMAND_SET_INTERVAL:
|
case FTDM_COMMAND_SET_INTERVAL:
|
||||||
{
|
{
|
||||||
err=sangoma_tdm_set_usr_period(ftdmchan->sockfd, &tdm_api, FTDM_COMMAND_OBJ_INT);
|
err=sangoma_tdm_set_usr_period(ftdmchan->sockfd, &tdm_api, FTDM_COMMAND_OBJ_INT);
|
||||||
|
|
||||||
ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
|
ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -793,7 +814,7 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
|
|||||||
FTDM_COMMAND_OBJ_INT = wanpipe_swap_bits(rbsbits);
|
FTDM_COMMAND_OBJ_INT = wanpipe_swap_bits(rbsbits);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// does sangoma_tdm_read_rbs is available here?
|
/* is sangoma_tdm_read_rbs available here? */
|
||||||
FTDM_COMMAND_OBJ_INT = ftdmchan->rx_cas_bits;
|
FTDM_COMMAND_OBJ_INT = ftdmchan->rx_cas_bits;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -969,12 +990,15 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
|
|||||||
* \param datalen Size of data buffer
|
* \param datalen Size of data buffer
|
||||||
* \return Success, failure or timeout
|
* \return Success, failure or timeout
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static FIO_READ_FUNCTION(wanpipe_read)
|
static FIO_READ_FUNCTION(wanpipe_read)
|
||||||
{
|
{
|
||||||
int rx_len = 0;
|
int rx_len = 0;
|
||||||
int rq_len = (int)*datalen;
|
int rq_len = (int)*datalen;
|
||||||
wp_tdm_api_rx_hdr_t hdrframe;
|
wp_tdm_api_rx_hdr_t hdrframe;
|
||||||
|
|
||||||
|
|
||||||
#ifdef WP_DEBUG_IO
|
#ifdef WP_DEBUG_IO
|
||||||
wp_channel_t *wchan = ftdmchan->io_data;
|
wp_channel_t *wchan = ftdmchan->io_data;
|
||||||
ftdm_time_t time_diff = 0;
|
ftdm_time_t time_diff = 0;
|
||||||
@ -1034,6 +1058,10 @@ static FIO_READ_FUNCTION(wanpipe_read)
|
|||||||
wanpipe_read_stats(ftdmchan, &hdrframe);
|
wanpipe_read_stats(ftdmchan, &hdrframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ftdmchan->type == FTDM_CHAN_TYPE_B) && (ftdmchan->span->trunk_type == FTDM_TRUNK_GSM)) {
|
||||||
|
wp_swap16(data, *datalen);
|
||||||
|
}
|
||||||
|
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,6 +1078,10 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
wp_tdm_api_tx_hdr_t hdrframe;
|
wp_tdm_api_tx_hdr_t hdrframe;
|
||||||
|
|
||||||
|
if ((ftdmchan->type == FTDM_CHAN_TYPE_B) && (ftdmchan->span->trunk_type == FTDM_TRUNK_GSM)) {
|
||||||
|
wp_swap16(data, *datalen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do we even need the headerframe here? on windows, we don't even pass it to the driver */
|
/* Do we even need the headerframe here? on windows, we don't even pass it to the driver */
|
||||||
memset(&hdrframe, 0, sizeof(hdrframe));
|
memset(&hdrframe, 0, sizeof(hdrframe));
|
||||||
if (*datalen == 0) {
|
if (*datalen == 0) {
|
||||||
|
@ -346,6 +346,11 @@ typedef struct {
|
|||||||
uint8_t plan;
|
uint8_t plan;
|
||||||
} ftdm_number_t;
|
} ftdm_number_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char from[FTDM_MAX_NUMBER_STR_SZ];
|
||||||
|
char body[FTDM_MAX_NAME_STR_SZ];
|
||||||
|
} ftdm_sms_data_t;
|
||||||
|
|
||||||
/*! \brief Caller information */
|
/*! \brief Caller information */
|
||||||
typedef struct ftdm_caller_data {
|
typedef struct ftdm_caller_data {
|
||||||
char cid_date[8]; /*!< Caller ID date */
|
char cid_date[8]; /*!< Caller ID date */
|
||||||
@ -456,12 +461,13 @@ typedef enum {
|
|||||||
FTDM_SIGEVENT_INDICATION_COMPLETED, /*!< Last requested indication was completed */
|
FTDM_SIGEVENT_INDICATION_COMPLETED, /*!< Last requested indication was completed */
|
||||||
FTDM_SIGEVENT_DIALING, /*!< Outgoing call just started */
|
FTDM_SIGEVENT_DIALING, /*!< Outgoing call just started */
|
||||||
FTDM_SIGEVENT_TRANSFER_COMPLETED, /*!< Transfer request is completed */
|
FTDM_SIGEVENT_TRANSFER_COMPLETED, /*!< Transfer request is completed */
|
||||||
|
FTDM_SIGEVENT_SMS,
|
||||||
FTDM_SIGEVENT_INVALID, /*!<Invalid */
|
FTDM_SIGEVENT_INVALID, /*!<Invalid */
|
||||||
} ftdm_signal_event_t;
|
} ftdm_signal_event_t;
|
||||||
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \
|
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \
|
||||||
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
|
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
|
||||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "FACILITY", \
|
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "FACILITY", \
|
||||||
"TRACE", "TRACE_RAW", "INDICATION_COMPLETED", "DIALING", "TRANSFER_COMPLETED", "INVALID"
|
"TRACE", "TRACE_RAW", "INDICATION_COMPLETED", "DIALING", "TRANSFER_COMPLETED", "SMS", "INVALID"
|
||||||
/*! \brief Move from string to ftdm_signal_event_t and viceversa */
|
/*! \brief Move from string to ftdm_signal_event_t and viceversa */
|
||||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t)
|
FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user