diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index a2a3e930b6..60e596e439 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -786,16 +786,29 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
 {
 	int i;
 	struct ast_stream_topology *topology;
+	struct ast_sip_session_media_state* media_state;
 	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) {
+	if (session->pending_media_state->topology) {
+		/* Normal case: use pending media state to negotiate;
+		 * the pending state becomes the active state after negotiation
+		 */
+		media_state = session->pending_media_state;
+
+	} else if (session->active_media_state) {
+		/* This happens when we're negotiated media after receiving a 183,
+		 * and we're now receiving a 200 with new SDP.
+		 * In this case, there is active_media_state, but the pending_media_state
+		 * has been reset.
+		 */
 		ast_debug(1, "Pending topology was NULL for channel '%s'\n",
-			session->channel ? ast_channel_name(session->channel) : "unknown");
+				  session->channel ? ast_channel_name(session->channel) : "unknown");
+		// Use active_media_state to negotiate
+		media_state = session->active_media_state;
+
+	} else {
+		ast_log(LOG_WARNING, "No pending or active media state for channel '%s'\n",
+				  session->channel ? ast_channel_name(session->channel) : "unknown");
 		return 0;
 	}
 
@@ -804,11 +817,11 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
 	 * the local SDP, and there should be the same number of session medias
 	 * and streams as there are local SDP streams
 	 */
-	if (ast_stream_topology_get_count(session->pending_media_state->topology) != local->media_count
-		|| AST_VECTOR_SIZE(&session->pending_media_state->sessions) != local->media_count) {
+	if (ast_stream_topology_get_count(media_state->topology) != local->media_count
+		|| AST_VECTOR_SIZE(&media_state->sessions) != local->media_count) {
 		ast_log(LOG_WARNING, "Local SDP for channel '%s' contains %d media streams while we expected it to contain %u\n",
 			session->channel ? ast_channel_name(session->channel) : "unknown",
-			ast_stream_topology_get_count(session->pending_media_state->topology), local->media_count);
+			ast_stream_topology_get_count(media_state->topology), local->media_count);
 		return -1;
 	}
 
@@ -820,8 +833,8 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
 			continue;
 		}
 
-		session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, i);
-		stream = ast_stream_topology_get_stream(session->pending_media_state->topology, i);
+		session_media = AST_VECTOR_GET(&media_state->sessions, i);
+		stream = ast_stream_topology_get_stream(media_state->topology, i);
 
 		/* The stream state will have already been set to removed when either we
 		 * negotiate the incoming SDP stream or when we produce our own local SDP.
@@ -857,8 +870,8 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
 			continue;
 		}
 
-		session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, i);
-		stream = ast_stream_topology_get_stream(session->pending_media_state->topology, i);
+		session_media = AST_VECTOR_GET(&media_state->sessions, i);
+		stream = ast_stream_topology_get_stream(media_state->topology, i);
 
 		if (ast_stream_get_state(stream) == AST_STREAM_STATE_REMOVED
 			&& session_media->handler) {
@@ -872,7 +885,7 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
 	}
 
 	/* Update the topology on the channel to match the accepted one */
-	topology = ast_stream_topology_clone(session->pending_media_state->topology);
+	topology = ast_stream_topology_clone(media_state->topology);
 	if (topology) {
 		ast_channel_set_stream_topology(session->channel, topology);
 	}
@@ -883,16 +896,18 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_
 	}
 
 	/* Add all the file descriptors from the pending media state */
-	for (i = 0; i < AST_VECTOR_SIZE(&session->pending_media_state->read_callbacks); ++i) {
+	for (i = 0; i < AST_VECTOR_SIZE(&media_state->read_callbacks); ++i) {
 		struct ast_sip_session_media_read_callback_state *callback_state;
 
-		callback_state = AST_VECTOR_GET_ADDR(&session->pending_media_state->read_callbacks, i);
+		callback_state = AST_VECTOR_GET_ADDR(&media_state->read_callbacks, i);
 		ast_channel_internal_fd_set(session->channel, i + AST_EXTENDED_FDS, callback_state->fd);
 	}
 
 	/* Active and pending flip flop as needed */
-	SWAP(session->active_media_state, session->pending_media_state);
-	ast_sip_session_media_state_reset(session->pending_media_state);
+	if (media_state == session->pending_media_state) {
+		SWAP(session->active_media_state, session->pending_media_state);
+		ast_sip_session_media_state_reset(session->pending_media_state);
+	}
 
 	ast_channel_unlock(session->channel);
 
