ftmod_libpri: Rewrite parts of hangup handling to fix hanging calls problem.
Let's hope this fixes it for good and doesn't introduce new problems. Tested-by: SparFux (#freetdm @ irc.freenode.net) Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
This commit is contained in:
parent
43442e4f41
commit
ccce356392
|
@ -562,14 +562,18 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
|
||||||
sig.chan_id = ftdm_channel_get_id(chan);
|
sig.chan_id = ftdm_channel_get_id(chan);
|
||||||
sig.span_id = ftdm_channel_get_span_id(chan);
|
sig.span_id = ftdm_channel_get_span_id(chan);
|
||||||
sig.channel = chan;
|
sig.channel = chan;
|
||||||
|
|
||||||
ftdm_channel_complete_state(chan);
|
ftdm_channel_complete_state(chan);
|
||||||
|
|
||||||
switch (ftdm_channel_get_state(chan)) {
|
switch (ftdm_channel_get_state(chan)) {
|
||||||
case FTDM_CHANNEL_STATE_DOWN:
|
case FTDM_CHANNEL_STATE_DOWN:
|
||||||
{
|
{
|
||||||
ftdm_channel_t *chtmp = chan;
|
ftdm_channel_t *chtmp = chan;
|
||||||
chan->call_data = NULL;
|
|
||||||
|
if (call) {
|
||||||
|
pri_destroycall(isdn_data->spri.pri, call);
|
||||||
|
chan->call_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
|
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
|
||||||
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
|
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
|
||||||
|
@ -776,8 +780,7 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
|
||||||
|
|
||||||
pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause);
|
pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause);
|
||||||
// pri_destroycall(isdn_data->spri.pri, call);
|
// pri_destroycall(isdn_data->spri.pri, call);
|
||||||
|
// chan->call_data = NULL;
|
||||||
chan->call_data = NULL;
|
|
||||||
}
|
}
|
||||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||||
}
|
}
|
||||||
|
@ -785,10 +788,10 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
|
||||||
|
|
||||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||||
{
|
{
|
||||||
if (call) {
|
// if (call) {
|
||||||
pri_destroycall(isdn_data->spri.pri, call);
|
// pri_destroycall(isdn_data->spri.pri, call);
|
||||||
chan->call_data = NULL;
|
// chan->call_data = NULL;
|
||||||
}
|
// }
|
||||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN);
|
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -862,18 +865,61 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
|
||||||
|
|
||||||
ftdm_channel_lock(chan);
|
ftdm_channel_lock(chan);
|
||||||
|
|
||||||
if (ftdm_channel_get_state(chan) >= FTDM_CHANNEL_STATE_TERMINATING) {
|
switch (event_type) {
|
||||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n", ftdm_channel_get_state_str(chan));
|
case LPWRAP_PRI_EVENT_HANGUP_REQ: /* DISCONNECT */
|
||||||
goto done;
|
if (ftdm_channel_get_state(chan) >= FTDM_CHANNEL_STATE_TERMINATING) {
|
||||||
|
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n",
|
||||||
|
ftdm_channel_get_state_str(chan));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup REQ on channel %d:%d\n",
|
||||||
|
ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||||
|
|
||||||
|
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
|
||||||
|
|
||||||
|
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||||
|
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LPWRAP_PRI_EVENT_HANGUP_ACK: /* */
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup ACK on channel %d:%d\n",
|
||||||
|
ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||||
|
|
||||||
|
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
|
||||||
|
|
||||||
|
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LPWRAP_PRI_EVENT_HANGUP: /* "RELEASE/RELEASE_COMPLETE/other" */
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n",
|
||||||
|
ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||||
|
|
||||||
|
switch (ftdm_channel_get_state(chan)) {
|
||||||
|
case FTDM_CHANNEL_STATE_DIALING:
|
||||||
|
case FTDM_CHANNEL_STATE_RINGING:
|
||||||
|
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||||
|
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||||
|
case FTDM_CHANNEL_STATE_PROCEED:
|
||||||
|
case FTDM_CHANNEL_STATE_UP:
|
||||||
|
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||||
|
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||||
|
break;
|
||||||
|
case FTDM_CHANNEL_STATE_HANGUP:
|
||||||
|
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||||
|
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||||
|
break;
|
||||||
|
// case FTDM_CHANNEL_STATE_TERMINATING:
|
||||||
|
// ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
|
// break;
|
||||||
|
// case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||||
|
// ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN);
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
|
||||||
|
|
||||||
pri_hangup(spri->pri, pevent->hangup.call, -1);
|
|
||||||
|
|
||||||
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
|
||||||
chan->call_data = NULL;
|
|
||||||
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
|
||||||
done:
|
done:
|
||||||
ftdm_channel_unlock(chan);
|
ftdm_channel_unlock(chan);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1644,6 +1690,7 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
|
||||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_UP, on_dchan_up);
|
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_UP, on_dchan_up);
|
||||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_DOWN, on_dchan_down);
|
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_DOWN, on_dchan_down);
|
||||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_REQ, on_hangup);
|
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_REQ, on_hangup);
|
||||||
|
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_ACK, on_hangup);
|
||||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP, on_hangup);
|
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP, on_hangup);
|
||||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_INFO_RECEIVED, on_info);
|
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_INFO_RECEIVED, on_info);
|
||||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RESTART, on_restart);
|
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RESTART, on_restart);
|
||||||
|
|
Loading…
Reference in New Issue