summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiza Sulistyo <riza@teluu.com>2014-09-17 12:11:45 +0000
committerRiza Sulistyo <riza@teluu.com>2014-09-17 12:11:45 +0000
commit7e466f2b480ba0120aa15e9ca63edd18f7364af6 (patch)
tree3c70c363f66c7db8db2851e522ac44565a055440
parentfb3948795ad372ceaad306d2ea18c70ee3a846e4 (diff)
Re #1788: Add support to allow INVITE/reINVITE with unknown body.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4924 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip/sip_config.h12
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c61
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c57
3 files changed, 94 insertions, 36 deletions
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index f787dc3d..3fd0e41d 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -1208,6 +1208,18 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
# define PJSIP_HAS_TX_DATA_LIST 0
#endif
+/**
+ * Specify whether to accept INVITE/re-INVITE with unknown content type,
+ * by default the stack will reject this type of message as specified in
+ * RFC3261 section 8.2.3.
+ * Application that wishes to process the body could set this to PJ_TRUE,
+ * be informed that SDP offer/answer will still be present.
+ *
+ * Default: PJ_FALSE
+ */
+#ifndef PJSIP_INV_ACCEPT_UNKNOWN_BODY
+# define PJSIP_INV_ACCEPT_UNKNOWN_BODY PJ_FALSE
+#endif
PJ_END_DECL
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index d098cd6b..0c08f076 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -4737,36 +4737,53 @@ static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)
}
if (status != PJ_SUCCESS) {
+ pj_bool_t reject_message = PJ_TRUE;
- /* Not Acceptable */
- const pjsip_hdr *accept;
-
- /* The incoming SDP is unacceptable. If the SDP negotiator
- * state has just been changed, i.e: DONE -> REMOTE_OFFER,
- * revert it back.
- */
- if (pjmedia_sdp_neg_get_state(inv->neg) ==
- PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER)
+ if (status == PJMEDIA_SDP_EINSDP)
{
- pjmedia_sdp_neg_cancel_offer(inv->neg);
+ sdp_info = pjsip_rdata_get_sdp_info(rdata);
+ if (sdp_info->body.ptr == NULL &&
+ PJSIP_INV_ACCEPT_UNKNOWN_BODY)
+ {
+ /* Message body is not "application/sdp" */
+ reject_message = PJ_FALSE;
+ }
}
- status = pjsip_dlg_create_response(inv->dlg, rdata,
- 488, NULL, &tdata);
- if (status != PJ_SUCCESS)
- return;
+ if (reject_message) {
+ /* Not Acceptable */
+ const pjsip_hdr *accept;
+ /* The incoming SDP is unacceptable. If the SDP negotiator
+ * state has just been changed, i.e: DONE -> REMOTE_OFFER,
+ * revert it back.
+ */
+ if (pjmedia_sdp_neg_get_state(inv->neg) ==
+ PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER)
+ {
+ pjmedia_sdp_neg_cancel_offer(inv->neg);
+ }
- accept = pjsip_endpt_get_capability(dlg->endpt, PJSIP_H_ACCEPT,
- NULL);
- if (accept) {
- pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)
- pjsip_hdr_clone(tdata->pool, accept));
- }
+ status = pjsip_dlg_create_response(inv->dlg, rdata,
+ (status == PJMEDIA_SDP_EINSDP)?415:488,
+ NULL, &tdata);
- status = pjsip_dlg_send_response(dlg, tsx, tdata);
+ if (status != PJ_SUCCESS)
+ return;
- return;
+
+ accept = pjsip_endpt_get_capability(dlg->endpt,
+ PJSIP_H_ACCEPT,
+ NULL);
+ if (accept) {
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)
+ pjsip_hdr_clone(tdata->pool, accept));
+ }
+
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
+
+ return;
+ }
}
/* Create 2xx ANSWER */
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 34e0acc4..fd8bae01 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -1199,32 +1199,61 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
offer = sdp_info->sdp;
status = sdp_info->sdp_err;
- if (status==PJ_SUCCESS && sdp_info->sdp==NULL)
- status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
+ if (status==PJ_SUCCESS && sdp_info->sdp==NULL &&
+ !PJSIP_INV_ACCEPT_UNKNOWN_BODY)
+ {
+ if (sdp_info->body.ptr == NULL) {
+ status = PJSIP_ERRNO_FROM_SIP_STATUS(
+ PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
+ } else {
+ status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
+ }
+ }
if (status != PJ_SUCCESS) {
- const pj_str_t reason = pj_str("Bad SDP");
pjsip_hdr hdr_list;
- pjsip_warning_hdr *w;
- pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE",
- status);
+ /* Check if body really contains SDP. */
+ if (sdp_info->body.ptr == NULL) {
+ /* Couldn't find "application/sdp" */
+ pjsip_accept_hdr *acc;
- w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool,
- pjsip_endpt_name(pjsua_var.endpt),
- status);
- pj_list_init(&hdr_list);
- pj_list_push_back(&hdr_list, w);
+ pjsua_perror(THIS_FILE, "Unknown Content-Type in incoming "\
+ "INVITE", status);
- pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400,
- &reason, &hdr_list, NULL, NULL);
+ /* Add Accept header to response */
+ acc = pjsip_accept_hdr_create(rdata->tp_info.pool);
+ PJ_ASSERT_RETURN(acc, PJ_ENOMEM);
+ acc->values[acc->count++] = pj_str("application/sdp");
+ pj_list_init(&hdr_list);
+ pj_list_push_back(&hdr_list, acc);
+
+ pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
+ PJSIP_SC_UNSUPPORTED_MEDIA_TYPE,
+ NULL, &hdr_list, NULL, NULL);
+ } else {
+ const pj_str_t reason = pj_str("Bad SDP");
+ pjsip_warning_hdr *w;
+
+ pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE",
+ status);
+
+ w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool,
+ pjsip_endpt_name(pjsua_var.endpt),
+ status);
+ pj_list_init(&hdr_list);
+ pj_list_push_back(&hdr_list, w);
+
+ pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400,
+ &reason, &hdr_list, NULL, NULL);
+ }
goto on_return;
}
/* Do quick checks on SDP before passing it to transports. More elabore
* checks will be done in pjsip_inv_verify_request2() below.
*/
- if (offer->media_count==0) {
+ if ((offer) && (offer->media_count==0)) {
const pj_str_t reason = pj_str("Missing media in SDP");
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason,
NULL, NULL, NULL);