From 5d47a9375197ab631e0585c0584d9822c323f132 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 20 Feb 2008 03:57:01 +0000 Subject: [PATCH] better handling of negotiation errs git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7707 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/endpoints/mod_sofia/mod_sofia.c | 10 ++++++---- src/switch_channel.c | 16 +++++++++------ src/switch_ivr_bridge.c | 26 ++++++++++++++++--------- src/switch_ivr_originate.c | 16 ++++++++++++--- 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index e96e41731f..f54891ca16 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -354,7 +354,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) sofia_glue_tech_prepare_codecs(tech_pvt); if (sofia_glue_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); - nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); + //nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); return SWITCH_STATUS_FALSE; } } @@ -967,7 +967,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } break; case SWITCH_MESSAGE_INDICATE_ANSWER: - sofia_answer_channel(session); + return sofia_answer_channel(session); break; case SWITCH_MESSAGE_INDICATE_PROGRESS: { @@ -975,7 +975,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Asked to send early media by %s\n", msg->from); - + /* Transmit 183 Progress with SDP */ if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) { const char *sdp = NULL; @@ -985,13 +985,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } else { if (switch_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)) { switch_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION); + if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) { const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); + tech_pvt->num_codecs = 0; sofia_glue_tech_prepare_codecs(tech_pvt); if (sofia_glue_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); - nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); + //nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); return SWITCH_STATUS_FALSE; } } diff --git a/src/switch_channel.c b/src/switch_channel.c index 33dc43286e..88e2c9a3dc 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1390,9 +1390,11 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS; msg.from = channel->name; status = switch_core_session_receive_message(channel->session, &msg); - + if (status == SWITCH_STATUS_SUCCESS) { - status = switch_channel_perform_mark_pre_answered(channel, file, func, line); + switch_channel_perform_mark_pre_answered(channel, file, func, line); + } else { + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); } return status; @@ -1423,6 +1425,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_ring_ready(switch_channel if (status == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_NOTICE, "Ring Ready %s!\n", channel->name); + } else { + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); } return status; @@ -1487,17 +1491,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t * return SWITCH_STATUS_SUCCESS; } - msg.message_id = SWITCH_MESSAGE_INDICATE_ANSWER; msg.from = channel->name; status = switch_core_session_receive_message(channel->session, &msg); if (status == SWITCH_STATUS_SUCCESS) { - return switch_channel_perform_mark_answered(channel, file, func, line); + switch_channel_perform_mark_answered(channel, file, func, line); + } else { + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); } - return SWITCH_STATUS_FALSE; - + return status; } #define resize(l) {\ diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 0daa4eaa8f..b0690cee79 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -209,10 +209,16 @@ static void *audio_bridge_thread(switch_thread_t * thread, void *obj) if (!ans_a && originator) { if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) { - switch_channel_answer(chan_a); + if (switch_channel_answer(chan_a) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a)); + break; + } ans_a++; } else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) { - switch_channel_pre_answer(chan_a); + if (switch_channel_pre_answer(chan_a) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a)); + break; + } pre_b++; } if (!pre_b) { @@ -605,6 +611,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses int stream_id = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_channel_state_t state; + switch_event_t *event; + int br = 0; switch_channel_set_flag(caller_channel, CF_ORIGINATOR); switch_channel_clear_flag(caller_channel, CF_TRANSFER); @@ -630,7 +638,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) || switch_channel_test_flag(peer_channel, CF_RING_READY)) { - switch_event_t *event; switch_core_session_message_t msg = { 0 }; const switch_application_interface_t *application_interface; const char *app, *data; @@ -640,8 +647,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); switch_event_fire(&event); + br = 1; } - + if (switch_core_session_read_lock(peer_session) == SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session)); switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(session)); @@ -713,11 +721,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_state(peer_channel, CS_LOOPBACK); audio_bridge_thread(NULL, (void *) a_leg); - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(caller_channel, event); - switch_event_fire(&event); - } - switch_channel_clear_flag(caller_channel, CF_ORIGINATOR); //make sure this doesnt break anything @@ -747,6 +750,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses done: + if (br && switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(caller_channel, event); + switch_event_fire(&event); + } + state = switch_channel_get_state(caller_channel); if (!switch_channel_test_flag(caller_channel, CF_TRANSFER)) { diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index fe266640c9..1375c74a15 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -908,7 +908,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (ringback_data && !switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) { - switch_channel_pre_answer(caller_channel); + if ((status = switch_channel_pre_answer(caller_channel)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(caller_channel)); + goto done; + } } if (session && (read_codec = switch_core_session_get_read_codec(session)) && @@ -1132,9 +1135,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (caller_channel) { if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) { - switch_channel_answer(caller_channel); + status = switch_channel_answer(caller_channel); } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { - switch_channel_pre_answer(caller_channel); + status = switch_channel_pre_answer(caller_channel); + } else { + status = SWITCH_STATUS_SUCCESS; + } + + if (status != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(caller_channel)); + switch_channel_hangup(peer_channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); } }