From d476f61748b8a728c56207816e170d1bbf1a96df Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Wed, 17 Jun 2015 06:18:07 +0000 Subject: Fixed #1858: Remove extension tags (such as "100rel", "timer", "PRACK"), from Supported & Allow headers in outgoing messages (request & response), when the extension is disabled in the invite session. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5109 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsip-ua/sip_inv.h | 4 +- pjsip/src/pjsip-ua/sip_inv.c | 127 ++++++++++++++++++++++++++------------- 2 files changed, 87 insertions(+), 44 deletions(-) diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h index 858cb3a5..4f9777ca 100644 --- a/pjsip/include/pjsip-ua/sip_inv.h +++ b/pjsip/include/pjsip-ua/sip_inv.h @@ -478,7 +478,7 @@ PJ_DECL(void) pjsip_inv_usage_dump(void); * it can specify the SDP here. Otherwise it can leave * this to NULL, to let remote UAS specifies an offer. * @param options The options argument is bitmask combination of SIP - * features in pjsip_inv_options enumeration. + * features in pjsip_inv_option enumeration. * @param p_inv On successful return, the invite session will be put * in this argument. * @@ -615,7 +615,7 @@ PJ_DECL(pj_status_t) pjsip_inv_verify_request3( pjsip_rx_data *rdata, * to rearrange the media lines in the answer so that it * matches the offer. * @param options The options argument is bitmask combination of SIP - * features in pjsip_inv_options enumeration. + * features in pjsip_inv_option enumeration. * @param p_inv Pointer to receive the newly created invite session. * * @return On successful, the invite session will be put in diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index 3993c255..3dd354b6 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -1675,6 +1675,67 @@ static pjsip_msg_body *create_sdp_body(pj_pool_t *pool, return body; } +/* Utility to remove a string value from generic array header */ +static void remove_val_from_array_hdr(pjsip_generic_array_hdr *arr_hdr, + const pj_str_t *val) +{ + unsigned i; + for (i=0; icount; ++i) { + if (pj_stricmp(&arr_hdr->values[i], val)==0) { + pj_array_erase(arr_hdr->values, sizeof(arr_hdr->values[0]), + arr_hdr->count, i); + --arr_hdr->count; + break; + } + } +} + + +/* Remove disabled extensions, e.g: timer & 100rel, from Allow/Supported + * headers (see ticket #1858). + */ +static void cleanup_allow_sup_hdr(unsigned inv_option, + pjsip_tx_data *tdata, + pjsip_allow_hdr *allow_hdr, + pjsip_supported_hdr *sup_hdr) +{ + /* If all extensions are enabled, nothing to do */ + if ((inv_option & PJSIP_INV_SUPPORT_100REL) && + (inv_option & PJSIP_INV_SUPPORT_TIMER)) + { + return; + } + + if (!allow_hdr && tdata) { + allow_hdr = (pjsip_allow_hdr*) pjsip_msg_find_hdr(tdata->msg, + PJSIP_H_ALLOW, + NULL); + } + if (!sup_hdr && tdata) { + sup_hdr = (pjsip_supported_hdr*) pjsip_msg_find_hdr(tdata->msg, + PJSIP_H_SUPPORTED, + NULL); + } + + /* Remove "timer" from Supported header if Session-Timers is + * disabled (https://trac.pjsip.org/repos/ticket/1761) + */ + if ((inv_option & PJSIP_INV_SUPPORT_TIMER) == 0 && sup_hdr) { + const pj_str_t STR_TIMER = { "timer", 5 }; + remove_val_from_array_hdr(sup_hdr, &STR_TIMER); + } + + if ((inv_option & PJSIP_INV_SUPPORT_100REL) == 0) { + const pj_str_t STR_PRACK = { "PRACK", 5 }; + const pj_str_t STR_100REL = { "100rel", 6 }; + + if (allow_hdr) + remove_val_from_array_hdr(allow_hdr, &STR_PRACK); + if (sup_hdr) + remove_val_from_array_hdr(sup_hdr, &STR_100REL); + } +} + /* * Create initial INVITE request. */ @@ -1683,6 +1744,8 @@ PJ_DEF(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv, { pjsip_tx_data *tdata; const pjsip_hdr *hdr; + pjsip_allow_hdr *allow_hdr = NULL; + pjsip_supported_hdr *sup_hdr = NULL; pj_bool_t has_sdp; pj_status_t status; @@ -1750,36 +1813,23 @@ PJ_DEF(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv, if (inv->dlg->add_allow) { hdr = pjsip_endpt_get_capability(inv->dlg->endpt, PJSIP_H_ALLOW, NULL); if (hdr) { - pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) - pjsip_hdr_shallow_clone(tdata->pool, hdr)); + allow_hdr = (pjsip_allow_hdr*) + pjsip_hdr_shallow_clone(tdata->pool, hdr); + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)allow_hdr); } } /* Add Supported header */ hdr = pjsip_endpt_get_capability(inv->dlg->endpt, PJSIP_H_SUPPORTED, NULL); if (hdr) { - pjsip_supported_hdr *h_sup; - - h_sup = (pjsip_supported_hdr*) pjsip_hdr_clone(tdata->pool, hdr); - /* Remove "timer" from Supported header if Session-Timers is - * disabled (https://trac.pjsip.org/repos/ticket/1761) - */ - if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0) { - unsigned i; - const pj_str_t STR_TIMER = { "timer", 5 }; - for (i=0; icount; ++i) { - if (pj_stricmp(&h_sup->values[i], &STR_TIMER)==0) { - pj_array_erase(h_sup->values, sizeof(h_sup->values[0]), - h_sup->count, i); - --h_sup->count; - break; - } - } - } - - pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)h_sup); + sup_hdr = (pjsip_supported_hdr*) + pjsip_hdr_shallow_clone(tdata->pool, hdr); + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)sup_hdr); } + /* Cleanup Allow & Supported headers from disabled extensions */ + cleanup_allow_sup_hdr(inv->options, NULL, allow_hdr, sup_hdr); + /* Add Require header. */ if ((inv->options & PJSIP_INV_REQUIRE_100REL) || (inv->options & PJSIP_INV_REQUIRE_TIMER)) @@ -2228,6 +2278,9 @@ PJ_DEF(pj_status_t) pjsip_inv_initial_answer( pjsip_inv_session *inv, goto on_return; } + /* Cleanup Allow & Supported headers from disabled extensions */ + cleanup_allow_sup_hdr(inv->options, tdata, NULL, NULL); + /* Save this answer */ inv->last_answer = tdata; pjsip_tx_data_add_ref(inv->last_answer); @@ -2292,6 +2345,9 @@ PJ_DEF(pj_status_t) pjsip_inv_answer( pjsip_inv_session *inv, /* Invoke Session Timers */ pjsip_timer_update_resp(inv, last_res); + /* Cleanup Allow & Supported headers from disabled extensions */ + cleanup_allow_sup_hdr(inv->options, last_res, NULL, NULL); + *p_tdata = last_res; on_return: @@ -2882,6 +2938,7 @@ PJ_DEF(pj_status_t) pjsip_inv_update ( pjsip_inv_session *inv, pjsip_tx_data *tdata = NULL; pjmedia_sdp_session *sdp_copy; const pjsip_hdr *hdr; + pjsip_supported_hdr *sup_hdr = NULL; pj_status_t status = PJ_SUCCESS; /* Verify arguments. */ @@ -2957,32 +3014,18 @@ PJ_DEF(pj_status_t) pjsip_inv_update ( pjsip_inv_session *inv, */ hdr = pjsip_endpt_get_capability(inv->dlg->endpt, PJSIP_H_SUPPORTED, NULL); if (hdr) { - pjsip_supported_hdr *h_sup; - - h_sup = (pjsip_supported_hdr*) pjsip_hdr_clone(tdata->pool, hdr); - /* Remove "timer" from Supported header if Session-Timers is - * disabled (https://trac.pjsip.org/repos/ticket/1761) - */ - if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0) { - unsigned i; - const pj_str_t STR_TIMER = { "timer", 5 }; - for (i=0; icount; ++i) { - if (pj_stricmp(&h_sup->values[i], &STR_TIMER)==0) { - pj_array_erase(h_sup->values, sizeof(h_sup->values[0]), - h_sup->count, i); - --h_sup->count; - break; - } - } - } - - pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)h_sup); + sup_hdr = (pjsip_supported_hdr*) + pjsip_hdr_shallow_clone(tdata->pool, hdr); + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)sup_hdr); } status = pjsip_timer_update_req(inv, tdata); if (status != PJ_SUCCESS) goto on_error; + /* Cleanup Allow & Supported headers from disabled extensions */ + cleanup_allow_sup_hdr(inv->options, NULL, NULL, sup_hdr); + /* Unlock dialog. */ pjsip_dlg_dec_lock(inv->dlg); -- cgit v1.2.3