summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pjsip/include/pjsip/sip_config.h24
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c16
-rw-r--r--pjsip/src/pjsip/sip_config.c3
3 files changed, 36 insertions, 7 deletions
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index 5d0464f9..b72c6d02 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -111,6 +111,15 @@ typedef struct pjsip_cfg_t
*/
pj_bool_t disable_tcp_switch;
+ /**
+ * Enable call media session to always be updated to the latest
+ * received early media SDP when receiving forked early media
+ * (multiple 183 responses with different To tag).
+ *
+ * Default is PJSIP_FOLLOW_EARLY_MEDIA_FORK.
+ */
+ pj_bool_t follow_early_media_fork;
+
} endpt;
/** Transaction layer settings. */
@@ -292,6 +301,21 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
/**
+ * Specify whether the call media session should be updated to the latest
+ * received early media SDP when receiving forked early media (multiple 183
+ * responses with different To tag).
+ *
+ * This option can also be controlled at run-time by the
+ * \a follow_early_media_fork setting in pjsip_cfg_t.
+ *
+ * Default is PJ_TRUE.
+ */
+#ifndef PJSIP_FOLLOW_EARLY_MEDIA_FORK
+# define PJSIP_FOLLOW_EARLY_MEDIA_FORK PJ_TRUE
+#endif
+
+
+/**
* Accept call replace in early state when invite is not initiated
* by the user agent. RFC 3891 Section 3 disallows this, however,
* for better interoperability reason, this might be ignored.
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index 3c383183..35bb8fe8 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -1735,23 +1735,27 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
*/
if (tsx_inv_data->sdp_done) {
pj_str_t res_tag;
+ int st_code;
res_tag = rdata->msg_info.to->tag;
+ st_code = rdata->msg_info.msg->line.status.code;
- /* Allow final response after SDP has been negotiated in early
- * media, IF this response is a final response with different
+ /* Allow final/early response after SDP has been negotiated in early
+ * media, IF this response is a final/early response with different
* tag.
*/
if (tsx->role == PJSIP_ROLE_UAC &&
- rdata->msg_info.msg->line.status.code/100 == 2 &&
+ (st_code/100 == 2 ||
+ (st_code==183 && pjsip_cfg()->endpt.follow_early_media_fork)) &&
tsx_inv_data->done_early &&
pj_stricmp(&tsx_inv_data->done_tag, &res_tag))
{
const pjmedia_sdp_session *reoffer_sdp = NULL;
- PJ_LOG(4,(inv->obj_name, "Received forked final response "
+ PJ_LOG(4,(inv->obj_name, "Received forked %s response "
"after SDP negotiation has been done in early "
- "media. Renegotiating SDP.."));
+ "media. Renegotiating SDP..",
+ (st_code==183? "early" : "final" )));
/* Retrieve original SDP offer from INVITE request */
reoffer_sdp = (const pjmedia_sdp_session*)
@@ -1763,7 +1767,7 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
reoffer_sdp);
if (status != PJ_SUCCESS) {
PJ_LOG(1,(inv->obj_name, "Error updating local offer for "
- "forked 2xx response (err=%d)", status));
+ "forked 2xx/183 response (err=%d)", status));
return status;
}
diff --git a/pjsip/src/pjsip/sip_config.c b/pjsip/src/pjsip/sip_config.c
index 1fa3b6bd..8c0dac1d 100644
--- a/pjsip/src/pjsip/sip_config.c
+++ b/pjsip/src/pjsip/sip_config.c
@@ -29,7 +29,8 @@ pjsip_cfg_t pjsip_sip_cfg_var =
PJSIP_ACCEPT_REPLACE_IN_EARLY_STATE,
0,
0,
- PJSIP_DONT_SWITCH_TO_TCP
+ PJSIP_DONT_SWITCH_TO_TCP,
+ PJSIP_FOLLOW_EARLY_MEDIA_FORK
},
/* Transaction settings */