freetdm: - updated all signaling modules (except for ftmod_isdn and ftmod_sangoma_ss7) to adapt to new core state processing

- fixed bug in configure.ac to detect ftmod_pritap compilation
         - ignore FTDM_SIGEVENT_RELEASED and FTDM_SIGEVENT_INDICATION_COMPLETED in mod_freetdm
         - Destroy the state completed interrupt on channel destroy
         - Fix analog polarity reversal bug when using 3-way calling or call-swap
This commit is contained in:
Moises Silva 2010-12-31 13:44:20 -05:00
parent 39d58e0452
commit fe0d8d1ec5
11 changed files with 65 additions and 68 deletions

View File

@ -160,7 +160,7 @@ AC_ARG_WITH([pritap],
[AS_HELP_STRING([--with-pritap], [Install ftmod_pritap])],
[case "${withval}" in
no) enable_pritap="no" ;;
*) enable_pritab="yes" ;;
*) enable_pritap="yes" ;;
esac],
[enable_pritap="no"]
)

View File

@ -1642,6 +1642,14 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
}
return FTDM_SUCCESS;
}
case FTDM_SIGEVENT_RELEASED:
case FTDM_SIGEVENT_INDICATION_COMPLETED:
{
/* Swallow these events */
return FTDM_BREAK;
}
break;
default:
return FTDM_SUCCESS;
break;
@ -1732,7 +1740,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
}
}
break;
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { /* twiddle */ } break;
default:
@ -1788,7 +1795,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
}
}
break;
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
case FTDM_SIGEVENT_STOP:
{
@ -2015,8 +2021,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
}
break;
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
/* on DNIS received from the R2 forward side, return status == FTDM_BREAK to stop requesting DNIS */
case FTDM_SIGEVENT_COLLECTED_DIGIT:
{
@ -2135,8 +2139,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
}
break;
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
case FTDM_SIGEVENT_STOP:
case FTDM_SIGEVENT_RESTART:
{

View File

@ -615,6 +615,9 @@ static ftdm_status_t ftdm_channel_destroy(ftdm_channel_t *ftdmchan)
ftdm_mutex_destroy(&ftdmchan->mutex);
ftdm_mutex_destroy(&ftdmchan->pre_buffer_mutex);
if (ftdmchan->state_completed_interrupt) {
ftdm_interrupt_destroy(&ftdmchan->state_completed_interrupt);
}
}
return FTDM_SUCCESS;

View File

@ -103,7 +103,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
if (ftdm_test_flag(fchan, FTDM_CHANNEL_BLOCKING)) {
ftdm_clear_flag(fchan, FTDM_CHANNEL_BLOCKING);
ftdm_interrupt_signal(fchan->state_change_notify);
ftdm_interrupt_signal(fchan->state_completed_interrupt);
}
return FTDM_SUCCESS;
@ -194,8 +194,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *f
return FTDM_FAIL;
}
if (!ftdmchan->state_change_notify) {
status = ftdm_interrupt_create(&ftdmchan->state_change_notify, FTDM_INVALID_SOCKET);
if (!ftdmchan->state_completed_interrupt) {
status = ftdm_interrupt_create(&ftdmchan->state_completed_interrupt, FTDM_INVALID_SOCKET);
if (status != FTDM_SUCCESS) {
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_CRIT,
"Failed to create state change interrupt when moving from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
@ -323,17 +323,23 @@ end:
goto done;
}
if (!waitrq) {
/* no waiting was requested */
goto done;
}
/* let's wait for the state change to be completed by the signaling stack */
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_BLOCKING);
ftdm_mutex_unlock(ftdmchan->mutex);
status = ftdm_interrupt_wait(ftdmchan->state_change_notify, waitms);
status = ftdm_interrupt_wait(ftdmchan->state_completed_interrupt, waitms);
ftdm_mutex_lock(ftdmchan->mutex);
if (status != FTDM_SUCCESS) {
ftdm_log_chan_ex(ftdmchan, file, func, line,
FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not processed after aprox %dms\n",
FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not completed after aprox %dms\n",
ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME);
ok = 0;
goto done;
@ -437,6 +443,8 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan)
{
ftdm_channel_state_t state;
ftdm_assert_return(fchan->span->state_processor, FTDM_FAIL, "Cannot process states without a state processor!\n");
while (fchan->state_status == FTDM_STATE_STATUS_NEW) {
state = fchan->state;

View File

@ -585,8 +585,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
if (done) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
ftdm_channel_complete_state(ftdmchan);
ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
}
}
@ -628,7 +628,6 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
break;
}
} else {
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
ftdm_channel_complete_state(ftdmchan);
indicate = 0;
@ -672,11 +671,12 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) &&
ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) {
ftdm_polarity_t polarity = FTDM_POLARITY_REVERSE;
if (ftdmchan->polarity != FTDM_POLARITY_FORWARD) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Polarity is already reversed on answer??\n");
} else {
if (ftdmchan->polarity == FTDM_POLARITY_FORWARD) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on answer\n");
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity);
} else {
/* the polarity may be already reversed if this is the second time we
* answer (ie, due to 2 calls being on the same line) */
}
}
@ -1036,8 +1036,8 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) {
if (event->channel->state == FTDM_CHANNEL_STATE_HANGUP &&
ftdm_test_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE);
/* we do not need to process HANGUP since the device also hangup already */
ftdm_channel_complete_state(event->channel);
}
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
}
@ -1052,8 +1052,8 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
{
if (event->channel->state == FTDM_CHANNEL_STATE_CALLWAITING) {
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP);
ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE);
ftdm_clear_flag(event->channel->span, FTDM_SPAN_STATE_CHANGE);
ftdm_channel_complete_state(event->channel);
event->channel->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
}

