diff -Naur asterisk-certified-13.21-cert3/res/res_pjsip_t38.c asterisk-certified-13.21-cert3-patched/res/res_pjsip_t38.c --- asterisk-certified-13.21-cert3/res/res_pjsip_t38.c 2018-09-20 21:04:02.000000000 +0200 +++ asterisk-certified-13.21-cert3-patched/res/res_pjsip_t38.c 2019-07-16 11:54:00.694532261 +0200 @@ -289,6 +289,35 @@ return 0; } +/*! \brief Callback for when a response is received for a T.38 fallback re-invite */ +static int t38_fallback_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata) +{ + struct pjsip_status_line status = rdata->msg_info.msg->line.status; + struct ast_format *fmt; + + if (status.code / 100 == 2) { + ast_debug(2, "channel %s accepted t38 audio fallback, setting native formats...\n", + ast_channel_name(session->channel)); + fmt = ast_format_cap_get_best_by_type(ast_channel_nativeformats(session->channel), AST_MEDIA_TYPE_AUDIO); + if (!fmt) { + /* No format? That's weird. */ + ast_log(LOG_WARNING, "Received response to T.38 fallback re-invite on '%s' but format is not available!!!\n", + session->channel ? ast_channel_name(session->channel) : "unknown channel"); + return 0; + } + ast_channel_set_writeformat(session->channel, fmt); + ast_channel_set_rawwriteformat(session->channel, fmt); + ast_channel_set_readformat(session->channel, fmt); + ast_channel_set_rawreadformat(session->channel, fmt); + ao2_ref(fmt, -1); + } else { + ast_debug(2, "channel %s refused audio fallback... don't know what to do...", + ast_channel_name(session->channel)); + } + return 0; + +} + /*! \brief Callback for when a response is received for a T.38 re-invite */ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata) { @@ -307,6 +336,16 @@ return 0; } + if (status.code / 100 != 2) { + ast_debug(2, "t38 refused on channel %s, falling back to G711", + ast_channel_name(session->channel)); + ast_format_cap_remove_by_type(session->req_caps, AST_MEDIA_TYPE_AUDIO); + ast_format_cap_update_by_allow_disallow(session->req_caps, "!all,alaw,ulaw", 1); + ast_sip_session_refresh(session, NULL, NULL, t38_fallback_response_cb, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1); + ast_debug(2, "t38 fallback invite sent on channel %s, falling back to G711, waiting for response...\n", + ast_channel_name(session->channel)); + } + t38_change_state(session, session_media, state, (status.code == 200) ? T38_ENABLED : T38_REJECTED); ao2_cleanup(session_media);