mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-24 20:24:16 +00:00
Merge branch 'moy.nonblocking-api'
Conflicts: libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
This commit is contained in:
commit
1334d02ac0
32 files changed
+1614
-2549
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ typedef struct ftdm_r2_call_t {
|
||||
int disconnect_rcvd:1;
|
||||
int ftdm_call_started:1;
|
||||
int protocol_error:1;
|
||||
ftdm_channel_state_t chanstate;
|
||||
ftdm_size_t dnis_index;
|
||||
ftdm_size_t ani_index;
|
||||
char logname[255];
|
||||
@@ -168,8 +167,7 @@ static ftdm_hash_t *g_mod_data_hash;
|
||||
/* IO interface for the command API */
|
||||
static ftdm_io_interface_t g_ftdm_r2_interface;
|
||||
|
||||
static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* whether R2 call accept process is pending */
|
||||
#define IS_ACCEPTING_PENDING(ftdmchan) \
|
||||
@@ -349,7 +347,6 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call)
|
||||
call->disconnect_rcvd = 0;
|
||||
call->ftdm_call_started = 0;
|
||||
call->protocol_error = 0;
|
||||
call->chanstate = FTDM_CHANNEL_STATE_DOWN;
|
||||
call->dnis_index = 0;
|
||||
call->ani_index = 0;
|
||||
call->name[0] = 0;
|
||||
@@ -479,7 +476,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
||||
}
|
||||
|
||||
R2CALL(ftdmchan)->ftdm_call_started = 1;
|
||||
R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
|
||||
|
||||
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
|
||||
@@ -624,7 +620,7 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
ftdm_sched_cancel_timer(r2data->sched, r2call->protocol_error_recovery_timer);
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancelled protocol error recovery timer\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,7 +654,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size);
|
||||
}
|
||||
|
||||
R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
|
||||
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL);
|
||||
@@ -708,12 +703,10 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons
|
||||
static void clear_accept_pending(ftdm_channel_t *fchan)
|
||||
{
|
||||
if (IS_ACCEPTING_PENDING(fchan)) {
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(fchan);
|
||||
} else if (ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "State change flag set in state %s, last state = %s\n",
|
||||
ftdm_channel_state2str(fchan->state), ftdm_channel_state2str(fchan->last_state));
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(fchan);
|
||||
}
|
||||
}
|
||||
@@ -821,7 +814,7 @@ static void ftdm_r2_on_call_end(openr2_chan_t *r2chan)
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
|
||||
/* in some circumstances openr2 can call on_call_init right after this, so let's advance the state right here */
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
}
|
||||
|
||||
static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
|
||||
@@ -853,7 +846,7 @@ static void ftdm_r2_recover_from_protocol_error(void *data)
|
||||
goto done;
|
||||
}
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
done:
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
@@ -1617,10 +1610,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
|
||||
span->set_channel_sig_status = ftdm_r2_set_channel_sig_status;
|
||||
|
||||
span->state_map = &r2_state_map;
|
||||
span->state_processor = ftdm_r2_state_advance;
|
||||
|
||||
/* use signals queue */
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
|
||||
|
||||
/* we can skip states (going straight from RING to UP) */
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES);
|
||||
|
||||
/* setup the scheduler */
|
||||
snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name);
|
||||
ftdm_assert(ftdm_sched_create(&r2data->sched, schedname) == FTDM_SUCCESS, "Failed to create schedule!\n");
|
||||
@@ -1643,10 +1640,10 @@ fail:
|
||||
}
|
||||
|
||||
/* the channel must be locked when calling this function */
|
||||
static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
int ret;
|
||||
ftdm_status_t ret;
|
||||
ftdm_r2_call_t *r2call = R2CALL(ftdmchan);
|
||||
openr2_chan_t *r2chan = r2call->r2chan;
|
||||
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
@@ -1656,183 +1653,173 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
|
||||
ret = 0;
|
||||
ret = FTDM_SUCCESS;
|
||||
|
||||
/* because we do not always acknowledge the state change (clearing the FTDM_CHANNEL_STATE_CHANGE flag) due to the accept
|
||||
* procedure described below, we need the chanstate member to NOT process some states twice, so is valid entering this
|
||||
* function with the FTDM_CHANNEL_STATE_CHANGE flag set but with a state that was already processed and is just waiting
|
||||
* to complete (the processing is media-bound)
|
||||
* */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)
|
||||
&& (r2call->chanstate != ftdmchan->state)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
r2call->chanstate = ftdmchan->state;
|
||||
|
||||
if (IS_ACCEPTING_PENDING(ftdmchan)) {
|
||||
/*
|
||||
Moving to PROGRESS, PROGRESS_MEDIA or UP means that we must accept the call first, and accepting
|
||||
the call in R2 means sending a tone, then waiting for the acknowledge from the other end,
|
||||
since all of that requires sending and detecting tones, it takes a few milliseconds (I'd say around 100)
|
||||
which means during that time the user should not try to perform any operations like answer, hangup or anything
|
||||
else, therefore we DO NOT clear the FTDM_CHANNEL_STATE_CHANGE flag here, we rely on ftdm_io.c to block
|
||||
the user thread until we're done with the accept (see on_call_accepted callback) and then we clear the state change flag,
|
||||
otherwise we have a race condition between freetdm calling openr2_chan_answer_call and openr2 accepting the call first,
|
||||
if freetdm calls openr2_chan_answer_call before the accept cycle completes, openr2 will fail to answer the call */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "State ack for state %s will have to wait a bit\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
}
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
|
||||
/* starting an incoming call */
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting processing of incoming call with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* starting an outgoing call */
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan,
|
||||
FTDM_LOG_DEBUG, "Starting processing of outgoing call in channel with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* incoming call was offered */
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
|
||||
/* notify the user about the new call */
|
||||
sigev.event_id = FTDM_SIGEVENT_START;
|
||||
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
r2call->ftdm_call_started = 1;
|
||||
|
||||
break;
|
||||
|
||||
/* the call is making progress */
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
{
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n");
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_PROCEED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* the call was answered */
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n");
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n");
|
||||
// the answering will be done in the on_call_accepted handler
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
r2call->answer_pending = 1;
|
||||
} else {
|
||||
ft_r2_answer_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying of call answered\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* just got hangup */
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
{
|
||||
if (!r2call->disconnect_rcvd) {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* this will disconnect the call, but need to wait for the call end before moving to DOWN */
|
||||
openr2_chan_disconnect_call(r2chan, disconnect_cause);
|
||||
} else if (!r2call->protocol_error) {
|
||||
/* just ack the hangup, on_call_end will be called by openr2 right after */
|
||||
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n");
|
||||
/* do not set to down yet, give some time for recovery */
|
||||
ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100,
|
||||
ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
/* if the call has not been started yet we must go to HANGUP right here */
|
||||
if (!r2call->ftdm_call_started) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
} else {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* notify the user of the call terminating and we wait for the user to move us to hangup */
|
||||
sigev.event_id = FTDM_SIGEVENT_STOP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* finished call for good */
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_RESET) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n");
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n");
|
||||
}
|
||||
break;
|
||||
|
||||
/* put the r2 channel back to IDLE, close ftdmchan and set it's state as DOWN */
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RESET indicated, putting the R2 channel back to IDLE\n");
|
||||
openr2_chan_set_idle(r2chan);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
if (IS_ACCEPTING_PENDING(ftdmchan)) {
|
||||
/*
|
||||
Moving to PROGRESS, PROGRESS_MEDIA or UP means that we must accept the call first, and accepting
|
||||
the call in R2 means sending a tone, then waiting for the acknowledge from the other end,
|
||||
since all of that requires sending and detecting tones, it takes a few milliseconds (I'd say around 100)
|
||||
which means during that time the user should not try to perform any operations like answer, hangup or anything
|
||||
else, therefore we DO NOT clear the FTDM_CHANNEL_STATE_CHANGE flag here, we rely on ftdm_io.c to block
|
||||
the user thread until we're done with the accept (see on_call_accepted callback) and then we clear the state change flag,
|
||||
otherwise we have a race condition between freetdm calling openr2_chan_answer_call and openr2 accepting the call first,
|
||||
if freetdm calls openr2_chan_answer_call before the accept cycle completes, openr2 will fail to answer the call */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "State ack for state %s will have to wait a bit\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
switch (ftdmchan->state) {
|
||||
|
||||
/* starting an incoming call */
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting processing of incoming call with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* starting an outgoing call */
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan,
|
||||
FTDM_LOG_DEBUG, "Starting processing of outgoing call in channel with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* incoming call was offered */
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
|
||||
/* notify the user about the new call */
|
||||
sigev.event_id = FTDM_SIGEVENT_START;
|
||||
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
r2call->ftdm_call_started = 1;
|
||||
|
||||
break;
|
||||
|
||||
/* the call is making progress */
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
{
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n");
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_PROCEED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* the call was answered */
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n");
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n");
|
||||
// the answering will be done in the on_call_accepted handler
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
r2call->answer_pending = 1;
|
||||
} else {
|
||||
ft_r2_answer_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying of call answered\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* just got hangup */
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
{
|
||||
if (!r2call->disconnect_rcvd) {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* this will disconnect the call, but need to wait for the call end before moving to DOWN */
|
||||
openr2_chan_disconnect_call(r2chan, disconnect_cause);
|
||||
} else if (!r2call->protocol_error) {
|
||||
/* just ack the hangup, on_call_end will be called by openr2 right after */
|
||||
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n");
|
||||
/* do not set to down yet, give some time for recovery */
|
||||
ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100,
|
||||
ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
/* if the call has not been started yet we must go to HANGUP right here */
|
||||
if (!r2call->ftdm_call_started) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
} else {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* notify the user of the call terminating and we wait for the user to move us to hangup */
|
||||
sigev.event_id = FTDM_SIGEVENT_STOP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* finished call for good */
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_RESET) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n");
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Reset Complete\n");
|
||||
}
|
||||
ret = FTDM_BREAK;
|
||||
}
|
||||
break;
|
||||
|
||||
/* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n");
|
||||
}
|
||||
break;
|
||||
|
||||
/* put the r2 channel back to IDLE, close ftdmchan and set it's state as DOWN */
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RESET indicated, putting the R2 channel back to IDLE\n");
|
||||
openr2_chan_set_idle(r2chan);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == FTDM_BREAK) {
|
||||
ftdm_channel_t *closed_chan;
|
||||
closed_chan = ftdmchan;
|
||||
ftdm_channel_close(&closed_chan);
|
||||
@@ -1841,20 +1828,6 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* the channel must be locked when calling this function */
|
||||
static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
/* because we do not always acknowledge the state change (clearing the FTDM_CHANNEL_STATE_CHANGE flag) due to the accept
|
||||
* procedure described below, we need the chanstate member to NOT process some states twice, so is valid entering this
|
||||
* function with the FTDM_CHANNEL_STATE_CHANGE flag set but with a state that was already processed and is just waiting
|
||||
* to complete (the processing is media-bound)
|
||||
* */
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)
|
||||
&& (R2CALL(ftdmchan)->chanstate != ftdmchan->state)) {
|
||||
ftdm_r2_state_advance(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
openr2_chan_t *r2chan = NULL;
|
||||
@@ -1983,12 +1956,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED);
|
||||
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
r2chan = call->r2chan;
|
||||
openr2_chan_process_signaling(r2chan);
|
||||
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
if (!call->accepted) {
|
||||
/* if the call is not accepted we do not want users reading */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -46,10 +46,9 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span);
|
||||
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span);
|
||||
|
||||
ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
static void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span);
|
||||
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event);
|
||||
static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan);
|
||||
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *ftdmchan);
|
||||
@@ -270,13 +269,6 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
||||
}
|
||||
};
|
||||
|
||||
static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_isdn_process_state_change(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
@@ -457,7 +449,7 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
||||
while ((ftdmchan = ftdm_queue_dequeue(span->pendingchans))) {
|
||||
/* double check that this channel has a state change pending */
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
ftdm_sangoma_isdn_advance_chan_states(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
|
||||
@@ -470,11 +462,11 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
||||
/* twiddle */
|
||||
break;
|
||||
case FTDM_FAIL:
|
||||
ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned error!\n", span->name);
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s: ftdm_interrupt_wait returned error!\n", span->name);
|
||||
break;
|
||||
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned with unknown code\n", span->name);
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s: ftdm_interrupt_wait returned with unknown code\n", span->name);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -536,7 +528,7 @@ ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisd
|
||||
break;
|
||||
}
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
ftdm_sangoma_isdn_advance_chan_states(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
return ftdmchan;
|
||||
}
|
||||
|
||||
@@ -600,13 +592,14 @@ static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_ev
|
||||
sngisdn_process_rst_ind(sngisdn_event);
|
||||
break;
|
||||
}
|
||||
if(ftdmchan != NULL) {
|
||||
ftdm_sangoma_isdn_advance_chan_states(ftdmchan);
|
||||
if (ftdmchan != NULL) {
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
/* this function is called with the channel already locked by the core */
|
||||
static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
ftdm_channel_state_t initial_state;
|
||||
@@ -618,13 +611,12 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
|
||||
/*first lock the channel*/
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
/*clear the state change flag...since we might be setting a new state*/
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
/* Acknowledge the state change */
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
|
||||
#ifdef FTDM_DEBUG_CHAN_MEMORY
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ)==0, "Failed to mprotect");
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ) == 0, "Failed to mprotect");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -879,11 +871,10 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
}
|
||||
#ifdef FTDM_DEBUG_CHAN_MEMORY
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ|PROT_WRITE)==0, "Failed to mprotect");
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ|PROT_WRITE) == 0, "Failed to mprotect");
|
||||
}
|
||||
#endif
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg)
|
||||
@@ -1098,6 +1089,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
||||
span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status;
|
||||
span->set_span_sig_status = ftdm_sangoma_isdn_set_span_sig_status;
|
||||
span->state_map = &sangoma_isdn_state_map;
|
||||
span->state_processor = ftdm_sangoma_isdn_process_state_change;
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
|
||||
|
||||
@@ -46,7 +46,6 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data;
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj);
|
||||
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
|
||||
@@ -308,9 +307,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* process state changes for this channel until they are all done */
|
||||
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_ss7_process_state_change (ftdmchan);
|
||||
}
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock (ftdmchan->mutex);
|
||||
@@ -403,9 +400,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* while there's a state change present on this channel process it */
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_ss7_process_state_change(ftdmchan);
|
||||
}
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
/* figure out the type of event and send it to the right handler */
|
||||
switch (sngss7_event->event_id) {
|
||||
@@ -468,9 +463,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
} /* switch (sngss7_event->event_id) */
|
||||
|
||||
/* while there's a state change present on this channel process it */
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_ss7_process_state_change(ftdmchan);
|
||||
}
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
@@ -479,7 +472,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
sng_isup_inf_t *isup_intf = NULL;
|
||||
@@ -495,7 +488,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
|
||||
|
||||
/* clear the state change flag...since we might be setting a new state */
|
||||
ftdm_clear_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
|
||||
/*check what state we are supposed to be in */
|
||||
switch (ftdmchan->state) {
|
||||
@@ -1212,7 +1205,7 @@ suspend_goto_restart:
|
||||
/**************************************************************************/
|
||||
}/*switch (ftdmchan->state) */
|
||||
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1476,6 +1469,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
|
||||
span->get_channel_sig_status = ftdm_sangoma_ss7_get_sig_status;
|
||||
span->set_channel_sig_status = ftdm_sangoma_ss7_set_sig_status;
|
||||
span->state_map = &sangoma_ss7_state_map;
|
||||
span->state_processor = ftdm_sangoma_ss7_process_state_change;
|
||||
span->signal_data = ss7_span_info;
|
||||
|
||||
/* set the flag to indicate that this span uses channel state change queues */
|
||||
|
||||
@@ -452,7 +452,7 @@ extern int cmbLinkSetId;
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
/* in ftmod_sangoma_ss7_main.c */
|
||||
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
|
||||
ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* in ftmod_sangoma_ss7_logger.c */
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
|
||||
Reference in new issue
Block a user