fix races in bypass media regarding channel signalling that may cause answer to be skipped
This commit is contained in:
parent
5dd9b7218a
commit
d43af04e93
|
@ -687,7 +687,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(_In_ switch_co
|
||||||
/*!
|
/*!
|
||||||
\brief Signal a session's state machine thread that a state change has occured
|
\brief Signal a session's state machine thread that a state change has occured
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(void) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session);
|
SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session);
|
||||||
SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_session_t *session);
|
SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_session_t *session);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -111,6 +111,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_events(switch_core_session_
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_event(switch_core_session_t *session);
|
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_event(switch_core_session_t *session);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session);
|
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_session_t *session);
|
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_session_t *session);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Wait for time to pass for a specified number of milliseconds
|
\brief Wait for time to pass for a specified number of milliseconds
|
||||||
\param session the session to wait for.
|
\param session the session to wait for.
|
||||||
|
|
|
@ -1257,9 +1257,7 @@ void sofia_event_callback(nua_event_t event,
|
||||||
|
|
||||||
if (!zstr(sofia_private->uuid)) {
|
if (!zstr(sofia_private->uuid)) {
|
||||||
if ((session = switch_core_session_locate(sofia_private->uuid))) {
|
if ((session = switch_core_session_locate(sofia_private->uuid))) {
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
if (switch_core_session_running(session)) {
|
||||||
|
|
||||||
if (switch_core_session_running(session) && !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
|
|
||||||
switch_core_session_queue_signal_data(session, de);
|
switch_core_session_queue_signal_data(session, de);
|
||||||
} else {
|
} else {
|
||||||
switch_core_session_message_t msg = { 0 };
|
switch_core_session_message_t msg = { 0 };
|
||||||
|
|
|
@ -2885,6 +2885,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_
|
||||||
switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH);
|
switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send
|
/* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send
|
||||||
a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
|
a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -832,9 +832,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_flush_message(switch_core_se
|
||||||
|
|
||||||
switch_assert(session != NULL);
|
switch_assert(session != NULL);
|
||||||
|
|
||||||
|
|
||||||
if (session->message_queue) {
|
if (session->message_queue) {
|
||||||
while ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
|
while ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
|
||||||
message = (switch_core_session_message_t *) pop;
|
message = (switch_core_session_message_t *) pop;
|
||||||
|
switch_ivr_process_indications(session, message);
|
||||||
switch_core_session_free_message(&message);
|
switch_core_session_free_message(&message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1124,14 +1126,20 @@ SWITCH_DECLARE(switch_channel_t *) switch_core_session_get_channel(switch_core_s
|
||||||
return session->channel;
|
return session->channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_core_session_wake_session_thread(switch_core_session_t *session)
|
SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
|
switch_status_t status;
|
||||||
|
|
||||||
/* If trylock fails the signal is already awake so we needn't bother */
|
/* If trylock fails the signal is already awake so we needn't bother */
|
||||||
|
|
||||||
if (switch_mutex_trylock(session->mutex) == SWITCH_STATUS_SUCCESS) {
|
status = switch_mutex_trylock(session->mutex);
|
||||||
|
|
||||||
|
if (status == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_thread_cond_signal(session->cond);
|
switch_thread_cond_signal(session->cond);
|
||||||
switch_mutex_unlock(session->mutex);
|
switch_mutex_unlock(session->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session_t *session)
|
SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session_t *session)
|
||||||
|
|
|
@ -422,13 +422,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
|
||||||
switch_channel_hangup(session->channel, SWITCH_CAUSE_INVALID_CALL_REFERENCE);
|
switch_channel_hangup(session->channel, SWITCH_CAUSE_INVALID_CALL_REFERENCE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch_core_session_message_t *message;
|
switch_ivr_parse_all_events(session);
|
||||||
|
|
||||||
while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
|
|
||||||
switch_core_session_receive_message(session, message);
|
|
||||||
message = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_ivr_parse_all_events(session);
|
switch_ivr_parse_all_events(session);
|
||||||
|
|
||||||
if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
|
if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
|
||||||
|
@ -440,11 +434,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_ivr_parse_all_events(session);
|
switch_ivr_parse_all_events(session);
|
||||||
|
switch_ivr_parse_all_events(session);
|
||||||
while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
|
|
||||||
switch_core_session_receive_message(session, message);
|
|
||||||
message = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -668,43 +668,51 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_event(switch_core_session_
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session)
|
SWITCH_DECLARE(switch_status_t) switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message)
|
||||||
{
|
{
|
||||||
switch_core_session_message_t *message;
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
switch_ivr_parse_all_signal_data(session);
|
|
||||||
|
|
||||||
while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
|
|
||||||
i++;
|
|
||||||
|
|
||||||
switch(message->message_id) {
|
switch(message->message_id) {
|
||||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||||
if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
|
if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
}
|
}
|
||||||
switch_core_session_free_message(&message);
|
|
||||||
break;
|
break;
|
||||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||||
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
|
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
}
|
}
|
||||||
switch_core_session_free_message(&message);
|
|
||||||
break;
|
break;
|
||||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||||
if (switch_channel_ring_ready(channel) != SWITCH_STATUS_SUCCESS) {
|
if (switch_channel_ring_ready(channel) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
}
|
}
|
||||||
switch_core_session_free_message(&message);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch_core_session_receive_message(session, message);
|
status = SWITCH_STATUS_FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
message = NULL;
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session)
|
||||||
|
{
|
||||||
|
switch_core_session_message_t *message;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
switch_ivr_parse_all_signal_data(session);
|
||||||
|
|
||||||
|
while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (switch_ivr_process_indications(session, message) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_core_session_free_message(&message);
|
||||||
|
} else {
|
||||||
|
switch_core_session_receive_message(session, message);
|
||||||
|
message = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
|
return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
|
||||||
|
|
|
@ -1030,6 +1030,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t
|
||||||
switch_buffer_destroy(&ringback.audio_buffer);
|
switch_buffer_destroy(&ringback.audio_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch_ivr_parse_all_events(session);
|
||||||
|
|
||||||
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
|
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
|
||||||
|
|
||||||
if (switch_core_codec_ready(&write_codec)) {
|
if (switch_core_codec_ready(&write_codec)) {
|
||||||
|
@ -3162,9 +3165,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||||
if (caller_channel) {
|
if (caller_channel) {
|
||||||
if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
|
if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
|
||||||
switch_channel_pass_callee_id(peer_channel, caller_channel);
|
switch_channel_pass_callee_id(peer_channel, caller_channel);
|
||||||
|
if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
status = switch_channel_answer(caller_channel);
|
status = switch_channel_answer(caller_channel);
|
||||||
|
}
|
||||||
} else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
|
} else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
|
||||||
|
if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
status = switch_channel_pre_answer(caller_channel);
|
status = switch_channel_pre_answer(caller_channel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
status = SWITCH_STATUS_SUCCESS;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -3462,6 +3473,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||||
switch_ivr_sleep(*bleg, 0, SWITCH_TRUE, NULL);
|
switch_ivr_sleep(*bleg, 0, SWITCH_TRUE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oglobals.session) {
|
||||||
|
switch_ivr_parse_all_events(oglobals.session);
|
||||||
|
}
|
||||||
|
|
||||||
if (oglobals.session && status == SWITCH_STATUS_SUCCESS) {
|
if (oglobals.session && status == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_ivr_sleep(oglobals.session, 0, SWITCH_TRUE, NULL);
|
switch_ivr_sleep(oglobals.session, 0, SWITCH_TRUE, NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue