Re #1788: Add support to allow INVITE/reINVITE with unknown body.
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@4924 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
5ee3d807c8
commit
e90ea2f3d8
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
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);
|
||||
}
|
||||
|
||||
status = pjsip_dlg_create_response(inv->dlg, rdata,
|
||||
(status == PJMEDIA_SDP_EINSDP)?415:488,
|
||||
NULL, &tdata);
|
||||
|
||||
if (status != PJ_SUCCESS)
|
||||
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;
|
||||
|
||||
|
||||
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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue