summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorlvl <digium@lvlconsultancy.nl>2018-02-20 18:48:50 +0100
committerRichard Mudgett <rmudgett@digium.com>2018-03-06 13:35:22 -0600
commit3fb26df4acd712fbbac78dd9e88235d37024b2fa (patch)
tree9ae033905cf1a01be4d527900ae0f739a4f8f012 /res
parent91a8c7a28114dd4d64dd5216a7cffd0f36d35bab (diff)
res_pjsip_session: properly handle SDP from a forked call with early media
In handle_negotiated_sdp(), use session->active_media_state when session->pending_media_state is empty. The 200's SDP should be fed into handle_negotiated_sdp_session_media() together with the already negotiated state, which is now in session->active_media_state instead. Only if both the session's pending and active media are empty should handle_negotiated_sdp() abort. ASTERISK-27441 Change-Id: If0d5150ffe6f38d8a854831fef37942258d4629c
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip_session.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index fcd190bcb..f25201731 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -876,15 +876,30 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
struct ast_stream_topology *topology;
unsigned int changed = 0;
- /* This situation can legitimately happen when an SDP is received in a
- * 183 Session Progress message. In that case, everything's been done
- * by the time this function is called and there are no more pending
- * streams.
- */
if (!session->pending_media_state->topology) {
- ast_debug(1, "Pending topology was NULL for channel '%s'\n",
- session->channel ? ast_channel_name(session->channel) : "unknown");
- return 0;
+ if (session->active_media_state->topology) {
+ /*
+ * This happens when we have negotiated media after receiving a 183,
+ * and we're now receiving a 200 with a new SDP. In this case, there
+ * is active_media_state, but the pending_media_state has been reset.
+ */
+ struct ast_sip_session_media_state *active_media_state_clone;
+
+ active_media_state_clone =
+ ast_sip_session_media_state_clone(session->active_media_state);
+ if (!active_media_state_clone) {
+ ast_log(LOG_WARNING, "Unable to clone active media state for channel '%s'\n",
+ session->channel ? ast_channel_name(session->channel) : "unknown");
+ return -1;
+ }
+
+ ast_sip_session_media_state_free(session->pending_media_state);
+ session->pending_media_state = active_media_state_clone;
+ } else {
+ ast_log(LOG_WARNING, "No pending or active media state for channel '%s'\n",
+ session->channel ? ast_channel_name(session->channel) : "unknown");
+ return -1;
+ }
}
/* If we're handling negotiated streams, then we should already have set