Fix for calls not cleared on call abort
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@951 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
parent
29627360b5
commit
258e160057
|
@ -817,50 +817,57 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
|
||||
tech_pvt = (private_t *) switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
assert(tech_pvt->zchan != NULL);
|
||||
|
||||
zap_mutex_lock(tech_pvt->zchan->mutex);
|
||||
if (tech_pvt->zchan->state == ZAP_CHANNEL_STATE_TERMINATING) {
|
||||
zap_mutex_unlock(tech_pvt->zchan->mutex);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
} else {
|
||||
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
|
||||
} else {
|
||||
/* Don't skip messages in the ISDN call setup
|
||||
* TODO: make the isdn stack smart enough to handle that itself
|
||||
* until then, this is here for safety...
|
||||
*/
|
||||
if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS) {
|
||||
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
|
||||
} else {
|
||||
/* Don't skip messages in the ISDN call setup
|
||||
* TODO: make the isdn stack smart enough to handle that itself
|
||||
* until then, this is here for safety...
|
||||
*/
|
||||
if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS) {
|
||||
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS_MEDIA) {
|
||||
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP);
|
||||
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -868,6 +875,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
break;
|
||||
}
|
||||
|
||||
zap_mutex_unlock(tech_pvt->zchan->mutex);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -268,6 +268,26 @@
|
|||
/* The while(0) below throws a conditional expression is constant warning */
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
|
||||
#define zap_wait_for_flag_cleared(obj, flag, time) \
|
||||
do { \
|
||||
int __safety = time; \
|
||||
while(__safety-- && zap_test_flag(obj, flag)) { \
|
||||
zap_mutex_unlock(obj->mutex); \
|
||||
zap_sleep(10); \
|
||||
zap_mutex_lock(obj->mutex); \
|
||||
} \
|
||||
if(!__safety) { \
|
||||
zap_log(ZAP_LOG_CRIT, "flag %d was never cleared\n", flag); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
#define zap_set_state_wait(obj, s) \
|
||||
do { \
|
||||
zap_channel_set_state(obj, s, 0); \
|
||||
zap_wait_for_flag_cleared(obj, ZAP_CHANNEL_STATE_CHANGE, 100); \
|
||||
} while(0);
|
||||
|
||||
#define zap_set_state_locked_wait(obj, s) \
|
||||
do { \
|
||||
int __safety = 100; \
|
||||
|
@ -280,16 +300,6 @@
|
|||
} \
|
||||
} while(0);
|
||||
|
||||
#define zap_locked_wait_for_flag_cleared(obj, flag, time) \
|
||||
do { \
|
||||
int __safety = time; \
|
||||
while(__safety-- && zap_test_flag(obj, flag)) { \
|
||||
zap_sleep(10); \
|
||||
} \
|
||||
if(!__safety) { \
|
||||
zap_log(ZAP_LOG_CRIT, "flag %d was never cleared\n", flag); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -166,7 +166,7 @@ static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
|||
zap_mutex_lock(zchan->mutex);
|
||||
|
||||
/* the channel may be down but the thread not quite done */
|
||||
zap_locked_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200);
|
||||
zap_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200);
|
||||
|
||||
if (zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) {
|
||||
zap_log(ZAP_LOG_ERROR, "%d:%d Yay! R2 outgoing call in channel that is already in thread.\n",
|
||||
|
@ -217,7 +217,7 @@ static void zap_r2_on_call_init(openr2_chan_t *r2chan)
|
|||
}
|
||||
|
||||
/* the channel may be down but the thread not quite done */
|
||||
zap_locked_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200);
|
||||
zap_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200);
|
||||
|
||||
if (zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) {
|
||||
zap_log(ZAP_LOG_ERROR, "Cannot handle request to start call in channel %d, already in thread!\n",
|
||||
|
|
|
@ -372,9 +372,9 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||
while(zap_running() && OUTBOUND_REQUESTS[r].status == BST_ACK) {
|
||||
zap_sleep(1);
|
||||
if (--sanity <= 0) {
|
||||
status = ZAP_FAIL;
|
||||
*zchan = NULL;
|
||||
goto done;
|
||||
status = ZAP_FAIL;
|
||||
*zchan = NULL;
|
||||
goto done;
|
||||
}
|
||||
//printf("WTF %d\n", sanity);
|
||||
}
|
||||
|
@ -625,9 +625,11 @@ static void handle_call_start_nack(zap_span_t *span, sangomabc_connection_t *mco
|
|||
if ((zchan = find_zchan(span, event, 1))) {
|
||||
int r = 0;
|
||||
assert(!zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND));
|
||||
|
||||
zchan->call_data = (void*)event->event_id;
|
||||
|
||||
zap_mutex_lock(zchan->mutex);
|
||||
zap_set_state_r(zchan, ZAP_CHANNEL_STATE_CANCEL, 0, r);
|
||||
zap_set_state_r(zchan, ZAP_CHANNEL_STATE_TERMINATING, 0, r);
|
||||
if (r == ZAP_STATE_CHANGE_SUCCESS) {
|
||||
zchan->caller_data.hangup_cause = event->release_cause;
|
||||
}
|
||||
|
@ -898,9 +900,7 @@ static int parse_sangoma_event(zap_span_t *span, sangomabc_connection_t *mcon, s
|
|||
}
|
||||
|
||||
assert(event->call_setup_id <= MAX_REQ_ID);
|
||||
|
||||
switch(event->event_id) {
|
||||
|
||||
case SIGBOOST_EVENT_CALL_START:
|
||||
handle_call_start(span, mcon, (sangomabc_event_t*)event);
|
||||
break;
|
||||
|
@ -992,14 +992,25 @@ static __inline__ void state_advance(zap_channel_t *zchan)
|
|||
if (!zap_test_sflag(zchan, SFLAG_SENT_FINAL_MSG)) {
|
||||
zap_set_sflag_locked(zchan, SFLAG_SENT_FINAL_MSG);
|
||||
|
||||
sangomabc_exec_command(mcon,
|
||||
zchan->physical_span_id-1,
|
||||
zchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_STOPPED_ACK,
|
||||
0);
|
||||
if (zchan->call_data && ((uint32_t)zchan->call_data == SIGBOOST_EVENT_CALL_START_NACK)) {
|
||||
sangomabc_exec_command(mcon,
|
||||
zchan->physical_span_id-1,
|
||||
zchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
||||
0);
|
||||
|
||||
} else {
|
||||
sangomabc_exec_command(mcon,
|
||||
zchan->physical_span_id-1,
|
||||
zchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_STOPPED_ACK,
|
||||
0);
|
||||
}
|
||||
}
|
||||
zchan->sflags = 0;
|
||||
zchan->call_data = NULL;
|
||||
zap_channel_done(zchan);
|
||||
}
|
||||
break;
|
||||
|
@ -1103,20 +1114,6 @@ static __inline__ void state_advance(zap_channel_t *zchan)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case ZAP_CHANNEL_STATE_CANCEL:
|
||||
{
|
||||
sig.event_id = ZAP_SIGEVENT_STOP;
|
||||
status = sangoma_boost_data->signal_cb(&sig);
|
||||
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
|
||||
zap_set_sflag_locked(zchan, SFLAG_SENT_FINAL_MSG);
|
||||
sangomabc_exec_command(mcon,
|
||||
zchan->physical_span_id-1,
|
||||
zchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case ZAP_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
sig.event_id = ZAP_SIGEVENT_STOP;
|
||||
|
@ -1476,7 +1473,7 @@ static zap_state_map_t boost_state_map = {
|
|||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{ZAP_CHANNEL_STATE_RING, ZAP_END},
|
||||
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_CANCEL, ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END}
|
||||
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA,ZAP_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
|
@ -1487,14 +1484,14 @@ static zap_state_map_t boost_state_map = {
|
|||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{ZAP_CHANNEL_STATE_CANCEL, ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END},
|
||||
{ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END},
|
||||
{ZAP_CHANNEL_STATE_DOWN, ZAP_END},
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END},
|
||||
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_CANCEL, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_UP, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END},
|
||||
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_UP, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END},
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
|
|
Loading…
Reference in New Issue