/*!
\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(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_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
\param session the session to wait for.
if (!zstr(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) && !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
+ if (switch_core_session_running(session)) {
switch_core_session_queue_signal_data(session, de);
} else {
switch_core_session_message_t msg = { 0 };
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
a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
*/
switch_assert(session != NULL);
+
if (session->message_queue) {
while ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
message = (switch_core_session_message_t *) pop;
+ switch_ivr_process_indications(session, message);
switch_core_session_free_message(&message);
}
}
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 (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_mutex_unlock(session->mutex);
}
+
+ return status;
}
SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session_t *session)
switch_channel_hangup(session->channel, SWITCH_CAUSE_INVALID_CALL_REFERENCE);
}
} else {
- switch_core_session_message_t *message;
-
- 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)) {
}
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_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);
- 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) {
case SWITCH_MESSAGE_INDICATE_ANSWER:
if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
- switch_core_session_free_message(&message);
break;
case SWITCH_MESSAGE_INDICATE_PROGRESS:
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
- switch_core_session_free_message(&message);
break;
case SWITCH_MESSAGE_INDICATE_RINGING:
if (switch_channel_ring_ready(channel) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
- switch_core_session_free_message(&message);
break;
default:
- switch_core_session_receive_message(session, message);
+ status = SWITCH_STATUS_FALSE;
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;
switch_buffer_destroy(&ringback.audio_buffer);
}
+
+ switch_ivr_parse_all_events(session);
+
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
if (switch_core_codec_ready(&write_codec)) {
if (caller_channel) {
if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
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);
+ }
} 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);
+ }
} else {
status = SWITCH_STATUS_SUCCESS;
}
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) {
switch_ivr_sleep(oglobals.session, 0, SWITCH_TRUE, NULL);
}