From 48a8b26a8d96563a67428669f3f842047d6f543e Mon Sep 17 00:00:00 2001 From: George Yang <g.yang@genexis.eu> Date: Thu, 19 Dec 2024 14:07:49 +0100 Subject: [PATCH] No transport fallback happens when Status 500 received for SIP Invite, REF #15941 - Not trigger re-registration when Status 500 received for outgoing Invite - The emergency call flow is kept, which may trigger re-registration to recover from faulty status. --- res/res_pjsip_session.c | 95 +++++++++++++---------------------------- 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 0b9c22435f..c2c86b2752 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -3540,9 +3540,6 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint if (transport_state && transport_state->type == AST_TRANSPORT_TLS && !ast_sip_is_X_RDK_NTP_Synchronized()) transport_state = NULL; - - if (!transport_state && !ast_strlen_zero(endpoint->transport2)) - transport_state = ast_sip_get_transport_state(endpoint->transport2); } if (!transport_state) { ast_log(LOG_NOTICE,"===== No Transport! =====\n"); @@ -5054,72 +5051,42 @@ static struct ast_sip_transport_state* get_udp_transport_state() return state; } -static int sip_inv_transport2(pjsip_inv_session *inv, pjsip_event *e) +static void sip_inv_transport_emergency(pjsip_inv_session *inv) { struct ast_sip_session *session = inv->mod_data[session_module.id]; - struct ast_sip_endpoint *endpoint = session->endpoint; - struct ast_sip_transport_state *transport2; - pjsip_transaction *tsx = e->body.tsx_state.tsx; - struct pjsip_msg *msg = tsx->last_tx->msg; + struct ast_sip_transport_state *transport_udp; pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, }; - pjsip_sip_uri *target_uri; - pjsip_tx_data *tdata; - - if (msg->type != PJSIP_REQUEST_MSG || - msg->line.req.method.id != PJSIP_INVITE_METHOD) - return 0; - - if (endpoint && endpoint->transport2) { - transport2 = ast_sip_get_transport_state(endpoint->transport2); - } - if (!transport2) { - // for emergency ongoing call, try UDP further, if transport2 is not available - if (session->channel && ast_channel_emergency_ongoing_get(session->channel)) { - ast_log(LOG_NOTICE, "Try UDP transport for emergency ongoing call\n"); + ast_log(LOG_NOTICE, "Try UDP transport for emergency ongoing call\n"); - transport2 = get_udp_transport_state(); + transport_udp = get_udp_transport_state(); - if (!transport2) { - ast_log(LOG_NOTICE, "No UDP transport available\n"); - return 0; - } - } else { - if (endpoint->transport2) { - ast_log(LOG_ERROR, "transport2 %s is not available\n", endpoint->transport2); - } else { - ast_debug(3, "no transport2 available\n"); - } + if (transport_udp && transport_udp != session->transport_state && + !ast_sip_set_tpselector_from_transport_name(transport_udp->id, &selector)) { + pjsip_sip_uri *target_uri; + pjsip_tx_data *tdata; - return 0; - } - } + ast_log(LOG_NOTICE, "Sending SIP INVITE with transport (%s)\n", transport_udp->id); - if (transport2 == session->transport_state) { - ast_debug(3, "Tried transport2 '%s'. No help!\n", transport2->id); - return 0; - } + session->transport_state = transport_udp; + pjsip_dlg_set_transport(inv->dlg, &selector); - if (ast_sip_set_tpselector_from_transport_name(endpoint->transport2, &selector)) - return 0; + pjsip_inv_uac_restart(inv, PJ_FALSE); + pjmedia_sdp_neg_cancel_offer(inv->neg); - pjsip_dlg_set_transport(inv->dlg, &selector); - session->transport_state = transport2; + target_uri = pjsip_uri_get_uri(inv->dlg->target); + if (target_uri) + target_uri->port = pj_sockaddr_get_port(&transport_udp->host); - ast_log(LOG_NOTICE, "Sending SIP INVITE with transport (%s)\n", transport2->id); + ast_sip_session_create_invite(session, &tdata); + ast_sip_session_send_request(session, tdata); - pjsip_inv_uac_restart(inv, PJ_FALSE); - pjmedia_sdp_neg_cancel_offer(inv->neg); + } else if (session->endpoint) { + ast_log(LOG_NOTICE, "%s: Failed to INVITE, schedule re-registration\n", ast_sorcery_object_get_id(session->endpoint)); - target_uri = pjsip_uri_get_uri(inv->dlg->target); - if (target_uri) { - target_uri->port = pj_sockaddr_get_port(&transport2->host); + session->endpoint->failover_reg_addr = 1; + queue_registration_recovery_flow(ast_sorcery_object_get_id(session->endpoint)); } - - ast_sip_session_create_invite(session, &tdata); - ast_sip_session_send_request(session, tdata); - - return 1; } static int check_request_status(pjsip_inv_session *inv, pjsip_event *e) @@ -5136,18 +5103,16 @@ static int check_request_status(pjsip_inv_session *inv, pjsip_event *e) } ast_log(LOG_NOTICE, "Failed to send SIP INVITE with transport '%s'\n", session->transport_state->id); - // Try if the endpoint has transport2 - if (!sip_inv_transport2(inv, e)) { - // no transport2 - if (session->endpoint) { - ast_log(LOG_NOTICE, "INVITE sent to '%s' failed, schedule re-registrations\n", ast_sorcery_object_get_id(session->endpoint)); - session->endpoint->failover_reg_addr = 1; - queue_registration_recovery_flow(ast_sorcery_object_get_id(session->endpoint)); - } - return 0; + + // Try more for emergency ongoing INVITE + if (session->channel && ast_channel_emergency_ongoing_get(session->channel)) { + struct pjsip_msg *msg = tsx->last_tx->msg; + + if (msg && msg->type == PJSIP_REQUEST_MSG && msg->line.req.method.id == PJSIP_INVITE_METHOD) + sip_inv_transport_emergency(inv); } - return 1; // transport2 ongoing + return 1; } static void handle_incoming_before_media(pjsip_inv_session *inv, -- GitLab