mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-03 17:30:37 +00:00
ftmod_isdn: Fix channel state handling in NT mode w/ early disconnect.
In this particular case: NO_ROUTE_DESTINATION caused by missing context. Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
This commit is contained in:
parent
c6cf92d766
commit
964d14c012
@ -599,7 +599,9 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) {
|
if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN &&
|
||||||
|
ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_HANGUP_COMPLETE)
|
||||||
|
{
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d not in DOWN state, cleaning up\n",
|
ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d not in DOWN state, cleaning up\n",
|
||||||
ftdm_channel_get_span_id(ftdmchan),
|
ftdm_channel_get_span_id(ftdmchan),
|
||||||
ftdm_channel_get_id(ftdmchan));
|
ftdm_channel_get_id(ftdmchan));
|
||||||
@ -1320,6 +1322,9 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
sig.chan_id = ftdm_channel_get_id(ftdmchan);
|
sig.chan_id = ftdm_channel_get_id(ftdmchan);
|
||||||
sig.channel = ftdmchan;
|
sig.channel = ftdmchan;
|
||||||
|
|
||||||
|
/* Acknowledge channel state change */
|
||||||
|
ftdm_channel_complete_state(ftdmchan);
|
||||||
|
|
||||||
switch (ftdm_channel_get_state(ftdmchan)) {
|
switch (ftdm_channel_get_state(ftdmchan)) {
|
||||||
case FTDM_CHANNEL_STATE_DOWN:
|
case FTDM_CHANNEL_STATE_DOWN:
|
||||||
{
|
{
|
||||||
@ -1336,7 +1341,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||||
sig.event_id = FTDM_SIGEVENT_PROGRESS;
|
sig.event_id = FTDM_SIGEVENT_PROGRESS;
|
||||||
if ((status = ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig) != FTDM_SUCCESS)) {
|
if ((status = ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig) != FTDM_SUCCESS)) {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gen->MesType = Q931mes_CALL_PROCEEDING;
|
gen->MesType = Q931mes_CALL_PROCEEDING;
|
||||||
@ -1379,7 +1384,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||||
sig.event_id = FTDM_SIGEVENT_START;
|
sig.event_id = FTDM_SIGEVENT_START;
|
||||||
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
|
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1389,7 +1394,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED;
|
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED;
|
||||||
sig.event_id = FTDM_SIGEVENT_RESTART;
|
sig.event_id = FTDM_SIGEVENT_RESTART;
|
||||||
status = ftdm_span_send_signal(span, &sig);
|
status = ftdm_span_send_signal(span, &sig);
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||||
@ -1397,12 +1402,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||||
sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
||||||
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
|
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
|
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
|
||||||
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
|
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1416,12 +1421,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||||
sig.event_id = FTDM_SIGEVENT_UP;
|
sig.event_id = FTDM_SIGEVENT_UP;
|
||||||
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
|
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
|
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
|
||||||
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
|
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1564,7 +1569,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
|
|
||||||
Q931Rx43(&isdn_data->q931, gen, gen->Size);
|
Q931Rx43(&isdn_data->q931, gen, gen->Size);
|
||||||
}
|
}
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FTDM_CHANNEL_STATE_HANGUP:
|
case FTDM_CHANNEL_STATE_HANGUP:
|
||||||
@ -1572,7 +1577,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
|
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
|
||||||
Q931ie_Cause cause;
|
Q931ie_Cause cause;
|
||||||
|
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "Hangup: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
|
ftdm_log(FTDM_LOG_DEBUG, "Hangup: Call direction %s\n",
|
||||||
|
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
|
||||||
|
|
||||||
cause.IEId = Q931ie_CAUSE;
|
cause.IEId = Q931ie_CAUSE;
|
||||||
cause.Size = sizeof(Q931ie_Cause);
|
cause.Size = sizeof(Q931ie_Cause);
|
||||||
@ -1589,7 +1595,13 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
* inbound call [was: number unknown (= not found in routing state)]
|
* inbound call [was: number unknown (= not found in routing state)]
|
||||||
* (in Q.931 spec terms: Reject request)
|
* (in Q.931 spec terms: Reject request)
|
||||||
*/
|
*/
|
||||||
gen->MesType = Q931mes_RELEASE_COMPLETE;
|
if (!FTDM_SPAN_IS_NT(span)) {
|
||||||
|
gen->MesType = Q931mes_RELEASE_COMPLETE; /* TE mode: Reject call */
|
||||||
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||||
|
} else {
|
||||||
|
gen->MesType = Q931mes_DISCONNECT; /* NT mode: Disconnect and wait */
|
||||||
|
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
//cause.Value = (unsigned char) FTDM_CAUSE_UNALLOCATED;
|
//cause.Value = (unsigned char) FTDM_CAUSE_UNALLOCATED;
|
||||||
cause.Value = (unsigned char) caller_data->hangup_cause;
|
cause.Value = (unsigned char) caller_data->hangup_cause;
|
||||||
@ -1598,8 +1610,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
Q931Rx43(&isdn_data->q931, gen, gen->Size);
|
Q931Rx43(&isdn_data->q931, gen, gen->Size);
|
||||||
|
|
||||||
/* we're done, release channel */
|
/* we're done, release channel */
|
||||||
//ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
////ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||||
}
|
}
|
||||||
else if (ftdm_channel_get_last_state(ftdmchan) <= FTDM_CHANNEL_STATE_PROGRESS) {
|
else if (ftdm_channel_get_last_state(ftdmchan) <= FTDM_CHANNEL_STATE_PROGRESS) {
|
||||||
/*
|
/*
|
||||||
@ -1613,7 +1625,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
Q931Rx43(&isdn_data->q931, gen, gen->Size);
|
Q931Rx43(&isdn_data->q931, gen, gen->Size);
|
||||||
|
|
||||||
/* this will be triggered by the RELEASE_COMPLETE reply */
|
/* this will be triggered by the RELEASE_COMPLETE reply */
|
||||||
/* ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); */
|
/* ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/*
|
/*
|
||||||
@ -1630,7 +1642,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||||||
break;
|
break;
|
||||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||||
{
|
{
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "Terminating: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
|
ftdm_log(FTDM_LOG_DEBUG, "Terminating: Call direction %s\n",
|
||||||
|
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
|
||||||
|
|
||||||
sig.event_id = FTDM_SIGEVENT_STOP;
|
sig.event_id = FTDM_SIGEVENT_STOP;
|
||||||
status = ftdm_span_send_signal(span, &sig);
|
status = ftdm_span_send_signal(span, &sig);
|
||||||
@ -1655,11 +1668,8 @@ static __inline__ void check_state(ftdm_span_t *span)
|
|||||||
|
|
||||||
if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
|
if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||||
ftdm_channel_lock(chan);
|
ftdm_channel_lock(chan);
|
||||||
|
|
||||||
ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE);
|
ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE);
|
||||||
state_advance(chan);
|
state_advance(chan);
|
||||||
ftdm_channel_complete_state(chan);
|
|
||||||
|
|
||||||
ftdm_channel_unlock(chan);
|
ftdm_channel_unlock(chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user