- Timestamp:
- Dec 28, 2016 3:40:07 AM (8 years ago)
- Location:
- pjproject/branches/projects/uwp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/uwp
- Property svn:mergeinfo changed
/pjproject/trunk (added) merged: 5209,5212-5234,5237-5253,5255,5257-5292,5294-5297,5299-5332,5334-5394,5396-5438,5440-5469,5471-5496,5498-5510
- Property svn:mergeinfo changed
-
pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_call.c
r5185 r5513 570 570 { 571 571 opt->flag &= ~(PJSUA_CALL_UNHOLD | PJSUA_CALL_UPDATE_CONTACT | 572 PJSUA_CALL_NO_SDP_OFFER); 572 PJSUA_CALL_NO_SDP_OFFER | PJSUA_CALL_REINIT_MEDIA | 573 PJSUA_CALL_UPDATE_VIA); 573 574 } 574 575 … … 609 610 call->opt = *opt; 610 611 612 if (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) { 613 pjsua_media_channel_deinit(call->index); 614 } 615 611 616 /* If call is established or media channel hasn't been initialized, 612 617 * reinit media channel. … … 614 619 if ((call->inv && call->inv->state == PJSIP_INV_STATE_CONNECTING && 615 620 call->med_cnt == 0) || 616 (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED)) 621 (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) || 622 (call->opt.flag & PJSUA_CALL_REINIT_MEDIA)) 617 623 { 618 624 pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC; … … 632 638 633 639 return PJ_SUCCESS; 640 } 641 642 static void dlg_set_via(pjsip_dialog *dlg, pjsua_acc *acc) 643 { 644 if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) { 645 pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp); 646 } else if (!pjsua_sip_acc_is_using_stun(acc->index)) { 647 /* Choose local interface to use in Via if acc is not using 648 * STUN. See https://trac.pjsip.org/repos/ticket/1804 649 */ 650 pjsip_host_port via_addr; 651 const void *via_tp; 652 653 if (pjsua_acc_get_uac_addr(acc->index, dlg->pool, &acc->cfg.id, 654 &via_addr, NULL, NULL, 655 &via_tp) == PJ_SUCCESS) 656 { 657 pjsip_dlg_set_via_sent_by(dlg, &via_addr, 658 (pjsip_transport*)via_tp); 659 } 660 } 634 661 } 635 662 … … 773 800 pjsip_dlg_inc_lock(dlg); 774 801 775 if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) { 776 pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp); 777 } else if (!pjsua_sip_acc_is_using_stun(acc_id)) { 778 /* Choose local interface to use in Via if acc is not using 779 * STUN. See https://trac.pjsip.org/repos/ticket/1804 780 */ 781 pjsip_host_port via_addr; 782 const void *via_tp; 783 784 if (pjsua_acc_get_uac_addr(acc_id, dlg->pool, &acc->cfg.id, 785 &via_addr, NULL, NULL, 786 &via_tp) == PJ_SUCCESS) 787 { 788 pjsip_dlg_set_via_sent_by(dlg, &via_addr, 789 (pjsip_transport*)via_tp); 790 } 791 } 802 dlg_set_via(dlg, acc); 792 803 793 804 /* Calculate call's secure level */ … … 954 965 struct call_answer *answer, *next; 955 966 967 /* No initial answer yet, this function should be called again later */ 968 if (!call->inv->last_answer) 969 return; 970 956 971 answer = call->async_call.call_var.inc_call.answers.next; 957 972 while (answer != &call->async_call.call_var.inc_call.answers) { … … 983 998 pjsip_tx_data *response = NULL; 984 999 unsigned options = 0; 1000 pjsip_dialog *dlg = call->async_call.dlg; 985 1001 int sip_err_code = (info? info->sip_err_code: 0); 986 1002 pj_status_t status = (info? info->status: PJ_SUCCESS); 987 1003 988 1004 PJSUA_LOCK(); 1005 1006 /* Increment the dialog's lock to prevent it to be destroyed prematurely, 1007 * such as in case of transport error. 1008 */ 1009 pjsip_dlg_inc_lock(dlg); 1010 1011 /* Decrement dialog session. */ 1012 pjsip_dlg_dec_session(dlg, &pjsua_var.mod); 989 1013 990 1014 if (status != PJ_SUCCESS) { … … 997 1021 pjsua_media_channel_deinit(call->index); 998 1022 call->med_ch_cb = NULL; 1023 pjsip_dlg_dec_lock(dlg); 999 1024 PJSUA_UNLOCK(); 1000 1025 return PJ_SUCCESS; … … 1068 1093 } 1069 1094 } 1070 1095 1096 pjsip_dlg_dec_lock(dlg); 1097 1071 1098 PJSUA_UNLOCK(); 1072 1099 return status; … … 1089 1116 pjsip_inv_session *inv = NULL; 1090 1117 int acc_id; 1091 pjsua_call *call ;1118 pjsua_call *call = NULL; 1092 1119 int call_id = -1; 1093 1120 int sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR; … … 1210 1237 goto on_return; 1211 1238 } 1239 } 1240 1241 if (!replaced_dlg) { 1242 /* Clone rdata. */ 1243 pjsip_rx_data_clone(rdata, 0, &call->incoming_data); 1212 1244 } 1213 1245 … … 1352 1384 1353 1385 /* Create dialog: */ 1354 status = pjsip_dlg_create_uas ( pjsip_ua_instance(), rdata,1355 &contact, &dlg);1386 status = pjsip_dlg_create_uas_and_inc_lock( pjsip_ua_instance(), rdata, 1387 &contact, &dlg); 1356 1388 if (status != PJ_SUCCESS) { 1357 1389 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, … … 1460 1492 call->async_call.dlg = dlg; 1461 1493 pj_list_init(&call->async_call.call_var.inc_call.answers); 1494 1495 pjsip_dlg_inc_session(dlg, &pjsua_var.mod); 1462 1496 1463 1497 /* Init media channel, only when there is offer or call replace request. … … 1502 1536 pjsip_dlg_dec_lock(dlg); 1503 1537 1538 pjsip_dlg_dec_session(dlg, &pjsua_var.mod); 1539 1504 1540 call->inv = NULL; 1505 1541 call->async_call.dlg = NULL; … … 1610 1646 if (pjsua_var.ua_cfg.cb.on_incoming_call) { 1611 1647 pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata); 1648 1649 /* onIncomingCall() may be simulated by onCreateMediaTransport() 1650 * when media init is done synchrounously (see #1916). And if app 1651 * happens to answer/hangup the call from the callback, the 1652 * answer/hangup should have been delayed (see #1923), 1653 * so let's process the answer/hangup now. 1654 */ 1655 if (call->async_call.call_var.inc_call.hangup) { 1656 pjsua_call_hangup(call_id, call->last_code, &call->last_text, 1657 NULL); 1658 } else if (call->med_ch_cb == NULL && call->inv) { 1659 process_pending_call_answer(call); 1660 } 1612 1661 } else { 1613 1662 pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE, … … 1619 1668 /* This INVITE request has been handled. */ 1620 1669 on_return: 1670 if (dlg) { 1671 pjsip_dlg_dec_lock(dlg); 1672 } 1673 1674 if (call && call->incoming_data) { 1675 pjsip_rx_data_free_cloned(call->incoming_data); 1676 call->incoming_data = NULL; 1677 } 1678 1621 1679 pj_log_pop_indent(); 1622 1680 PJSUA_UNLOCK(); … … 2189 2247 /* If media transport creation is not yet completed, we will answer 2190 2248 * the call in the media transport creation callback instead. 2249 * Or if initial answer is not sent yet, we will answer the call after 2250 * initial answer is sent (see #1923). 2191 2251 */ 2192 if (call->med_ch_cb ) {2252 if (call->med_ch_cb || !call->inv->last_answer) { 2193 2253 struct call_answer *answer; 2194 2254 … … 2204 2264 } 2205 2265 if (reason) { 2266 answer->reason = PJ_POOL_ZALLOC_T(call->inv->pool_prov, pj_str_t); 2206 2267 pj_strdup(call->inv->pool_prov, answer->reason, reason); 2207 2268 } … … 2292 2353 * the call in the media transport creation callback instead. 2293 2354 */ 2294 if (call->med_ch_cb && !call->inv) { 2355 if ((call->med_ch_cb && !call->inv) || 2356 ((call->inv != NULL) && (call->inv->state == PJSIP_INV_STATE_NULL))) 2357 { 2295 2358 PJ_LOG(4,(THIS_FILE, "Pending call %d hangup upon completion " 2296 2359 "of media transport", call_id)); 2297 call->async_call.call_var.out_call.hangup = PJ_TRUE; 2360 2361 if (call->inv->role == PJSIP_ROLE_UAS) 2362 call->async_call.call_var.inc_call.hangup = PJ_TRUE; 2363 else 2364 call->async_call.call_var.out_call.hangup = PJ_TRUE; 2365 2298 2366 if (code == 0) 2299 2367 call->last_code = PJSIP_SC_REQUEST_TERMINATED; … … 2438 2506 } 2439 2507 2508 if ((options & PJSUA_CALL_UPDATE_VIA) && 2509 pjsua_acc_is_valid(call->acc_id)) 2510 { 2511 dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]); 2512 } 2513 2440 2514 /* Create re-INVITE with new offer */ 2441 2515 status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata); … … 2559 2633 } 2560 2634 2635 if ((call->opt.flag & PJSUA_CALL_UPDATE_VIA) && 2636 pjsua_acc_is_valid(call->acc_id)) 2637 { 2638 dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]); 2639 } 2640 2561 2641 /* Create re-INVITE with new offer */ 2562 2642 status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata); … … 2668 2748 } 2669 2749 2750 if ((call->opt.flag & PJSUA_CALL_UPDATE_VIA) && 2751 pjsua_acc_is_valid(call->acc_id)) 2752 { 2753 dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]); 2754 } 2755 2670 2756 /* Create UPDATE with new offer */ 2671 2757 status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata); … … 2784 2870 pj_str_t str_dest; 2785 2871 int len; 2872 char call_id_dest_buf[PJSIP_MAX_URL_SIZE * 2]; 2873 int call_id_len; 2786 2874 pjsip_uri *uri; 2787 2875 pj_status_t status; 2876 const pjsip_parser_const_t *pconst; 2788 2877 2789 2878 … … 2830 2919 2831 2920 str_dest.slen += len; 2832 2921 2922 /* This uses the the same scanner definition used for SIP parsing 2923 * to escape the call-id in the refer. 2924 * 2925 * A common pattern for call-ids is: name@domain. The '@' character, 2926 * when used in a URL parameter, throws off many SIP parsers. 2927 * URL escape it based off of the allowed characters for header values. 2928 */ 2929 pconst = pjsip_parser_const(); 2930 call_id_len = pj_strncpy2_escape(call_id_dest_buf, &dest_dlg->call_id->id, 2931 PJ_ARRAY_SIZE(call_id_dest_buf), 2932 &pconst->pjsip_HDR_CHAR_SPEC); 2933 if (call_id_len < 0) { 2934 status = PJSIP_EURITOOLONG; 2935 goto on_error; 2936 } 2833 2937 2834 2938 /* Build the URI */ … … 2841 2945 ((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ? 2842 2946 "" : "Require=replaces&"), 2843 (int)dest_dlg->call_id->id.slen,2844 dest_dlg->call_id->id.ptr,2947 call_id_len, 2948 call_id_dest_buf, 2845 2949 (int)dest_dlg->remote.info->tag.slen, 2846 2950 dest_dlg->remote.info->tag.ptr, … … 4050 4154 } 4051 4155 4156 cleanup_call_setting_flag(&call->opt); 4157 4052 4158 if (pjsua_var.ua_cfg.cb.on_call_rx_offer) { 4053 4159 pjsip_status_code code = PJSIP_SC_OK; 4054 4160 pjsua_call_setting opt; 4055 4161 4056 cleanup_call_setting_flag(&call->opt);4057 4162 opt = call->opt; 4058 4059 4163 (*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL, 4060 4164 &code, &opt); … … 4182 4286 #endif 4183 4287 4288 cleanup_call_setting_flag(&call->opt); 4289 4184 4290 if (pjsua_var.ua_cfg.cb.on_call_tx_offer) { 4185 cleanup_call_setting_flag(&call->opt);4186 4291 (*pjsua_var.ua_cfg.cb.on_call_tx_offer)(call->index, NULL, 4187 4292 &call->opt); … … 4471 4576 4472 4577 if (refer_sub) { 4473 if ( !pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0)4578 if (pj_strnicmp2(&refer_sub->hvalue, "true", 4)!=0) 4474 4579 no_refer_sub = PJ_TRUE; 4475 4580 } … … 4777 4882 tsx->state >= PJSIP_TSX_STATE_COMPLETED && 4778 4883 e->body.tsx_state.prev_state < PJSIP_TSX_STATE_COMPLETED && 4779 (tsx->status_code!=401 && tsx->status_code!=407 && 4884 (!PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 300) && 4885 tsx->status_code!=401 && tsx->status_code!=407 && 4780 4886 tsx->status_code!=422)) 4781 4887 { … … 4822 4928 tsx->state >= PJSIP_TSX_STATE_COMPLETED && 4823 4929 e->body.tsx_state.prev_state < PJSIP_TSX_STATE_COMPLETED && 4824 (tsx->status_code!=401 && tsx->status_code!=407 && 4930 (!PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 300) && 4931 tsx->status_code!=401 && tsx->status_code!=407 && 4825 4932 tsx->status_code!=422)) 4826 4933 {
Note: See TracChangeset
for help on using the changeset viewer.