View File

@ -355,7 +355,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
break;
}
} else {
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
ftdm_channel_complete_state(ftdmchan);
indicate = 0;

View File

@ -497,7 +497,7 @@ static ftdm_state_map_t isdn_state_map = {
* \param ftdmchan Channel to handle
* \note This function MUST be called with the channel locked
*/
static __inline__ void state_advance(ftdm_channel_t *chan)
static ftdm_status_t state_advance(ftdm_channel_t *chan)
{
ftdm_libpri_data_t *isdn_data = chan->span->signal_data;
q931_call *call = (q931_call *)chan->call_data;
@ -511,6 +511,8 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
sig.chan_id = ftdm_channel_get_id(chan);
sig.span_id = ftdm_channel_get_span_id(chan);
sig.channel = chan;
ftdm_channel_complete_state(chan);
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_DOWN:
@ -625,7 +627,7 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan));
/* TODO: set hangup cause? */
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
return;
return FTDM_SUCCESS;
}
ton = caller_data->dnis.type;
@ -708,6 +710,7 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
default:
break;
}
return FTDM_SUCCESS;
}
/**
@ -723,13 +726,8 @@ static __inline__ void check_state(ftdm_span_t *span)
for (j = 1; j <= ftdm_span_get_chan_count(span); j++) {
ftdm_channel_t *chan = ftdm_span_get_channel(span, j);
ftdm_channel_lock(chan);
while (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE);
state_advance(chan);
ftdm_channel_complete_state(chan);
}
ftdm_channel_advance_states(chan);
ftdm_channel_unlock(chan);
}
}
@ -1910,6 +1908,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
span->outgoing_call = isdn_outgoing_call;
span->state_map = &isdn_state_map;
span->state_processor = state_advance;
span->get_channel_sig_status = isdn_get_channel_sig_status;
span->get_span_sig_status = isdn_get_span_sig_status;

View File

@ -265,7 +265,7 @@ static ftdm_state_map_t pritap_state_map = {
}
};
static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
{
ftdm_status_t status;
ftdm_sigmsg_t sig;
@ -278,6 +278,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
sig.span_id = ftdmchan->span_id;
sig.channel = ftdmchan;
ftdm_channel_complete_state(ftdmchan);
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN:
{
@ -321,24 +323,20 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
break;
}
return;
return FTDM_SUCCESS;
}
static __inline__ void pritap_check_state(ftdm_span_t *span)
{
if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
uint32_t j;
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
for(j = 1; j <= span->chan_count; j++) {
if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_mutex_lock(span->channels[j]->mutex);
ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
state_advance(span->channels[j]);
ftdm_channel_complete_state(span->channels[j]);
ftdm_mutex_unlock(span->channels[j]->mutex);
}
}
}
if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
uint32_t j;
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
for(j = 1; j <= span->chan_count; j++) {
ftdm_mutex_lock(span->channels[j]->mutex);
ftdm_channel_advance_states(span->channels[j]);
ftdm_mutex_unlock(span->channels[j]->mutex);
}
}
}
static int pri_io_read(struct pri *pri, void *buf, int buflen)
@ -896,6 +894,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
span->get_span_sig_status = pritap_get_span_sig_status;
span->state_map = &pritap_state_map;
span->state_processor = state_advance;
return FTDM_SUCCESS;
}

View File

@ -951,7 +951,6 @@ static void handle_call_answer(ftdm_span_t *span, sangomabc_connection_t *mcon,
}
}
static __inline__ void advance_chan_states(ftdm_channel_t *ftdmchan);
static __inline__ void stop_loop(ftdm_channel_t *ftdmchan);
/**
@ -1002,7 +1001,7 @@ tryagain:
} else if (ftdmchan->state == FTDM_CHANNEL_STATE_IN_LOOP && retry) {
retry = 0;
stop_loop(ftdmchan);
advance_chan_states(ftdmchan);
ftdm_channel_advance_states(ftdmchan);
goto tryagain;
} else {
ftdm_log(FTDM_LOG_ERROR, "s%dc%d: rejecting incoming call in channel state %s\n",
@ -1267,7 +1266,7 @@ static ftdm_channel_t* event_process_states(ftdm_span_t *span, sangomabc_short_e
}
ftdm_mutex_lock(ftdmchan->mutex);
advance_chan_states(ftdmchan);
ftdm_channel_advance_states(ftdmchan);
return ftdmchan;
}
@ -1354,11 +1353,11 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon,
}
if(ftdmchan != NULL) {
advance_chan_states(ftdmchan);
ftdm_channel_advance_states(ftdmchan);
ftdm_mutex_unlock(ftdmchan->mutex);
}
return 0;
return 0;
}
@ -1366,7 +1365,7 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon,
* \brief Handler for channel state change
* \param ftdmchan Channel to handle
*/
static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
{
ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data;
sangomabc_connection_t *mcon = &sangoma_boost_data->mcon;
@ -1374,12 +1373,6 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
ftdm_status_t status;
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
} else {
return FTDM_SUCCESS;
}
ftdm_assert_return(ftdmchan->last_state != ftdmchan->state, FTDM_FAIL, "Channel state already processed\n");
ftdm_log(FTDM_LOG_DEBUG, "%d:%d PROCESSING STATE [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state));
@ -1389,6 +1382,8 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
sig.span_id = ftdmchan->span_id;
sig.channel = ftdmchan;
ftdm_channel_complete_state(ftdmchan);
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN:
{
@ -1640,24 +1635,15 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
default:
break;
}
ftdm_channel_complete_state(ftdmchan);
return FTDM_SUCCESS;
}
static __inline__ void advance_chan_states(ftdm_channel_t *ftdmchan)
{
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
state_advance(ftdmchan);
}
}
/**
* \brief Initialises outgoing requests array
*/
static __inline__ void init_outgoing_array(void)
{
memset(&OUTBOUND_REQUESTS, 0, sizeof(OUTBOUND_REQUESTS));
}
/**
@ -1685,7 +1671,7 @@ static __inline__ void check_state(ftdm_span_t *span)
if (susp && span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) {
ftdm_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART);
}
state_advance(span->channels[j]);
ftdm_channel_advance_states(span->channels[j]);
ftdm_mutex_unlock(span->channels[j]->mutex);
}
}
@ -1695,7 +1681,7 @@ static __inline__ void check_state(ftdm_span_t *span)
* but without taking the chan out of the queue, so check th
* flag before advancing the state */
ftdm_mutex_lock(ftdmchan->mutex);
state_advance(ftdmchan);
ftdm_channel_advance_states(ftdmchan);
ftdm_mutex_unlock(ftdmchan->mutex);
}
}
@ -2687,6 +2673,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span)
span->get_span_sig_status = sangoma_boost_get_span_sig_status;
span->set_span_sig_status = sangoma_boost_set_span_sig_status;
span->state_map = &boost_state_map;
span->state_processor = state_advance;
sangoma_boost_data->mcon.debuglevel = FTDM_LOG_LEVEL_DEBUG;
sangoma_boost_data->pcon.debuglevel = FTDM_LOG_LEVEL_DEBUG;
ftdm_clear_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);

View File

@ -583,10 +583,10 @@ typedef enum {
FTDM_COMMAND_GET_LINK_STATUS,
FTDM_COMMAND_ENABLE_LOOP,
FTDM_COMMAND_DISABLE_LOOP,
FTDM_COMMAND_COUNT,
FTDM_COMMAND_SET_RX_QUEUE_SIZE,
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
FTDM_COMMAND_SET_POLARITY,
FTDM_COMMAND_COUNT,
} ftdm_command_t;
typedef enum {

View File

@ -462,7 +462,7 @@ struct ftdm_channel {
ftdm_dtmf_debug_t dtmfdbg;
ftdm_io_dump_t rxdump;
ftdm_io_dump_t txdump;
ftdm_interrupt_t *state_change_notify; /*!< Notify when a state change is terminated */
ftdm_interrupt_t *state_completed_interrupt; /*!< Notify when a state change is completed */
int32_t txdrops;
int32_t rxdrops;
};