freetdm: add pvt data to freetdm channels

fix fxs features
This commit is contained in:
Moises Silva 2010-05-20 11:43:40 -04:00
parent 70bf7a0a6f
commit 9d45690006
5 changed files with 76 additions and 45 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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]) {

View File

@ -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
*

View File

@ -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 {