freetdm: add pvt data to freetdm channels
fix fxs features
This commit is contained in:
parent
70bf7a0a6f
commit
9d45690006
|
@ -55,19 +55,6 @@ typedef enum {
|
||||||
ANALOG_OPTION_CALL_SWAP = (1 << 1)
|
ANALOG_OPTION_CALL_SWAP = (1 << 1)
|
||||||
} analog_option_t;
|
} analog_option_t;
|
||||||
|
|
||||||
struct span_config {
|
|
||||||
ftdm_span_t *span;
|
|
||||||
char dialplan[80];
|
|
||||||
char context[80];
|
|
||||||
char dial_regex[256];
|
|
||||||
char fail_dial_regex[256];
|
|
||||||
char hold_music[256];
|
|
||||||
char type[256];
|
|
||||||
analog_option_t analog_options;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct span_config SPAN_CONFIG[FTDM_MAX_SPANS_INTERFACE] = {{0}};
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TFLAG_IO = (1 << 0),
|
TFLAG_IO = (1 << 0),
|
||||||
TFLAG_DTMF = (1 << 1),
|
TFLAG_DTMF = (1 << 1),
|
||||||
|
@ -95,6 +82,7 @@ static struct {
|
||||||
switch_hash_t *ss7_configs;
|
switch_hash_t *ss7_configs;
|
||||||
} globals;
|
} globals;
|
||||||
|
|
||||||
|
/* private data attached to each fs session */
|
||||||
struct private_object {
|
struct private_object {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
switch_codec_t read_codec;
|
switch_codec_t read_codec;
|
||||||
|
@ -114,8 +102,26 @@ struct private_object {
|
||||||
uint32_t wr_error;
|
uint32_t wr_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* private data attached to FTDM channels (only FXS for now) */
|
||||||
|
typedef struct chan_pvt {
|
||||||
|
unsigned int flags;
|
||||||
|
} chan_pvt_t;
|
||||||
|
|
||||||
typedef struct private_object private_t;
|
typedef struct private_object private_t;
|
||||||
|
|
||||||
|
struct span_config {
|
||||||
|
ftdm_span_t *span;
|
||||||
|
char dialplan[80];
|
||||||
|
char context[80];
|
||||||
|
char dial_regex[256];
|
||||||
|
char fail_dial_regex[256];
|
||||||
|
char hold_music[256];
|
||||||
|
char type[256];
|
||||||
|
analog_option_t analog_options;
|
||||||
|
chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct span_config SPAN_CONFIG[FTDM_MAX_SPANS_INTERFACE] = {{0}};
|
||||||
|
|
||||||
static switch_status_t channel_on_init(switch_core_session_t *session);
|
static switch_status_t channel_on_init(switch_core_session_t *session);
|
||||||
static switch_status_t channel_on_hangup(switch_core_session_t *session);
|
static switch_status_t channel_on_hangup(switch_core_session_t *session);
|
||||||
|
@ -873,17 +879,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio
|
||||||
switch (msg->message_id) {
|
switch (msg->message_id) {
|
||||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||||
#if 0
|
|
||||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
|
||||||
ftdm_set_flag_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_ANSWERED);
|
|
||||||
ftdm_set_flag_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_PROGRESS);
|
|
||||||
ftdm_set_flag_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_MEDIA);
|
|
||||||
} else {
|
|
||||||
ftdm_set_state_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_UP);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ftdm_channel_call_answer(tech_pvt->ftdmchan);
|
ftdm_channel_call_answer(tech_pvt->ftdmchan);
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1621,6 +1617,12 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||||
break;
|
break;
|
||||||
case FTDM_SIGEVENT_FLASH:
|
case FTDM_SIGEVENT_FLASH:
|
||||||
{
|
{
|
||||||
|
chan_pvt_t *chanpvt = ftdm_channel_get_private(sigmsg->channel);
|
||||||
|
if (!chanpvt) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "%d:%d has no private data, can't handle FXS features! (this is a bug)\n",
|
||||||
|
chanid, spanid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (ftdm_channel_call_check_hold(sigmsg->channel) && tokencount == 1) {
|
if (ftdm_channel_call_check_hold(sigmsg->channel) && tokencount == 1) {
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
|
if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
|
||||||
|
@ -1636,10 +1638,9 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||||
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
|
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
|
||||||
switch_core_session_rwunlock(session);
|
switch_core_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
} else if (tokencount == 2 && (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)) {
|
} else if (tokencount == 2 && (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)) {
|
||||||
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_3WAY)) {
|
if (switch_test_flag(chanpvt, ANALOG_OPTION_3WAY)) {
|
||||||
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_3WAY);
|
switch_clear_flag(chanpvt, ANALOG_OPTION_3WAY);
|
||||||
if ((session = ftdm_channel_get_session(sigmsg->channel, 1))) {
|
if ((session = ftdm_channel_get_session(sigmsg->channel, 1))) {
|
||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||||
|
@ -1649,8 +1650,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||||
cycle_foreground(sigmsg->channel, 1, NULL);
|
cycle_foreground(sigmsg->channel, 1, NULL);
|
||||||
} else {
|
} else {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
cmd = switch_mprintf("three_way::%s", sigmsg->channel->tokens[0]);
|
cmd = switch_mprintf("three_way::%s", ftdm_channel_get_token(sigmsg->channel, 0));
|
||||||
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_3WAY);
|
switch_set_flag(chanpvt, ANALOG_OPTION_3WAY);
|
||||||
cycle_foreground(sigmsg->channel, 1, cmd);
|
cycle_foreground(sigmsg->channel, 1, cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
|
@ -1661,7 +1662,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||||
if (tokencount == 1) {
|
if (tokencount == 1) {
|
||||||
ftdm_channel_call_hold(sigmsg->channel);
|
ftdm_channel_call_hold(sigmsg->channel);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2160,6 +2160,8 @@ static switch_status_t load_config(void)
|
||||||
ftdm_span_t *boost_span = NULL;
|
ftdm_span_t *boost_span = NULL;
|
||||||
unsigned boosti = 0;
|
unsigned boosti = 0;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
ftdm_channel_t *fchan = NULL;
|
||||||
|
unsigned int chancount = 0;
|
||||||
|
|
||||||
memset(boost_spans, 0, sizeof(boost_spans));
|
memset(boost_spans, 0, sizeof(boost_spans));
|
||||||
memset(&globals, 0, sizeof(globals));
|
memset(&globals, 0, sizeof(globals));
|
||||||
|
@ -2366,7 +2368,7 @@ static switch_status_t load_config(void)
|
||||||
"hotline", hotline,
|
"hotline", hotline,
|
||||||
"enable_callerid", enable_callerid,
|
"enable_callerid", enable_callerid,
|
||||||
FTDM_TAG_END) != FTDM_SUCCESS) {
|
FTDM_TAG_END) != FTDM_SUCCESS) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM span %d\n", span_id);
|
ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2375,6 +2377,12 @@ static switch_status_t load_config(void)
|
||||||
switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
|
switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
|
||||||
SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options;
|
SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options;
|
||||||
|
|
||||||
|
chancount = ftdm_span_get_chan_count(span);
|
||||||
|
for (i = 1; i <= chancount; i++) {
|
||||||
|
fchan = ftdm_span_get_channel(span, i);
|
||||||
|
ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (dial_regex) {
|
if (dial_regex) {
|
||||||
switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
|
switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1002,6 +1002,16 @@ FT_DECLARE(void) ftdm_channel_replace_token(ftdm_channel_t *ftdmchan, const char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(void) ftdm_channel_set_private(ftdm_channel_t *ftdmchan, void *pvt)
|
||||||
|
{
|
||||||
|
ftdmchan->user_private = pvt;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(void *) ftdm_channel_get_private(const ftdm_channel_t *ftdmchan)
|
||||||
|
{
|
||||||
|
return ftdmchan->user_private;
|
||||||
|
}
|
||||||
|
|
||||||
FT_DECLARE(uint32_t) ftdm_channel_get_token_count(const ftdm_channel_t *ftdmchan)
|
FT_DECLARE(uint32_t) ftdm_channel_get_token_count(const ftdm_channel_t *ftdmchan)
|
||||||
{
|
{
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
|
@ -1747,7 +1757,7 @@ FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_hold(const ftdm_channel_t *ftdmc
|
||||||
{
|
{
|
||||||
ftdm_bool_t condition;
|
ftdm_bool_t condition;
|
||||||
ftdm_channel_lock(ftdmchan);
|
ftdm_channel_lock(ftdmchan);
|
||||||
condition = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD);
|
condition = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD) ? FTDM_TRUE : FTDM_FALSE;
|
||||||
ftdm_channel_unlock(ftdmchan);
|
ftdm_channel_unlock(ftdmchan);
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
@ -1801,7 +1811,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char *
|
||||||
{
|
{
|
||||||
ftdm_channel_lock(ftdmchan);
|
ftdm_channel_lock(ftdmchan);
|
||||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_HOLD);
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_HOLD);
|
||||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALTONE, 1);
|
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALTONE, 0);
|
||||||
ftdm_channel_unlock(ftdmchan);
|
ftdm_channel_unlock(ftdmchan);
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1809,9 +1819,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char *
|
||||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
|
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
|
||||||
{
|
{
|
||||||
ftdm_channel_lock(ftdmchan);
|
ftdm_channel_lock(ftdmchan);
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD)) {
|
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 0);
|
||||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
|
|
||||||
}
|
|
||||||
ftdm_channel_unlock(ftdmchan);
|
ftdm_channel_unlock(ftdmchan);
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1820,15 +1828,11 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
|
||||||
{
|
{
|
||||||
ftdm_channel_lock(ftdmchan);
|
ftdm_channel_lock(ftdmchan);
|
||||||
|
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED)) {
|
|
||||||
ftdm_channel_unlock(ftdmchan);
|
|
||||||
return FTDM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
|
||||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
|
||||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
|
||||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
|
||||||
|
|
||||||
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||||
ftdm_channel_unlock(ftdmchan);
|
ftdm_channel_unlock(ftdmchan);
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -691,8 +691,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) {
|
if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "READ ERROR [%s]\n", ftdmchan->last_error);
|
ftdm_log(FTDM_LOG_WARNING, "read error [%s]\n", ftdmchan->last_error);
|
||||||
goto done;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdmchan->detected_tones[0]) {
|
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdmchan->detected_tones[0]) {
|
||||||
|
|
|
@ -658,6 +658,24 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa
|
||||||
/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
|
/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
|
||||||
FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
|
FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set user private data in the channel
|
||||||
|
*
|
||||||
|
* \param ftdmchan The channel where the private data will be stored
|
||||||
|
* \param pvt The private pointer to store
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FT_DECLARE(void) ftdm_channel_set_private(ftdm_channel_t *ftdmchan, void *pvt);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get user private data in the channel
|
||||||
|
*
|
||||||
|
* \param ftdmchan The channel to retrieve the private data
|
||||||
|
* \retval The private data (if any or NULL if no data has been stored)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FT_DECLARE(void *) ftdm_channel_get_private(const ftdm_channel_t *ftdmchan);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Remove the given token from the channel
|
* \brief Remove the given token from the channel
|
||||||
*
|
*
|
||||||
|
|
|
@ -407,6 +407,7 @@ struct ftdm_channel {
|
||||||
uint8_t txgain_table[FTDM_GAINS_TABLE_SIZE];
|
uint8_t txgain_table[FTDM_GAINS_TABLE_SIZE];
|
||||||
float rxgain;
|
float rxgain;
|
||||||
float txgain;
|
float txgain;
|
||||||
|
void *user_private;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ftdm_span {
|
struct ftdm_span {
|
||||||
|
|
Loading…
Reference in New Issue