diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 79cf1fadc45d4591ccb331195df2f9a4fb2b6022..a35eb19dbcaf9e7667a94aa963915055b47ab2ba 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -4328,6 +4328,8 @@ unsigned int ast_channel_sipResponseCode(const struct ast_channel *chan); void ast_channel_sipResponseCode_set(struct ast_channel *chan, unsigned int value); int ast_channel_narrow_band_only(const struct ast_channel *chan); void ast_channel_narrow_band_only_set(struct ast_channel *chan, int value); +struct ast_channel *ast_channel_bridged_chan(const struct ast_channel *chan); +void ast_channel_bridged_chan_set(struct ast_channel *chan, struct ast_channel *value); const char *ast_channel_codec_get(const struct ast_channel *chan); void ast_channel_codec_set(struct ast_channel *chan, const char *value); struct ast_channel_snapshot *ast_channel_snapshot(const struct ast_channel *chan); diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index 5029b20b6e4c036f0b5c47fe80e41c10e793000b..91b1d0bde8d4bade9866adc9e2b35b4ba4963f4b 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -235,6 +235,7 @@ struct ast_channel { int ptime; /*!< Negotiated ptime */ enum early_media_direction early_media_dir; /*!< The direction of the early media*/ int narrow_band_only; /*!< Whether the channel supports narrow band only */ + struct ast_channel *bridged_chan; /*!< Channel that will be bridged with */ }; /*! \brief The monotonically increasing integer counter for channel uniqueids */ @@ -879,6 +880,16 @@ void ast_channel_narrow_band_only_set(struct ast_channel *chan, int value) chan->narrow_band_only = value; } +struct ast_channel *ast_channel_bridged_chan(const struct ast_channel *chan) +{ + return chan->bridged_chan; +} + +void ast_channel_bridged_chan_set(struct ast_channel *chan, struct ast_channel *value) +{ + chan->bridged_chan = value; +} + const char *ast_channel_codec_get(const struct ast_channel *chan) { return chan->codec; diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index a6615c4c4dd421aea39bdc2eb35e13848f18ee76..9e742e42c32a15527a3502b7686c0510235f9e4c 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -2131,12 +2131,14 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, char host[NI_MAXHOST]; int res; struct ast_sip_session_media *session_media_transport; + struct ast_channel *bridged_chan; SCOPE_ENTER(1, "%s Stream: %s\n", ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(asterisk_stream, &STR_TMP))); if (!session->channel) { SCOPE_EXIT_RTN_VALUE(1, "No channel\n"); } + bridged_chan = ast_channel_bridged_chan(session->channel); /* Ensure incoming transport is compatible with the endpoint's configuration */ if (!session->endpoint->media.rtp.use_received_transport && @@ -2213,12 +2215,16 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, if (caps) { ast_format_cap_append(caps, ast_format_cap_get_format(ast_stream_get_formats(asterisk_stream), 0), ast_channel_ptime_get(session->channel)); ast_channel_nativeformats_set(session->channel, caps); + if (bridged_chan) { + ast_channel_nativeformats_set(bridged_chan, caps); + } ao2_ref(caps, -1); } else { ao2_cleanup(caps); ast_log(LOG_WARNING, "Unable to allocate caps\n"); } } + /* Get and set the ptime, get from remote_stream if it has, otherwise get from local_stream */ pjmedia_sdp_attr *attr; unsigned long framing; @@ -2231,9 +2237,13 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, framing = pj_strtoul(pj_strltrim(&attr->value)); ast_channel_ptime_set(session->channel, framing); } - ast_channel_codec_set(session->channel, ast_format_get_name(ast_format_cap_get_format(ast_stream_get_formats(asterisk_stream), 0))); - ast_log(LOG_NOTICE, "channel %s, codec: %s, ptime: %d \n", ast_channel_name(session->channel), ast_channel_codec_get(session->channel), ast_channel_ptime_get(session->channel)); + ast_log(LOG_NOTICE, "channel %s, codec: %s, ptime: %d \n", ast_channel_name(session->channel), + ast_channel_codec_get(session->channel), ast_channel_ptime_get(session->channel)); + if (bridged_chan) { + ast_channel_codec_set(bridged_chan, ast_channel_codec_get(session->channel)); + ast_channel_ptime_set(bridged_chan, ast_channel_ptime_get(session->channel)); + } /* Set the channel uniqueid on the RTP instance now that it is becoming active */ ast_rtp_instance_set_channel_id(session_media->rtp, ast_channel_uniqueid(session->channel)); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index d692ce5a6906d64772f17ad82dc2839d5815f3f8..915b2c046a8c9d88dcff83e206e64dc679dcde2b 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -6112,28 +6112,31 @@ static pjsip_inv_callback inv_callback = { int ast_sip_session_sdp_answer(struct ast_sip_session *session) { const pjmedia_sdp_session *offer = NULL, *answer; + struct ast_channel *chan; SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session)); - if (!session || !session->inv_session || !session->inv_session->neg) { + if (!session || !session->inv_session || !session->inv_session->neg || !(chan = session->channel)) { SCOPE_EXIT_RTN_VALUE(-1, "%s: invalid parameter(s)\n", ast_sip_session_get_name(session)); } - if (pjmedia_sdp_neg_get_neg_remote(session->inv_session->neg, &offer) != PJ_SUCCESS) { - SCOPE_EXIT_RTN_VALUE(-1, "%s: pjmedia_sdp_neg_get_neg_remote() failed\n", ast_sip_session_get_name(session)); - } + if (ast_channel_narrow_band_only(chan)) { + if (pjmedia_sdp_neg_get_neg_remote(session->inv_session->neg, &offer) != PJ_SUCCESS) { + SCOPE_EXIT_RTN_VALUE(-1, "%s: pjmedia_sdp_neg_get_neg_remote() failed\n", ast_sip_session_get_name(session)); + } - if (handle_incoming_sdp(session, offer)) { - ast_sip_session_media_state_reset(session->pending_media_state); - SCOPE_EXIT_RTN_VALUE(-1, "%s: handle_incoming_sdp() failed and media state is reset\n", ast_sip_session_get_name(session)); - } + if (handle_incoming_sdp(session, offer)) { + ast_sip_session_media_state_reset(session->pending_media_state); + SCOPE_EXIT_RTN_VALUE(-1, "%s: handle_incoming_sdp() failed and media state is reset\n", ast_sip_session_get_name(session)); + } - answer = create_local_sdp(session->inv_session, session, offer, 0); - if (!answer) { - SCOPE_EXIT_RTN_VALUE(-1, "%s: create_local_sdp() failed\n", ast_sip_session_get_name(session)); - } + answer = create_local_sdp(session->inv_session, session, offer, 0); + if (!answer) { + SCOPE_EXIT_RTN_VALUE(-1, "%s: create_local_sdp() failed\n", ast_sip_session_get_name(session)); + } - if (pjsip_inv_set_sdp_answer(session->inv_session, answer) != PJ_SUCCESS) { - SCOPE_EXIT_RTN_VALUE(-1, "%s: pjsip_inv_set_sdp_answer() failed\n", ast_sip_session_get_name(session)); + if (pjsip_inv_set_sdp_answer(session->inv_session, answer) != PJ_SUCCESS) { + SCOPE_EXIT_RTN_VALUE(-1, "%s: pjsip_inv_set_sdp_answer() failed\n", ast_sip_session_get_name(session)); + } } SCOPE_EXIT_RTN_VALUE(0, "%s\n", ast_sip_session_get_name(session));