diff options
Diffstat (limited to 'libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch')
| -rw-r--r-- | libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch b/libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch deleted file mode 100644 index 8db8aab..0000000 --- a/libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch +++ /dev/null @@ -1,653 +0,0 @@ -From 0ed41eb5fd0e4192e1b7dc374f819d17aef3e805 Mon Sep 17 00:00:00 2001 -From: George Joseph <gtjoseph@users.noreply.github.com> -Date: Tue, 21 Dec 2021 19:32:22 -0700 -Subject: [PATCH] sip_inv: Additional multipart support (#2919) (#2920) - ---- - pjsip/include/pjsip-ua/sip_inv.h | 108 ++++++++++- - pjsip/src/pjsip-ua/sip_inv.c | 240 ++++++++++++++++++++----- - pjsip/src/test/inv_offer_answer_test.c | 103 ++++++++++- - 3 files changed, 394 insertions(+), 57 deletions(-) - ---- a/pjsip/include/pjsip-ua/sip_inv.h -+++ b/pjsip/include/pjsip-ua/sip_inv.h -@@ -451,11 +451,11 @@ struct pjsip_inv_session - - - /** -- * This structure represents SDP information in a pjsip_rx_data. Application -- * retrieve this information by calling #pjsip_rdata_get_sdp_info(). This -+ * This structure represents SDP information in a pjsip_(rx|tx)_data. Application -+ * retrieve this information by calling #pjsip_get_sdp_info(). This - * mechanism supports multipart message body. - */ --typedef struct pjsip_rdata_sdp_info -+typedef struct pjsip_sdp_info - { - /** - * Pointer and length of the text body in the incoming message. If -@@ -475,7 +475,15 @@ typedef struct pjsip_rdata_sdp_info - */ - pjmedia_sdp_session *sdp; - --} pjsip_rdata_sdp_info; -+} pjsip_sdp_info; -+ -+/** -+ * For backwards compatibility and completeness, -+ * pjsip_rdata_sdp_info and pjsip_tdata_sdp_info -+ * are typedef'd to pjsip_sdp_info. -+ */ -+typedef pjsip_sdp_info pjsip_rdata_sdp_info; -+typedef pjsip_sdp_info pjsip_tdata_sdp_info; - - - /** -@@ -1046,6 +1054,44 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_bo - pjsip_msg_body **p_body); - - /** -+ * This is a utility function to create a multipart body with the -+ * SIP body as the first part. -+ * -+ * @param pool Pool to allocate memory. -+ * @param sdp SDP session to be put in the SIP message body. -+ * @param p_body Pointer to receive SIP message body containing -+ * the SDP session. -+ * -+ * @return PJ_SUCCESS on success. -+ */ -+PJ_DECL(pj_status_t) pjsip_create_multipart_sdp_body( pj_pool_t *pool, -+ pjmedia_sdp_session *sdp, -+ pjsip_msg_body **p_body); -+ -+/** -+ * Retrieve SDP information from a message body. Application should -+ * prefer to use this function rather than parsing the SDP manually since -+ * this function supports multipart message body. -+ * -+ * This function will only parse the SDP once, the first time it is called -+ * on the same message. Subsequent call on the same message will just pick -+ * up the already parsed SDP from the message. -+ * -+ * @param pool Pool to allocate memory. -+ * @param body The message body. -+ * @param msg_media_type From the rdata or tdata Content-Type header, if available. -+ * If NULL, the content_type from the body will be used. -+ * @param search_media_type The media type to search for. -+ * If NULL, "application/sdp" will be used. -+ * -+ * @return The SDP info. -+ */ -+PJ_DECL(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool, -+ pjsip_msg_body *body, -+ pjsip_media_type *msg_media_type, -+ const pjsip_media_type *search_media_type); -+ -+/** - * Retrieve SDP information from an incoming message. Application should - * prefer to use this function rather than parsing the SDP manually since - * this function supports multipart message body. -@@ -1061,6 +1107,60 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_bo - PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata); - - -+/** -+ * Retrieve SDP information from an incoming message. Application should -+ * prefer to use this function rather than parsing the SDP manually since -+ * this function supports multipart message body. -+ * -+ * This function will only parse the SDP once, the first time it is called -+ * on the same message. Subsequent call on the same message will just pick -+ * up the already parsed SDP from the message. -+ * -+ * @param rdata The incoming message. -+ * @param search_media_type The SDP media type to search for. -+ * If NULL, "application/sdp" will be used. -+ * -+ * @return The SDP info. -+ */ -+PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2( -+ pjsip_rx_data *rdata, -+ const pjsip_media_type *search_media_type); -+ -+/** -+ * Retrieve SDP information from an outgoing message. Application should -+ * prefer to use this function rather than parsing the SDP manually since -+ * this function supports multipart message body. -+ * -+ * This function will only parse the SDP once, the first time it is called -+ * on the same message. Subsequent call on the same message will just pick -+ * up the already parsed SDP from the message. -+ * -+ * @param tdata The outgoing message. -+ * -+ * @return The SDP info. -+ */ -+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata); -+ -+/** -+ * Retrieve SDP information from an outgoing message. Application should -+ * prefer to use this function rather than parsing the SDP manually since -+ * this function supports multipart message body. -+ * -+ * This function will only parse the SDP once, the first time it is called -+ * on the same message. Subsequent call on the same message will just pick -+ * up the already parsed SDP from the message. -+ * -+ * @param tdata The outgoing message. -+ * @param search_media_type The SDP media type to search for. -+ * If NULL, "application/sdp" will be used. -+ * -+ * @return The SDP info. -+ */ -+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2( -+ pjsip_tx_data *tdata, -+ const pjsip_media_type *search_media_type); -+ -+ - PJ_END_DECL - - /** ---- a/pjsip/src/pjsip-ua/sip_inv.c -+++ b/pjsip/src/pjsip-ua/sip_inv.c -@@ -118,6 +118,8 @@ static pj_status_t handle_timer_response - static pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv, - pjsip_event *e); - -+static int print_sdp(pjsip_msg_body *body, char *buf, pj_size_t len); -+ - static void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) = - { - &inv_on_state_null, -@@ -956,66 +958,170 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac - return PJ_SUCCESS; - } - --PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata) --{ -- pjsip_rdata_sdp_info *sdp_info; -- pjsip_msg_body *body = rdata->msg_info.msg->body; -- pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype; -- pjsip_media_type app_sdp; -+PJ_DEF(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool, -+ pjsip_msg_body *body, -+ pjsip_media_type *msg_media_type, -+ const pjsip_media_type *search_media_type) -+{ -+ pjsip_sdp_info *sdp_info; -+ pjsip_media_type search_type; -+ pjsip_media_type multipart_mixed; -+ pjsip_media_type multipart_alternative; -+ pjsip_media_type *msg_type; -+ pj_status_t status; - -- sdp_info = (pjsip_rdata_sdp_info*) -- rdata->endpt_info.mod_data[mod_inv.mod.id]; -- if (sdp_info) -- return sdp_info; -+ sdp_info = PJ_POOL_ZALLOC_T(pool, -+ pjsip_sdp_info); - -- sdp_info = PJ_POOL_ZALLOC_T(rdata->tp_info.pool, -- pjsip_rdata_sdp_info); - PJ_ASSERT_RETURN(mod_inv.mod.id >= 0, sdp_info); -- rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info; - -- pjsip_media_type_init2(&app_sdp, "application", "sdp"); -+ if (!body) { -+ return sdp_info; -+ } - -- if (body && ctype_hdr && -- pj_stricmp(&ctype_hdr->media.type, &app_sdp.type)==0 && -- pj_stricmp(&ctype_hdr->media.subtype, &app_sdp.subtype)==0) -+ if (msg_media_type) { -+ msg_type = msg_media_type; -+ } else { -+ if (body->content_type.type.slen == 0) { -+ return sdp_info; -+ } -+ msg_type = &body->content_type; -+ } -+ -+ if (!search_media_type) { -+ pjsip_media_type_init2(&search_type, "application", "sdp"); -+ } else { -+ pj_memcpy(&search_type, search_media_type, sizeof(search_type)); -+ } -+ -+ pjsip_media_type_init2(&multipart_mixed, "multipart", "mixed"); -+ pjsip_media_type_init2(&multipart_alternative, "multipart", "alternative"); -+ -+ if (pjsip_media_type_cmp(msg_type, &search_type, PJ_FALSE) == 0) - { -- sdp_info->body.ptr = (char*)body->data; -- sdp_info->body.slen = body->len; -- } else if (body && ctype_hdr && -- pj_stricmp2(&ctype_hdr->media.type, "multipart")==0 && -- (pj_stricmp2(&ctype_hdr->media.subtype, "mixed")==0 || -- pj_stricmp2(&ctype_hdr->media.subtype, "alternative")==0)) -+ /* -+ * If the print_body function is print_sdp, we know that -+ * body->data is a pjmedia_sdp_session object and came from -+ * a tx_data. If not, it's the text representation of the -+ * sdp from an rx_data. -+ */ -+ if (body->print_body == print_sdp) { -+ sdp_info->sdp = body->data; -+ } else { -+ sdp_info->body.ptr = (char*)body->data; -+ sdp_info->body.slen = body->len; -+ } -+ } else if (pjsip_media_type_cmp(&multipart_mixed, msg_type, PJ_FALSE) == 0 || -+ pjsip_media_type_cmp(&multipart_alternative, msg_type, PJ_FALSE) == 0) - { -- pjsip_multipart_part *part; -+ pjsip_multipart_part *part; -+ part = pjsip_multipart_find_part(body, &search_type, NULL); -+ if (part) { -+ if (part->body->print_body == print_sdp) { -+ sdp_info->sdp = part->body->data; -+ } else { -+ sdp_info->body.ptr = (char*)part->body->data; -+ sdp_info->body.slen = part->body->len; -+ } -+ } -+ } - -- part = pjsip_multipart_find_part(body, &app_sdp, NULL); -- if (part) { -- sdp_info->body.ptr = (char*)part->body->data; -- sdp_info->body.slen = part->body->len; -- } -+ /* -+ * If the body was already a pjmedia_sdp_session, we can just -+ * return it. If not and there wasn't a text representation -+ * of the sdp either, we can also just return. -+ */ -+ if (sdp_info->sdp || !sdp_info->body.ptr) { -+ return sdp_info; - } - -- if (sdp_info->body.ptr) { -- pj_status_t status; -- status = pjmedia_sdp_parse(rdata->tp_info.pool, -- sdp_info->body.ptr, -- sdp_info->body.slen, -- &sdp_info->sdp); -- if (status == PJ_SUCCESS) -- status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE); -+ /* -+ * If the body was the text representation of teh SDP, we need -+ * to parse it to create a pjmedia_sdp_session object. -+ */ -+ status = pjmedia_sdp_parse(pool, -+ sdp_info->body.ptr, -+ sdp_info->body.slen, -+ &sdp_info->sdp); -+ if (status == PJ_SUCCESS) -+ status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE); - -- if (status != PJ_SUCCESS) { -- sdp_info->sdp = NULL; -- PJ_PERROR(1,(THIS_FILE, status, -- "Error parsing/validating SDP body")); -- } -+ if (status != PJ_SUCCESS) { -+ sdp_info->sdp = NULL; -+ PJ_PERROR(1, (THIS_FILE, status, -+ "Error parsing/validating SDP body")); -+ } -+ -+ sdp_info->sdp_err = status; -+ -+ return sdp_info; -+} -+ -+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2( -+ pjsip_rx_data *rdata, -+ const pjsip_media_type *search_media_type) -+{ -+ pjsip_media_type *msg_media_type = NULL; -+ pjsip_rdata_sdp_info *sdp_info; - -- sdp_info->sdp_err = status; -+ if (rdata->endpt_info.mod_data[mod_inv.mod.id]) { -+ return (pjsip_rdata_sdp_info *)rdata->endpt_info.mod_data[mod_inv.mod.id]; -+ } -+ -+ /* -+ * rdata should have a Content-Type header at this point but we'll -+ * make sure. -+ */ -+ if (rdata->msg_info.ctype) { -+ msg_media_type = &rdata->msg_info.ctype->media; - } -+ sdp_info = pjsip_get_sdp_info(rdata->tp_info.pool, -+ rdata->msg_info.msg->body, -+ msg_media_type, -+ search_media_type); -+ rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info; - - return sdp_info; - } - -+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata) -+{ -+ return pjsip_rdata_get_sdp_info2(rdata, NULL); -+} -+ -+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2( -+ pjsip_tx_data *tdata, -+ const pjsip_media_type *search_media_type) -+{ -+ pjsip_ctype_hdr *ctype_hdr = NULL; -+ pjsip_media_type *msg_media_type = NULL; -+ pjsip_tdata_sdp_info *sdp_info; -+ -+ if (tdata->mod_data[mod_inv.mod.id]) { -+ return (pjsip_tdata_sdp_info *)tdata->mod_data[mod_inv.mod.id]; -+ } -+ /* -+ * tdata won't usually have a Content-Type header at this point -+ * but we'll check just the same, -+ */ -+ ctype_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTENT_TYPE, NULL); -+ if (ctype_hdr) { -+ msg_media_type = &ctype_hdr->media; -+ } -+ -+ sdp_info = pjsip_get_sdp_info(tdata->pool, -+ tdata->msg->body, -+ msg_media_type, -+ search_media_type); -+ tdata->mod_data[mod_inv.mod.id] = sdp_info; -+ -+ return sdp_info; -+} -+ -+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata) -+{ -+ return pjsip_tdata_get_sdp_info2(tdata, NULL); -+} - - /* - * Verify incoming INVITE request. -@@ -1740,13 +1846,55 @@ PJ_DEF(pj_status_t) pjsip_create_sdp_bod - return PJ_SUCCESS; - } - -+static pjsip_multipart_part* create_sdp_part(pj_pool_t *pool, pjmedia_sdp_session *sdp) -+{ -+ pjsip_multipart_part *sdp_part; -+ pjsip_media_type media_type; -+ -+ pjsip_media_type_init2(&media_type, "application", "sdp"); -+ -+ sdp_part = pjsip_multipart_create_part(pool); -+ PJ_ASSERT_RETURN(sdp_part != NULL, NULL); -+ -+ sdp_part->body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body); -+ PJ_ASSERT_RETURN(sdp_part->body != NULL, NULL); -+ -+ pjsip_media_type_cp(pool, &sdp_part->body->content_type, &media_type); -+ -+ sdp_part->body->data = sdp; -+ sdp_part->body->clone_data = clone_sdp; -+ sdp_part->body->print_body = print_sdp; -+ -+ return sdp_part; -+} -+ -+PJ_DEF(pj_status_t) pjsip_create_multipart_sdp_body(pj_pool_t *pool, -+ pjmedia_sdp_session *sdp, -+ pjsip_msg_body **p_body) -+{ -+ pjsip_media_type media_type; -+ pjsip_msg_body *multipart; -+ pjsip_multipart_part *sdp_part; -+ -+ pjsip_media_type_init2(&media_type, "multipart", "mixed"); -+ multipart = pjsip_multipart_create(pool, &media_type, NULL); -+ PJ_ASSERT_RETURN(multipart != NULL, PJ_ENOMEM); -+ -+ sdp_part = create_sdp_part(pool, sdp); -+ PJ_ASSERT_RETURN(sdp_part != NULL, PJ_ENOMEM); -+ pjsip_multipart_add_part(pool, multipart, sdp_part); -+ *p_body = multipart; -+ -+ return PJ_SUCCESS; -+} -+ - static pjsip_msg_body *create_sdp_body(pj_pool_t *pool, - const pjmedia_sdp_session *c_sdp) - { - pjsip_msg_body *body; - pj_status_t status; - -- status = pjsip_create_sdp_body(pool, -+ status = pjsip_create_sdp_body(pool, - pjmedia_sdp_session_clone(pool, c_sdp), - &body); - -@@ -2069,6 +2217,7 @@ static pj_status_t inv_check_sdp_in_inco - ) - ) - { -+ pjsip_sdp_info *tdata_sdp_info; - const pjmedia_sdp_session *reoffer_sdp = NULL; - - PJ_LOG(4,(inv->obj_name, "Received %s response " -@@ -2077,14 +2226,15 @@ static pj_status_t inv_check_sdp_in_inco - (st_code/10==18? "early" : "final" ))); - - /* Retrieve original SDP offer from INVITE request */ -- reoffer_sdp = (const pjmedia_sdp_session*) -- tsx->last_tx->msg->body->data; -+ tdata_sdp_info = pjsip_tdata_get_sdp_info(tsx->last_tx); -+ reoffer_sdp = tdata_sdp_info->sdp; - - /* Feed the original offer to negotiator */ - status = pjmedia_sdp_neg_modify_local_offer2(inv->pool_prov, - inv->neg, - inv->sdp_neg_flags, - reoffer_sdp); -+ - if (status != PJ_SUCCESS) { - PJ_LOG(1,(inv->obj_name, "Error updating local offer for " - "forked 2xx/18x response (err=%d)", status)); ---- a/pjsip/src/test/inv_offer_answer_test.c -+++ b/pjsip/src/test/inv_offer_answer_test.c -@@ -137,6 +137,7 @@ typedef struct inv_test_param_t - pj_bool_t need_established; - unsigned count; - oa_t oa[4]; -+ pj_bool_t multipart_body; - } inv_test_param_t; - - typedef struct inv_test_t -@@ -257,6 +258,17 @@ static void on_media_update(pjsip_inv_se - } - } - -+ /* Special handling for standard offer/answer */ -+ if (inv_test.param.count == 1 && -+ inv_test.param.oa[0] == OFFERER_UAC && -+ inv_test.param.need_established) -+ { -+ jobs[job_cnt].type = ESTABLISH_CALL; -+ jobs[job_cnt].who = PJSIP_ROLE_UAS; -+ job_cnt++; -+ TRACE_((THIS_FILE, " C+++")); -+ } -+ - pj_assert(job_cnt <= PJ_ARRAY_SIZE(jobs)); - } - } -@@ -333,6 +345,15 @@ static pj_bool_t on_rx_request(pjsip_rx_ - NULL, &tdata); - pj_assert(status == PJ_SUCCESS); - -+ /* Use multipart body, if configured */ -+ if (sdp && inv_test.param.multipart_body) { -+ status = pjsip_create_multipart_sdp_body( -+ tdata->pool, -+ pjmedia_sdp_session_clone(tdata->pool, sdp), -+ &tdata->msg->body); -+ } -+ pj_assert(status == PJ_SUCCESS); -+ - status = pjsip_inv_send_msg(inv_test.uas, tdata); - pj_assert(status == PJ_SUCCESS); - -@@ -426,6 +447,7 @@ static int perform_test(inv_test_param_t - sdp = NULL; - - status = pjsip_inv_create_uac(dlg, sdp, inv_test.param.inv_option, &inv_test.uac); -+ //inv_test.uac->create_multipart = param->multipart_body; - PJ_ASSERT_RETURN(status==PJ_SUCCESS, -20); - - TRACE_((THIS_FILE, " Sending INVITE %s offer", (sdp ? "with" : "without"))); -@@ -436,8 +458,17 @@ static int perform_test(inv_test_param_t - status = pjsip_inv_invite(inv_test.uac, &tdata); - PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30); - -+ /* Use multipart body, if configured */ -+ if (sdp && param->multipart_body) { -+ status = pjsip_create_multipart_sdp_body( -+ tdata->pool, -+ pjmedia_sdp_session_clone(tdata->pool, sdp), -+ &tdata->msg->body); -+ } -+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, -40); -+ - status = pjsip_inv_send_msg(inv_test.uac, tdata); -- PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30); -+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, -50); - - /* - * Wait until test completes -@@ -525,13 +556,14 @@ static inv_test_param_t test_params[] = - 200/INVITE (answer) <-- - ACK --> - */ --#if 0 -+#if 1 - { - "Standard INVITE with offer", - 0, - PJ_TRUE, - 1, -- { OFFERER_UAC } -+ { OFFERER_UAC }, -+ PJ_FALSE - }, - - { -@@ -539,7 +571,25 @@ static inv_test_param_t test_params[] = - PJSIP_INV_REQUIRE_100REL, - PJ_TRUE, - 1, -- { OFFERER_UAC } -+ { OFFERER_UAC }, -+ PJ_FALSE -+ }, -+ { -+ "Standard INVITE with offer, with Multipart", -+ 0, -+ PJ_TRUE, -+ 1, -+ { OFFERER_UAC }, -+ PJ_TRUE -+ }, -+ -+ { -+ "Standard INVITE with offer, with 100rel, with Multipart", -+ PJSIP_INV_REQUIRE_100REL, -+ PJ_TRUE, -+ 1, -+ { OFFERER_UAC }, -+ PJ_TRUE - }, - #endif - -@@ -555,7 +605,8 @@ static inv_test_param_t test_params[] = - 0, - PJ_TRUE, - 1, -- { OFFERER_UAS } -+ { OFFERER_UAS }, -+ PJ_FALSE - }, - - { -@@ -563,7 +614,25 @@ static inv_test_param_t test_params[] = - PJSIP_INV_REQUIRE_100REL, - PJ_TRUE, - 1, -- { OFFERER_UAS } -+ { OFFERER_UAS }, -+ PJ_FALSE -+ }, -+ { -+ "INVITE with no offer, with Multipart", -+ 0, -+ PJ_TRUE, -+ 1, -+ { OFFERER_UAS }, -+ PJ_TRUE -+ }, -+ -+ { -+ "INVITE with no offer, with 100rel, with Multipart", -+ PJSIP_INV_REQUIRE_100REL, -+ PJ_TRUE, -+ 1, -+ { OFFERER_UAS }, -+ PJ_TRUE - }, - #endif - -@@ -584,14 +653,24 @@ static inv_test_param_t test_params[] = - 0, - PJ_TRUE, - 2, -- { OFFERER_UAC, OFFERER_UAC } -+ { OFFERER_UAC, OFFERER_UAC }, -+ PJ_FALSE -+ }, -+ { -+ "INVITE and UPDATE by UAC, with Multipart", -+ 0, -+ PJ_TRUE, -+ 2, -+ { OFFERER_UAC, OFFERER_UAC }, -+ PJ_TRUE - }, - { - "INVITE and UPDATE by UAC, with 100rel", - PJSIP_INV_REQUIRE_100REL, - PJ_TRUE, - 2, -- { OFFERER_UAC, OFFERER_UAC } -+ { OFFERER_UAC, OFFERER_UAC }, -+ PJ_FALSE - }, - #endif - -@@ -617,6 +696,14 @@ static inv_test_param_t test_params[] = - 4, - { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS } - }, -+ { -+ "INVITE and many UPDATE by UAC and UAS, with Multipart", -+ 0, -+ PJ_TRUE, -+ 4, -+ { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS }, -+ PJ_TRUE -+ }, - - }; - |
