diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c index 8890d235b5689416eb405b1301071e03ffce8c52..ee3abfb7f7337f89b6f0ac9df3438703b8c2198a 100644 --- a/res/res_pjsip_refer.c +++ b/res/res_pjsip_refer.c @@ -805,82 +805,41 @@ static int refer_incoming_attended_request(struct ast_sip_session *session, pjsi return 400; } - /* See if the dialog is local, or remote */ - if ((dlg = pjsip_ua_find_dialog(&replaces->call_id, &replaces->to_tag, &replaces->from_tag, PJ_TRUE))) { - RAII_VAR(struct ast_sip_session *, other_session, ast_sip_dialog_get_session(dlg), ao2_cleanup); - struct refer_attended *attended; - - pjsip_dlg_dec_lock(dlg); - - if (!other_session) { - ast_debug(3, "Received REFER request on channel '%s' from endpoint '%s' for local dialog but no session exists on it\n", - ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint)); - return 603; - } - - /* We defer actually doing the attended transfer to the other session so no deadlock can occur */ - if (!(attended = refer_attended_alloc(session, other_session, progress))) { - ast_log(LOG_ERROR, "Received REFER request on channel '%s' from endpoint '%s' for local dialog but could not allocate structure to complete, rejecting\n", - ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint)); - return 500; - } - - if (ast_sip_session_defer_termination(session)) { - ast_log(LOG_ERROR, "Received REFER request on channel '%s' from endpoint '%s' for local dialog but could not defer termination, rejecting\n", - ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint)); - ao2_cleanup(attended); - return 500; - } - - /* Push it to the other session, which will have both channels with minimal locking */ - if (ast_sip_push_task(other_session->serializer, refer_attended_task, attended)) { - ast_sip_session_end_if_deferred(session); - ast_sip_session_defer_termination_cancel(session); - ao2_cleanup(attended); - return 500; - } - - ast_debug(3, "Attended transfer from '%s' pushed to second channel serializer\n", - ast_channel_name(session->channel)); - - return 200; - } else { - const char *context; - struct refer_blind refer = { 0, }; - int response; - - DETERMINE_TRANSFER_CONTEXT(context, session); + const char *context; + struct refer_blind refer = { 0, }; + int response; - if (!ast_exists_extension(NULL, context, "external_replaces", 1, NULL)) { - ast_log(LOG_ERROR, "Received REFER for remote session on channel '%s' from endpoint '%s' but 'external_replaces' extension not found in context %s\n", - ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint), context); - return 404; - } + DETERMINE_TRANSFER_CONTEXT(context, session); - refer.context = context; - refer.progress = progress; - refer.rdata = rdata; - refer.replaces = replaces; - refer.refer_to = target_uri; - refer.attended = 1; + if (!ast_exists_extension(NULL, context, "external_replaces", 1, NULL)) { + ast_log(LOG_ERROR, "Received REFER for remote session on channel '%s' from endpoint '%s' but 'external_replaces' extension not found in context %s\n", + ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint), context); + return 404; + } - if (ast_sip_session_defer_termination(session)) { - ast_log(LOG_ERROR, "Received REFER for remote session on channel '%s' from endpoint '%s' but could not defer termination, rejecting\n", - ast_channel_name(session->channel), - ast_sorcery_object_get_id(session->endpoint)); - return 500; - } + refer.context = context; + refer.progress = progress; + refer.rdata = rdata; + refer.replaces = replaces; + refer.refer_to = target_uri; + refer.attended = 1; - response = xfer_response_code2sip(ast_bridge_transfer_blind(1, session->channel, - "external_replaces", context, refer_blind_callback, &refer)); + if (ast_sip_session_defer_termination(session)) { + ast_log(LOG_ERROR, "Received REFER for remote session on channel '%s' from endpoint '%s' but could not defer termination, rejecting\n", + ast_channel_name(session->channel), + ast_sorcery_object_get_id(session->endpoint)); + return 500; + } - ast_sip_session_end_if_deferred(session); - if (response != 200) { - ast_sip_session_defer_termination_cancel(session); - } + response = xfer_response_code2sip(ast_bridge_transfer_blind(1, session->channel, + "external_replaces", context, refer_blind_callback, &refer)); - return response; + ast_sip_session_end_if_deferred(session); + if (response != 200) { + ast_sip_session_defer_termination_cancel(session); } + + return response; } static int refer_incoming_blind_request(struct ast_sip_session *session, pjsip_rx_data *rdata, pjsip_sip_uri *target,