forked from Mirrors/freeswitch
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_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 {
|
||||
TFLAG_IO = (1 << 0),
|
||||
TFLAG_DTMF = (1 << 1),
|
||||
@ -95,6 +82,7 @@ static struct {
|
||||
switch_hash_t *ss7_configs;
|
||||
} globals;
|
||||
|
||||
/* private data attached to each fs session */
|
||||
struct private_object {
|
||||
unsigned int flags;
|
||||
switch_codec_t read_codec;
|
||||
@ -114,8 +102,26 @@ struct private_object {
|
||||
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;
|
||||
|
||||
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_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) {
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
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);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1514,7 +1510,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||
spanid = ftdm_channel_get_span_id(sigmsg->channel);
|
||||
tokencount = ftdm_channel_get_token_count(sigmsg->channel);
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "got FXS sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "got FXS sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id));
|
||||
|
||||
switch(sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_UP:
|
||||
@ -1621,6 +1617,12 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||
break;
|
||||
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) {
|
||||
switch_core_session_t *session;
|
||||
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_core_session_rwunlock(session);
|
||||
}
|
||||
#if 0
|
||||
} else if (tokencount == 2 && (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)) {
|
||||
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_3WAY)) {
|
||||
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_3WAY);
|
||||
if (switch_test_flag(chanpvt, ANALOG_OPTION_3WAY)) {
|
||||
switch_clear_flag(chanpvt, ANALOG_OPTION_3WAY);
|
||||
if ((session = ftdm_channel_get_session(sigmsg->channel, 1))) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
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);
|
||||
} else {
|
||||
char *cmd;
|
||||
cmd = switch_mprintf("three_way::%s", sigmsg->channel->tokens[0]);
|
||||
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_3WAY);
|
||||
cmd = switch_mprintf("three_way::%s", ftdm_channel_get_token(sigmsg->channel, 0));
|
||||
switch_set_flag(chanpvt, ANALOG_OPTION_3WAY);
|
||||
cycle_foreground(sigmsg->channel, 1, cmd);
|
||||
free(cmd);
|
||||
}
|
||||
@ -1661,7 +1662,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||
if (tokencount == 1) {
|
||||
ftdm_channel_call_hold(sigmsg->channel);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@ -2160,6 +2160,8 @@ static switch_status_t load_config(void)
|
||||
ftdm_span_t *boost_span = NULL;
|
||||
unsigned boosti = 0;
|
||||
unsigned int i = 0;
|
||||
ftdm_channel_t *fchan = NULL;
|
||||
unsigned int chancount = 0;
|
||||
|
||||
memset(boost_spans, 0, sizeof(boost_spans));
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
@ -2366,7 +2368,7 @@ static switch_status_t load_config(void)
|
||||
"hotline", hotline,
|
||||
"enable_callerid", enable_callerid,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2375,6 +2377,12 @@ static switch_status_t load_config(void)
|
||||
switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
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_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);
|
||||
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_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);
|
||||
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)
|
||||
{
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD)) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
|
||||
}
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 0);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
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);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED)) {
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
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) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "READ ERROR [%s]\n", ftdmchan->last_error);
|
||||
goto done;
|
||||
ftdm_log(FTDM_LOG_WARNING, "read error [%s]\n", ftdmchan->last_error);
|
||||
continue;
|
||||
}
|
||||
|
||||
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) */
|
||||
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
|
||||
*
|
||||
|
@ -407,6 +407,7 @@ struct ftdm_channel {
|
||||
uint8_t txgain_table[FTDM_GAINS_TABLE_SIZE];
|
||||
float rxgain;
|
||||
float txgain;
|
||||
void *user_private;
|
||||
};
|
||||
|
||||
struct ftdm_span {
|
||||
|
Loading…
Reference in New Issue
Block a user