Changeset 4728 for pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
- Timestamp:
- Feb 4, 2014 10:13:56 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r4724 r4728 1 1 /* $Id$ */ 2 /* 2 /* 3 3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) 4 4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> … … 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 #include <pjsua-lib/pjsua.h> … … 39 39 * The INFO method. 40 40 */ 41 const pjsip_method pjsip_info_method = 41 const pjsip_method pjsip_info_method = 42 42 { 43 43 PJSIP_OTHER_METHOD, … … 49 49 * session state has changed. 50 50 */ 51 static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 51 static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 52 52 pjsip_event *e); 53 53 … … 55 55 * has forked. 56 56 */ 57 static void pjsua_call_on_forked( pjsip_inv_session *inv, 57 static void pjsua_call_on_forked( pjsip_inv_session *inv, 58 58 pjsip_event *e); 59 59 … … 164 164 /* Check the route URI's and force loose route if required */ 165 165 for (i=0; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) { 166 status = normalize_route_uri(pjsua_var.pool, 166 status = normalize_route_uri(pjsua_var.pool, 167 167 &pjsua_var.ua_cfg.outbound_proxy[i]); 168 168 if (status != PJ_SUCCESS) … … 258 258 #if 1 259 259 /* New algorithm: round-robin */ 260 if (pjsua_var.next_call_id >= (int)pjsua_var.ua_cfg.max_calls || 260 if (pjsua_var.next_call_id >= (int)pjsua_var.ua_cfg.max_calls || 261 261 pjsua_var.next_call_id < 0) 262 262 { … … 264 264 } 265 265 266 for (cid=pjsua_var.next_call_id; 267 cid<(int)pjsua_var.ua_cfg.max_calls; 268 ++cid) 266 for (cid=pjsua_var.next_call_id; 267 cid<(int)pjsua_var.ua_cfg.max_calls; 268 ++cid) 269 269 { 270 270 if (pjsua_var.calls[cid].inv == NULL && … … 310 310 if (pj_stristr(dst_uri, &sips)) 311 311 return 2; 312 312 313 313 if (!pj_list_empty(&acc->route_set)) { 314 314 pjsip_route_hdr *r = acc->route_set.next; 315 315 pjsip_uri *uri = r->name_addr.uri; 316 316 pjsip_sip_uri *sip_uri; 317 317 318 318 sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri); 319 319 if (pj_stricmp2(&sip_uri->transport_param, "tls")==0) … … 338 338 pjsip_uri *uri = r->name_addr.uri; 339 339 pjsip_sip_uri *sip_uri; 340 340 341 341 sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri); 342 342 if (pj_stricmp2(&sip_uri->transport_param, "tls")==0) … … 468 468 /* Set credentials: */ 469 469 if (acc->cred_cnt) { 470 pjsip_auth_clt_set_credentials( &dlg->auth_sess, 470 pjsip_auth_clt_set_credentials( &dlg->auth_sess, 471 471 acc->cred_cnt, acc->cred); 472 472 } … … 479 479 status = pjsip_inv_invite(inv, &tdata); 480 480 if (status != PJ_SUCCESS) { 481 pjsua_perror(THIS_FILE, "Unable to create initial INVITE request", 481 pjsua_perror(THIS_FILE, "Unable to create initial INVITE request", 482 482 status); 483 483 goto on_error; … … 499 499 cb_called = PJ_TRUE; 500 500 501 /* Upon failure to send first request, the invite 501 /* Upon failure to send first request, the invite 502 502 * session would have been cleared. 503 503 */ … … 617 617 618 618 /* Check that account is valid */ 619 PJ_ASSERT_RETURN(acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc), 619 PJ_ASSERT_RETURN(acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc), 620 620 PJ_EINVAL); 621 621 … … 631 631 632 632 /* Create sound port if none is instantiated, to check if sound device 633 * can be used. But only do this with the conference bridge, as with 634 * audio switchboard (i.e. APS-Direct), we can only open the sound 633 * can be used. But only do this with the conference bridge, as with 634 * audio switchboard (i.e. APS-Direct), we can only open the sound 635 635 * device once the correct format has been known 636 636 */ 637 if (!pjsua_var.is_mswitch && pjsua_var.snd_port==NULL && 638 pjsua_var.null_snd==NULL && !pjsua_var.no_snd) 637 if (!pjsua_var.is_mswitch && pjsua_var.snd_port==NULL && 638 pjsua_var.null_snd==NULL && !pjsua_var.no_snd) 639 639 { 640 640 status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev); … … 679 679 tmp_pool = pjsua_pool_create("tmpcall10", 512, 256); 680 680 681 /* Verify that destination URI is valid before calling 682 * pjsua_acc_create_uac_contact, or otherwise there 681 /* Verify that destination URI is valid before calling 682 * pjsua_acc_create_uac_contact, or otherwise there 683 683 * a misleading "Invalid Contact URI" error will be printed 684 684 * when pjsua_acc_create_uac_contact() fails. … … 692 692 693 693 if (uri == NULL) { 694 pjsua_perror(THIS_FILE, "Unable to make call", 694 pjsua_perror(THIS_FILE, "Unable to make call", 695 695 PJSIP_EINVALIDREQURI); 696 696 status = PJSIP_EINVALIDREQURI; … … 714 714 acc_id, dest_uri); 715 715 if (status != PJ_SUCCESS) { 716 pjsua_perror(THIS_FILE, "Unable to generate Contact header", 716 pjsua_perror(THIS_FILE, "Unable to generate Contact header", 717 717 status); 718 718 goto on_error; … … 721 721 722 722 /* Create outgoing dialog: */ 723 status = pjsip_dlg_create_uac( pjsip_ua_instance(), 723 status = pjsip_dlg_create_uac( pjsip_ua_instance(), 724 724 &acc->cfg.id, &contact, 725 725 dest_uri, … … 745 745 /* Attach user data */ 746 746 call->user_data = user_data; 747 747 748 748 /* Store variables required for the callback after the async 749 749 * media transport creation is completed. … … 762 762 763 763 /* Init media channel */ 764 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, 764 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, 765 765 call->secure_level, dlg->pool, 766 766 NULL, NULL, PJ_TRUE, … … 813 813 814 814 /* Get the NAT type information in remote's SDP */ 815 static void update_remote_nat_type(pjsua_call *call, 815 static void update_remote_nat_type(pjsua_call *call, 816 816 const pjmedia_sdp_session *sdp) 817 817 { … … 900 900 { 901 901 struct call_answer *answer, *next; 902 902 903 903 answer = call->async_call.call_var.inc_call.answers.next; 904 904 while (answer != &call->async_call.call_var.inc_call.answers) { … … 906 906 pjsua_call_answer2(call->index, answer->opt, answer->code, 907 907 answer->reason, answer->msg_data); 908 908 909 909 /* Call might have been disconnected if application is answering 910 910 * with 200/OK and the media failed to start. … … 953 953 954 954 status = pjsua_media_channel_create_sdp(call_id, 955 call->async_call.dlg->pool, 955 call->async_call.dlg->pool, 956 956 offer, &answer, &sip_err_code); 957 957 if (status != PJ_SUCCESS) { … … 977 977 sip_err_code = PJSIP_ERRNO_TO_SIP_STATUS(status); 978 978 goto on_return; 979 } 979 } 980 980 981 981 on_return: … … 1007 1007 if (call->async_call.call_var.inc_call.replaced_dlg) { 1008 1008 /* Process pending call replace */ 1009 pjsip_dialog *replaced_dlg = 1009 pjsip_dialog *replaced_dlg = 1010 1010 call->async_call.call_var.inc_call.replaced_dlg; 1011 1011 process_incoming_call_replace(call, replaced_dlg); … … 1054 1054 /* Don't want to accept the call if shutdown is in progress */ 1055 1055 if (pjsua_var.thread_quit_flag) { 1056 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 1056 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 1057 1057 PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL, 1058 1058 NULL, NULL); … … 1069 1069 1070 1070 if (call_id == PJSUA_INVALID_ID) { 1071 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 1071 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 1072 1072 PJSIP_SC_BUSY_HERE, NULL, 1073 1073 NULL, NULL); 1074 PJ_LOG(2,(THIS_FILE, 1074 PJ_LOG(2,(THIS_FILE, 1075 1075 "Unable to accept incoming call (too many calls)")); 1076 1076 goto on_return; … … 1098 1098 1099 1099 pjsip_get_response_addr(response->pool, rdata, &res_addr); 1100 pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 1100 pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 1101 1101 NULL, NULL); 1102 1102 … … 1152 1152 st_text = *pjsip_get_status_text(st_code); 1153 1153 1154 pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 1154 pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 1155 1155 st_code, &st_text, NULL, NULL, NULL); 1156 1156 goto on_return; … … 1158 1158 } 1159 1159 1160 /* 1160 /* 1161 1161 * Get which account is most likely to be associated with this incoming 1162 1162 * call. We need the account to find which contact URI to put for … … 1190 1190 pjsip_warning_hdr *w; 1191 1191 1192 pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE", 1192 pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE", 1193 1193 status); 1194 1194 1195 w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool, 1195 w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool, 1196 1196 pjsip_endpt_name(pjsua_var.endpt), 1197 1197 status); … … 1199 1199 pj_list_push_back(&hdr_list, w); 1200 1200 1201 pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, 1201 pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, 1202 1202 &reason, &hdr_list, NULL, NULL); 1203 1203 goto on_return; 1204 1204 } 1205 1205 1206 /* Do quick checks on SDP before passing it to transports. More elabore 1206 /* Do quick checks on SDP before passing it to transports. More elabore 1207 1207 * checks will be done in pjsip_inv_verify_request2() below. 1208 1208 */ 1209 1209 if (offer->media_count==0) { 1210 1210 const pj_str_t reason = pj_str("Missing media in SDP"); 1211 pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason, 1211 pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason, 1212 1212 NULL, NULL, NULL); 1213 1213 goto on_return; … … 1241 1241 1242 1242 pjsip_get_response_addr(response->pool, rdata, &res_addr); 1243 pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 1243 pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 1244 1244 NULL, NULL); 1245 1245 … … 1251 1251 1252 1252 goto on_return; 1253 } 1253 } 1254 1254 1255 1255 /* Get suitable Contact header */ … … 1260 1260 acc_id, rdata); 1261 1261 if (status != PJ_SUCCESS) { 1262 pjsua_perror(THIS_FILE, "Unable to generate Contact header", 1262 pjsua_perror(THIS_FILE, "Unable to generate Contact header", 1263 1263 status); 1264 1264 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, … … 1286 1286 /* Set credentials */ 1287 1287 if (pjsua_var.acc[acc_id].cred_cnt) { 1288 pjsip_auth_clt_set_credentials(&dlg->auth_sess, 1288 pjsip_auth_clt_set_credentials(&dlg->auth_sess, 1289 1289 pjsua_var.acc[acc_id].cred_cnt, 1290 1290 pjsua_var.acc[acc_id].cred); … … 1292 1292 1293 1293 /* Set preference */ 1294 pjsip_auth_clt_set_prefs(&dlg->auth_sess, 1294 pjsip_auth_clt_set_prefs(&dlg->auth_sess, 1295 1295 &pjsua_var.acc[acc_id].cfg.auth_pref); 1296 1296 … … 1298 1298 * did not require it. 1299 1299 */ 1300 if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_INACTIVE && 1300 if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_INACTIVE && 1301 1301 (options & PJSIP_INV_REQUIRE_TIMER) == 0) 1302 1302 { … … 1323 1323 pjsip_warning_hdr *w; 1324 1324 1325 w = pjsip_warning_hdr_create_from_status(dlg->pool, 1325 w = pjsip_warning_hdr_create_from_status(dlg->pool, 1326 1326 pjsip_endpt_name(pjsua_var.endpt), 1327 1327 status); … … 1361 1361 */ 1362 1362 if (offer || replaced_dlg) { 1363 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 1364 call->secure_level, 1363 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 1364 call->secure_level, 1365 1365 rdata->tp_info.pool, 1366 1366 offer, … … 1377 1377 */ 1378 1378 pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL); 1379 pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 1379 pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 1380 1380 call->inv = NULL; 1381 1381 call->async_call.dlg = NULL; … … 1385 1385 pjsua_perror(THIS_FILE, "Error initializing media channel", status); 1386 1386 pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL); 1387 pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 1388 call->inv = NULL; 1387 pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 1388 call->inv = NULL; 1389 1389 call->async_call.dlg = NULL; 1390 1390 goto on_return; … … 1393 1393 1394 1394 /* Create answer */ 1395 /* 1396 status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, 1395 /* 1396 status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, 1397 1397 offer, &answer, &sip_err_code); 1398 1398 if (status != PJ_SUCCESS) { … … 1405 1405 1406 1406 /* Init Session Timers */ 1407 status = pjsip_timer_init_session(inv, 1407 status = pjsip_timer_init_session(inv, 1408 1408 &pjsua_var.acc[acc_id].cfg.timer_setting); 1409 1409 if (status != PJ_SUCCESS) { … … 1420 1420 1421 1421 /* Update NAT type of remote endpoint, only when there is SDP in 1422 * incoming INVITE! 1422 * incoming INVITE! 1423 1423 */ 1424 1424 if (pjsua_var.ua_cfg.nat_type_in_sdp && inv->neg && 1425 pjmedia_sdp_neg_get_state(inv->neg) > PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 1425 pjmedia_sdp_neg_get_state(inv->neg) > PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 1426 1426 { 1427 1427 const pjmedia_sdp_session *remote_sdp; … … 1489 1489 } 1490 1490 } else { 1491 /* Notify application if on_incoming_call() is overriden, 1491 /* Notify application if on_incoming_call() is overriden, 1492 1492 * otherwise hangup the call with 480 1493 1493 */ … … 1495 1495 pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata); 1496 1496 } else { 1497 pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE, 1497 pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE, 1498 1498 NULL, NULL); 1499 1499 } … … 1551 1551 break; 1552 1552 } 1553 1553 1554 1554 has_pjsua_lock = PJ_FALSE; 1555 1555 … … 1596 1596 return PJ_ETIMEDOUT; 1597 1597 } 1598 1598 1599 1599 *p_call = call; 1600 1600 *p_dlg = dlg; … … 1701 1701 sizeof(info->buf_.last_status_text)); 1702 1702 } 1703 1703 1704 1704 /* Audio & video count offered by remote */ 1705 1705 info->rem_offerer = call->rem_offerer; … … 1727 1727 pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV; 1728 1728 1729 info->media[info->media_cnt].stream.vid.win_in = 1729 info->media[info->media_cnt].stream.vid.win_in = 1730 1730 call_med->strm.v.rdr_win_id; 1731 1731 … … 1763 1763 pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV; 1764 1764 1765 info->prov_media[info->prov_media_cnt].stream.vid.win_in = 1765 info->prov_media[info->prov_media_cnt].stream.vid.win_in = 1766 1766 call_med->strm.v.rdr_win_id; 1767 1767 … … 1874 1874 * Get media transport info for the specified media index. 1875 1875 */ 1876 PJ_DEF(pj_status_t) 1876 PJ_DEF(pj_status_t) 1877 1877 pjsua_call_get_med_transport_info(pjsua_call_id call_id, 1878 1878 unsigned med_idx, … … 1890 1890 1891 1891 call = &pjsua_var.calls[call_id]; 1892 1892 1893 1893 if (med_idx >= call->med_cnt) { 1894 1894 PJSUA_UNLOCK(); … … 1900 1900 pjmedia_transport_info_init(t); 1901 1901 status = pjmedia_transport_get_info(call_med->tp, t); 1902 1902 1903 1903 PJSUA_UNLOCK(); 1904 1904 return status; … … 1932 1932 1933 1933 status = pjsua_media_channel_create_sdp(call_id, 1934 call->async_call.dlg->pool, 1934 call->async_call.dlg->pool, 1935 1935 NULL, &sdp, &sip_err_code); 1936 1936 if (status != PJ_SUCCESS) { … … 1984 1984 * Send response to incoming INVITE request. 1985 1985 */ 1986 PJ_DEF(pj_status_t) pjsua_call_answer( pjsua_call_id call_id, 1986 PJ_DEF(pj_status_t) pjsua_call_answer( pjsua_call_id call_id, 1987 1987 unsigned code, 1988 1988 const pj_str_t *reason, … … 2042 2042 * answer code 183 or 2xx is issued 2043 2043 */ 2044 if (!call->med_ch_cb && 2044 if (!call->med_ch_cb && 2045 2045 (call->opt_inited || (code==183 || code/100==2)) && 2046 2046 (!call->inv->neg || 2047 pjmedia_sdp_neg_get_state(call->inv->neg) == 2047 pjmedia_sdp_neg_get_state(call->inv->neg) == 2048 2048 PJMEDIA_SDP_NEG_STATE_NULL)) 2049 2049 { … … 2076 2076 if (call->med_ch_cb) { 2077 2077 struct call_answer *answer; 2078 2078 2079 2079 PJ_LOG(4,(THIS_FILE, "Pending answering call %d upon completion " 2080 2080 "of media transport", call_id)); … … 2114 2114 status = pjsip_inv_answer(call->inv, code, reason, NULL, &tdata); 2115 2115 if (status != PJ_SUCCESS) { 2116 pjsua_perror(THIS_FILE, "Error creating response", 2116 pjsua_perror(THIS_FILE, "Error creating response", 2117 2117 status); 2118 2118 goto on_return; … … 2131 2131 status = pjsip_inv_send_msg(call->inv, tdata); 2132 2132 if (status != PJ_SUCCESS) 2133 pjsua_perror(THIS_FILE, "Error sending response", 2133 pjsua_perror(THIS_FILE, "Error sending response", 2134 2134 status); 2135 2135 … … 2160 2160 call_id)); 2161 2161 } 2162 2162 2163 2163 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 2164 2164 PJ_EINVAL); … … 2186 2186 sizeof(call->last_text_buf_)); 2187 2187 } 2188 2188 2189 2189 goto on_return; 2190 2190 } … … 2201 2201 status = pjsip_inv_end_session(call->inv, code, reason, &tdata); 2202 2202 if (status != PJ_SUCCESS) { 2203 pjsua_perror(THIS_FILE, 2204 "Failed to create end session message", 2203 pjsua_perror(THIS_FILE, 2204 "Failed to create end session message", 2205 2205 status); 2206 2206 goto on_return; 2207 2207 } 2208 2208 2209 /* pjsip_inv_end_session may return PJ_SUCCESS with NULL 2209 /* pjsip_inv_end_session may return PJ_SUCCESS with NULL 2210 2210 * as p_tdata when INVITE transaction has not been answered 2211 2211 * with any provisional responses. … … 2220 2220 status = pjsip_inv_send_msg(call->inv, tdata); 2221 2221 if (status != PJ_SUCCESS) { 2222 pjsua_perror(THIS_FILE, 2223 "Failed to send end session message", 2222 pjsua_perror(THIS_FILE, 2223 "Failed to send end session message", 2224 2224 status); 2225 2225 goto on_return; … … 2252 2252 PJ_EINVAL); 2253 2253 2254 status = acquire_call("pjsua_call_process_redirect()", call_id, 2254 status = acquire_call("pjsua_call_process_redirect()", call_id, 2255 2255 &call, &dlg); 2256 2256 if (status != PJ_SUCCESS) … … 2398 2398 goto on_return; 2399 2399 } 2400 2401 status = apply_call_setting(call, opt, NULL);2402 if (status != PJ_SUCCESS) {2403 pjsua_perror(THIS_FILE, "Failed to apply call setting", status);2404 goto on_return;2405 }2406 2407 /* Create SDP */2408 if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {2409 status = create_sdp_of_call_hold(call, &sdp);2410 } else {2411 status = pjsua_media_channel_create_sdp(call->index,2412 call->inv->pool_prov,2413 NULL, &sdp, NULL);2414 call->local_hold = PJ_FALSE;2415 }2416 if (status != PJ_SUCCESS) {2417 pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",2418 status);2419 goto on_return;2420 }2421 2422 if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&2423 pjsua_acc_is_valid(call->acc_id))2424 {2425 new_contact = &pjsua_var.acc[call->acc_id].contact;2426 }2427 2428 /* Create re-INVITE with new offer */2429 status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);2430 if (status != PJ_SUCCESS) {2431 pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);2432 goto on_return;2433 }2434 2435 /* Add additional headers etc */2436 pjsua_process_msg_data( tdata, msg_data);2437 2438 /* Send the request */2439 status = pjsip_inv_send_msg( call->inv, tdata);2440 if (status != PJ_SUCCESS) {2441 pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);2442 goto on_return;2443 }2444 2445 on_return:2446 if (dlg) pjsip_dlg_dec_lock(dlg);2447 pj_log_pop_indent();2448 return status;2449 }2450 2451 2452 /*2453 * Send UPDATE request.2454 */2455 PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id,2456 unsigned options,2457 const pjsua_msg_data *msg_data)2458 {2459 pjsua_call *call;2460 pjsip_dialog *dlg = NULL;2461 pj_status_t status;2462 2463 status = acquire_call("pjsua_call_update()", call_id, &call, &dlg);2464 if (status != PJ_SUCCESS)2465 goto on_return;2466 2467 if (options != call->opt.flag)2468 call->opt.flag = options;2469 2470 status = pjsua_call_update2(call_id, NULL, msg_data);2471 2472 on_return:2473 if (dlg) pjsip_dlg_dec_lock(dlg);2474 return status;2475 }2476 2477 2478 /*2479 * Send UPDATE request.2480 */2481 PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id,2482 const pjsua_call_setting *opt,2483 const pjsua_msg_data *msg_data)2484 {2485 pjmedia_sdp_session *sdp;2486 pj_str_t *new_contact = NULL;2487 pjsip_tx_data *tdata;2488 pjsua_call *call;2489 pjsip_dialog *dlg = NULL;2490 pj_status_t status;2491 2492 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,2493 PJ_EINVAL);2494 2495 PJ_LOG(4,(THIS_FILE, "Sending UPDATE on call %d", call_id));2496 pj_log_push_indent();2497 2498 status = acquire_call("pjsua_call_update2()", call_id, &call, &dlg);2499 if (status != PJ_SUCCESS)2500 goto on_return;2501 2400 2502 2401 status = apply_call_setting(call, opt, NULL); … … 2515 2414 call->local_hold = PJ_FALSE; 2516 2415 } 2517 2518 2416 if (status != PJ_SUCCESS) { 2519 2417 pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", … … 2528 2426 } 2529 2427 2530 /* Create UPDATE with new offer */2531 status = pjsip_inv_ update(call->inv, new_contact, sdp, &tdata);2532 if (status != PJ_SUCCESS) { 2533 pjsua_perror(THIS_FILE, "Unable to create UPDATE request", status);2428 /* Create re-INVITE with new offer */ 2429 status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata); 2430 if (status != PJ_SUCCESS) { 2431 pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); 2534 2432 goto on_return; 2535 2433 } … … 2541 2439 status = pjsip_inv_send_msg( call->inv, tdata); 2542 2440 if (status != PJ_SUCCESS) { 2543 pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status);2441 pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); 2544 2442 goto on_return; 2545 2443 } … … 2553 2451 2554 2452 /* 2453 * Send UPDATE request. 2454 */ 2455 PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id, 2456 unsigned options, 2457 const pjsua_msg_data *msg_data) 2458 { 2459 pjsua_call *call; 2460 pjsip_dialog *dlg = NULL; 2461 pj_status_t status; 2462 2463 status = acquire_call("pjsua_call_update()", call_id, &call, &dlg); 2464 if (status != PJ_SUCCESS) 2465 goto on_return; 2466 2467 if (options != call->opt.flag) 2468 call->opt.flag = options; 2469 2470 status = pjsua_call_update2(call_id, NULL, msg_data); 2471 2472 on_return: 2473 if (dlg) pjsip_dlg_dec_lock(dlg); 2474 return status; 2475 } 2476 2477 2478 /* 2479 * Send UPDATE request. 2480 */ 2481 PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id, 2482 const pjsua_call_setting *opt, 2483 const pjsua_msg_data *msg_data) 2484 { 2485 pjmedia_sdp_session *sdp; 2486 pj_str_t *new_contact = NULL; 2487 pjsip_tx_data *tdata; 2488 pjsua_call *call; 2489 pjsip_dialog *dlg = NULL; 2490 pj_status_t status; 2491 2492 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 2493 PJ_EINVAL); 2494 2495 PJ_LOG(4,(THIS_FILE, "Sending UPDATE on call %d", call_id)); 2496 pj_log_push_indent(); 2497 2498 status = acquire_call("pjsua_call_update2()", call_id, &call, &dlg); 2499 if (status != PJ_SUCCESS) 2500 goto on_return; 2501 2502 status = apply_call_setting(call, opt, NULL); 2503 if (status != PJ_SUCCESS) { 2504 pjsua_perror(THIS_FILE, "Failed to apply call setting", status); 2505 goto on_return; 2506 } 2507 2508 /* Create SDP */ 2509 if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) { 2510 status = create_sdp_of_call_hold(call, &sdp); 2511 } else { 2512 status = pjsua_media_channel_create_sdp(call->index, 2513 call->inv->pool_prov, 2514 NULL, &sdp, NULL); 2515 call->local_hold = PJ_FALSE; 2516 } 2517 2518 if (status != PJ_SUCCESS) { 2519 pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", 2520 status); 2521 goto on_return; 2522 } 2523 2524 if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) && 2525 pjsua_acc_is_valid(call->acc_id)) 2526 { 2527 new_contact = &pjsua_var.acc[call->acc_id].contact; 2528 } 2529 2530 /* Create UPDATE with new offer */ 2531 status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata); 2532 if (status != PJ_SUCCESS) { 2533 pjsua_perror(THIS_FILE, "Unable to create UPDATE request", status); 2534 goto on_return; 2535 } 2536 2537 /* Add additional headers etc */ 2538 pjsua_process_msg_data( tdata, msg_data); 2539 2540 /* Send the request */ 2541 status = pjsip_inv_send_msg( call->inv, tdata); 2542 if (status != PJ_SUCCESS) { 2543 pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status); 2544 goto on_return; 2545 } 2546 2547 on_return: 2548 if (dlg) pjsip_dlg_dec_lock(dlg); 2549 pj_log_pop_indent(); 2550 return status; 2551 } 2552 2553 2554 /* 2555 2555 * Initiate call transfer to the specified address. 2556 2556 */ 2557 PJ_DEF(pj_status_t) pjsua_call_xfer( pjsua_call_id call_id, 2557 PJ_DEF(pj_status_t) pjsua_call_xfer( pjsua_call_id call_id, 2558 2558 const pj_str_t *dest, 2559 2559 const pjsua_msg_data *msg_data) … … 2571 2571 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls && 2572 2572 dest, PJ_EINVAL); 2573 2573 2574 2574 PJ_LOG(4,(THIS_FILE, "Transferring call %d to %.*s", call_id, 2575 2575 (int)dest->slen, dest->ptr)); … … 2579 2579 if (status != PJ_SUCCESS) 2580 2580 goto on_return; 2581 2581 2582 2582 /* Create xfer client subscription. */ 2583 2583 pj_bzero(&xfer_cb, sizeof(xfer_cb)); … … 2618 2618 } 2619 2619 2620 /* For simplicity (that's what this program is intended to be!), 2620 /* For simplicity (that's what this program is intended to be!), 2621 2621 * leave the original invite session as it is. More advanced application 2622 2622 * may want to hold the INVITE, or terminate the invite, or whatever. … … 2633 2633 * Initiate attended call transfer to the specified address. 2634 2634 */ 2635 PJ_DEF(pj_status_t) pjsua_call_xfer_replaces( pjsua_call_id call_id, 2635 PJ_DEF(pj_status_t) pjsua_call_xfer_replaces( pjsua_call_id call_id, 2636 2636 pjsua_call_id dest_call_id, 2637 2637 unsigned options, … … 2645 2645 pjsip_uri *uri; 2646 2646 pj_status_t status; 2647 2647 2648 2648 2649 2649 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 2650 2650 PJ_EINVAL); 2651 PJ_ASSERT_RETURN(dest_call_id>=0 && 2651 PJ_ASSERT_RETURN(dest_call_id>=0 && 2652 2652 dest_call_id<(int)pjsua_var.ua_cfg.max_calls, 2653 2653 PJ_EINVAL); 2654 2654 2655 2655 PJ_LOG(4,(THIS_FILE, "Transferring call %d replacing with call %d", 2656 2656 call_id, dest_call_id)); 2657 2657 pj_log_push_indent(); 2658 2658 2659 status = acquire_call("pjsua_call_xfer_replaces()", dest_call_id, 2659 status = acquire_call("pjsua_call_xfer_replaces()", dest_call_id, 2660 2660 &dest_call, &dest_dlg); 2661 2661 if (status != PJ_SUCCESS) { … … 2663 2663 return status; 2664 2664 } 2665 2666 /* 2665 2666 /* 2667 2667 * Create REFER destination URI with Replaces field. 2668 2668 */ … … 2672 2672 dest_dlg->call_id->id.slen + 2673 2673 dest_dlg->remote.info->tag.slen + 2674 dest_dlg->local.info->tag.slen + 32 2674 dest_dlg->local.info->tag.slen + 32 2675 2675 < (long)sizeof(str_dest_buf), 2676 2676 { status=PJSIP_EURITOOLONG; goto on_error; }); … … 2681 2681 2682 2682 uri = (pjsip_uri*) pjsip_uri_get_uri(dest_dlg->remote.info->uri); 2683 len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, 2683 len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, 2684 2684 str_dest_buf+1, sizeof(str_dest_buf)-1); 2685 2685 if (len < 0) { … … 2692 2692 2693 2693 /* Build the URI */ 2694 len = pj_ansi_snprintf(str_dest_buf + str_dest.slen, 2694 len = pj_ansi_snprintf(str_dest_buf + str_dest.slen, 2695 2695 sizeof(str_dest_buf) - str_dest.slen, 2696 2696 "?%s" … … 2709 2709 PJ_ASSERT_ON_FAIL(len > 0 && len <= (int)sizeof(str_dest_buf)-str_dest.slen, 2710 2710 { status=PJSIP_EURITOOLONG; goto on_error; }); 2711 2711 2712 2712 str_dest.ptr = str_dest_buf; 2713 2713 str_dest.slen += len; 2714 2714 2715 2715 pjsip_dlg_dec_lock(dest_dlg); 2716 2716 2717 2717 status = pjsua_call_xfer(call_id, &str_dest, msg_data); 2718 2718 … … 2730 2730 * Send instant messaging inside INVITE session. 2731 2731 */ 2732 PJ_DEF(pj_status_t) pjsua_call_send_im( pjsua_call_id call_id, 2732 PJ_DEF(pj_status_t) pjsua_call_send_im( pjsua_call_id call_id, 2733 2733 const pj_str_t *mime_type, 2734 2734 const pj_str_t *content, … … 2754 2754 if (status != PJ_SUCCESS) 2755 2755 goto on_return; 2756 2756 2757 2757 /* Set default media type if none is specified */ 2758 2758 if (mime_type == NULL) { … … 2769 2769 2770 2770 /* Add accept header. */ 2771 pjsip_msg_add_hdr( tdata->msg, 2771 pjsip_msg_add_hdr( tdata->msg, 2772 2772 (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); 2773 2773 … … 2797 2797 2798 2798 /* Send the request. */ 2799 status = pjsip_dlg_send_request( call->inv->dlg, tdata, 2799 status = pjsip_dlg_send_request( call->inv->dlg, tdata, 2800 2800 pjsua_var.mod.id, im_data); 2801 2801 if (status != PJ_SUCCESS) { … … 2814 2814 * Send IM typing indication inside INVITE session. 2815 2815 */ 2816 PJ_DEF(pj_status_t) pjsua_call_send_typing_ind( pjsua_call_id call_id, 2816 PJ_DEF(pj_status_t) pjsua_call_send_typing_ind( pjsua_call_id call_id, 2817 2817 pj_bool_t is_typing, 2818 2818 const pjsua_msg_data*msg_data) … … 3099 3099 pjmedia_transport_info tpinfo; 3100 3100 pjmedia_ice_transport_info *ice_info; 3101 3101 3102 3102 if (call_med->tp_st == PJSUA_MED_TP_NULL || 3103 3103 call_med->tp_st == PJSUA_MED_TP_DISABLED || … … 3106 3106 continue; 3107 3107 } 3108 3108 3109 3109 pjmedia_transport_info_init(&tpinfo); 3110 3110 pjmedia_transport_get_info(call_med->tp, &tpinfo); … … 3122 3122 break; 3123 3123 } 3124 3124 3125 3125 /* Check if ICE needs to send reinvite */ 3126 3126 if (!ice_need_reinv && … … 3137 3137 } 3138 3138 } 3139 3139 3140 3140 if (ice_complete && need_reinv) 3141 3141 *need_reinv = ice_need_reinv; 3142 3142 3143 3143 return ice_complete; 3144 3144 } … … 3177 3177 * remote does not support UPDATE method. 3178 3178 */ 3179 if (inv->state == PJSIP_INV_STATE_EARLY && 3179 if (inv->state == PJSIP_INV_STATE_EARLY && 3180 3180 pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &ST_UPDATE)!= 3181 3181 PJSIP_DIALOG_CAP_SUPPORTED) … … 3197 3197 return PJ_SUCCESS; 3198 3198 3199 3199 3200 3200 /* Okay! So we need to send re-INVITE/UPDATE */ 3201 3201 … … 3218 3218 )); 3219 3219 } 3220 3220 3221 3221 /* Generate SDP re-offer */ 3222 3222 status = pjsua_media_channel_create_sdp(call->index, pool, NULL, … … 3235 3235 if (need_lock_codec) { 3236 3236 const pjmedia_sdp_session *ref_sdp; 3237 3237 3238 3238 /* Get local active SDP as reference */ 3239 3239 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &ref_sdp); 3240 3240 if (status != PJ_SUCCESS) 3241 3241 return status; 3242 3242 3243 3243 /* Verify media count. Note that remote may add/remove media line 3244 3244 * in the answer. When answer has less media, it must have been … … 3262 3262 pjmedia_sdp_media *m = new_offer->media[i]; 3263 3263 pjsua_call_media *call_med = &call->media[i]; 3264 3264 3265 3265 /* Verify if media is deactivated */ 3266 3266 if (call_med->state == PJSUA_CALL_MEDIA_NONE || … … 3270 3270 continue; 3271 3271 } 3272 3272 3273 3273 /* Reset formats */ 3274 3274 m->desc.fmt_count = 0; 3275 3275 pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "rtpmap"); 3276 3276 pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "fmtp"); 3277 3277 3278 3278 /* Copy only the first format + any non-AV formats from 3279 3279 * the active local SDP. … … 3284 3284 if (is_non_av_fmt(ref_m, fmt) || (++codec_cnt == 1)) { 3285 3285 pjmedia_sdp_attr *a; 3286 3286 3287 3287 m->desc.fmt[m->desc.fmt_count++] = *fmt; 3288 3288 a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr, … … 3300 3300 { 3301 3301 const pjmedia_sdp_session *cur_sdp; 3302 3302 3303 3303 /* Get local active SDP */ 3304 3304 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &cur_sdp); … … 3356 3356 } 3357 3357 3358 3358 3359 3359 if (rem_can_update) { 3360 3360 status = pjsip_inv_update(inv, NULL, new_offer, &tdata); … … 3388 3388 if (need_lock_codec) 3389 3389 ++call->lock_codec.retry_cnt; 3390 3390 3391 3391 return PJ_SUCCESS; 3392 3392 } … … 3397 3397 * session state has changed. 3398 3398 */ 3399 static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 3399 static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 3400 3400 pjsip_event *e) 3401 3401 { … … 3418 3418 if (call->res_time.sec == 0) 3419 3419 pj_gettimeofday(&call->res_time); 3420 call->last_code = (pjsip_status_code) 3420 call->last_code = (pjsip_status_code) 3421 3421 e->body.tsx_state.tsx->status_code; 3422 pj_strncpy(&call->last_text, 3422 pj_strncpy(&call->last_text, 3423 3423 &e->body.tsx_state.tsx->status_text, 3424 3424 sizeof(call->last_text_buf_)); … … 3439 3439 if (call->res_time.sec == 0) 3440 3440 pj_gettimeofday(&call->res_time); 3441 if (e->type == PJSIP_EVENT_TSX_STATE && 3442 e->body.tsx_state.tsx->status_code > call->last_code) 3441 if (e->type == PJSIP_EVENT_TSX_STATE && 3442 e->body.tsx_state.tsx->status_code > call->last_code) 3443 3443 { 3444 call->last_code = (pjsip_status_code) 3444 call->last_code = (pjsip_status_code) 3445 3445 e->body.tsx_state.tsx->status_code; 3446 pj_strncpy(&call->last_text, 3446 pj_strncpy(&call->last_text, 3447 3447 &e->body.tsx_state.tsx->status_text, 3448 3448 sizeof(call->last_text_buf_)); … … 3461 3461 break; 3462 3462 default: 3463 call->last_code = (pjsip_status_code) 3463 call->last_code = (pjsip_status_code) 3464 3464 e->body.tsx_state.tsx->status_code; 3465 pj_strncpy(&call->last_text, 3465 pj_strncpy(&call->last_text, 3466 3466 &e->body.tsx_state.tsx->status_text, 3467 3467 sizeof(call->last_text_buf_)); … … 3475 3475 int st_code = -1; 3476 3476 pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE; 3477 3477 3478 3478 3479 3479 switch (call->inv->state) { … … 3554 3554 3555 3555 PJSUA_LOCK(); 3556 3556 3557 3557 pjsua_media_channel_deinit(call->index); 3558 3558 … … 3577 3577 * has forked. 3578 3578 */ 3579 static void pjsua_call_on_forked( pjsip_inv_session *inv, 3579 static void pjsua_call_on_forked( pjsip_inv_session *inv, 3580 3580 pjsip_event *e) 3581 3581 { … … 3592 3592 pjsip_dialog* on_dlg_forked(pjsip_dialog *dlg, pjsip_rx_data *res) 3593 3593 { 3594 if (dlg->uac_has_2xx && 3594 if (dlg->uac_has_2xx && 3595 3595 res->msg_info.cseq->method.id == PJSIP_INVITE_METHOD && 3596 3596 pjsip_rdata_get_tsx(res) == NULL && 3597 res->msg_info.msg->line.status.code/100 == 2) 3597 res->msg_info.msg->line.status.code/100 == 2) 3598 3598 { 3599 3599 pjsip_dialog *forked_dlg; … … 3631 3631 * Disconnect call upon error. 3632 3632 */ 3633 static void call_disconnect( pjsip_inv_session *inv, 3633 static void call_disconnect( pjsip_inv_session *inv, 3634 3634 int code ) 3635 3635 { 3636 pjsua_call *call;3637 3636 pjsip_tx_data *tdata; 3638 3637 pj_status_t status; 3639 3640 call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];3641 3638 3642 3639 status = pjsip_inv_end_session(inv, code, NULL, &tdata); … … 3644 3641 return; 3645 3642 3643 #if DISABLED_FOR_TICKET_1185 3644 pjsua_call *call; 3645 3646 3646 /* Add SDP in 488 status */ 3647 #if DISABLED_FOR_TICKET_1185 3647 call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; 3648 3648 3649 if (call && call->tp && tdata->msg->type==PJSIP_RESPONSE_MSG && 3649 code==PJSIP_SC_NOT_ACCEPTABLE_HERE) 3650 code==PJSIP_SC_NOT_ACCEPTABLE_HERE) 3650 3651 { 3651 3652 pjmedia_sdp_session *local_sdp; … … 3654 3655 pjmedia_transport_info_init(&ti); 3655 3656 pjmedia_transport_get_info(call->med_tp, &ti); 3656 status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool, 3657 status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool, 3657 3658 1, &ti.sock_info, &local_sdp); 3658 3659 if (status == PJ_SUCCESS) { … … 3699 3700 3700 3701 /* Disconnect call if we're not in the middle of initializing an 3701 * UAS dialog and if this is not a re-INVITE 3702 * UAS dialog and if this is not a re-INVITE 3702 3703 */ 3703 3704 if (inv->state != PJSIP_INV_STATE_NULL && 3704 inv->state != PJSIP_INV_STATE_CONFIRMED) 3705 inv->state != PJSIP_INV_STATE_CONFIRMED) 3705 3706 { 3706 3707 call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); … … 3714 3715 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp); 3715 3716 if (status != PJ_SUCCESS) { 3716 pjsua_perror(THIS_FILE, 3717 "Unable to retrieve currently active local SDP", 3717 pjsua_perror(THIS_FILE, 3718 "Unable to retrieve currently active local SDP", 3718 3719 status); 3719 3720 //call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); … … 3723 3724 status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp); 3724 3725 if (status != PJ_SUCCESS) { 3725 pjsua_perror(THIS_FILE, 3726 "Unable to retrieve currently active remote SDP", 3726 pjsua_perror(THIS_FILE, 3727 "Unable to retrieve currently active remote SDP", 3727 3728 status); 3728 3729 //call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); … … 3738 3739 status = pjsua_media_channel_update(call->index, local_sdp, remote_sdp); 3739 3740 if (status != PJ_SUCCESS) { 3740 pjsua_perror(THIS_FILE, "Unable to create media session", 3741 pjsua_perror(THIS_FILE, "Unable to create media session", 3741 3742 status); 3742 3743 call_disconnect(inv, PJSIP_SC_NOT_ACCEPTABLE_HERE); … … 3768 3769 unsigned mi; 3769 3770 3770 /* Call-hold is done by set the media direction to 'sendonly' 3771 * (PJMEDIA_DIR_ENCODING), except when current media direction is 3771 /* Call-hold is done by set the media direction to 'sendonly' 3772 * (PJMEDIA_DIR_ENCODING), except when current media direction is 3772 3773 * 'inactive' (PJMEDIA_DIR_NONE). 3773 3774 * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1) 3774 3775 */ 3775 /* http://trac.pjsip.org/repos/ticket/880 3776 /* http://trac.pjsip.org/repos/ticket/880 3776 3777 if (call->dir != PJMEDIA_DIR_ENCODING) { 3777 3778 */ … … 3883 3884 pjsip_status_code code = PJSIP_SC_OK; 3884 3885 pjsua_call_setting opt = call->opt; 3885 3886 3886 3887 (*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL, 3887 3888 &code, &opt); … … 3895 3896 call->opt = opt; 3896 3897 } 3897 3898 3898 3899 /* Re-init media for the new remote offer before creating SDP */ 3899 3900 status = apply_call_setting(call, &call->opt, offer); … … 3901 3902 goto on_return; 3902 3903 3903 status = pjsua_media_channel_create_sdp(call->index, 3904 call->inv->pool_prov, 3904 status = pjsua_media_channel_create_sdp(call->index, 3905 call->inv->pool_prov, 3905 3906 offer, &answer, NULL); 3906 3907 if (status != PJ_SUCCESS) { … … 3972 3973 /* See if we've put call on hold. */ 3973 3974 if (call->local_hold) { 3974 PJ_LOG(4,(THIS_FILE, 3975 PJ_LOG(4,(THIS_FILE, 3975 3976 "Call %d: call is on-hold locally, creating call-hold SDP ", 3976 3977 call->index)); … … 3980 3981 call->index)); 3981 3982 3982 status = pjsua_media_channel_create_sdp(call->index, 3983 call->inv->pool_prov, 3983 status = pjsua_media_channel_create_sdp(call->index, 3984 call->inv->pool_prov, 3984 3985 NULL, offer, NULL); 3985 3986 } … … 4001 4002 static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event) 4002 4003 { 4003 4004 4004 4005 PJ_UNUSED_ARG(event); 4005 4006 … … 4007 4008 4008 4009 /* 4009 * When subscription is accepted (got 200/OK to REFER), check if 4010 * When subscription is accepted (got 200/OK to REFER), check if 4010 4011 * subscription suppressed. 4011 4012 */ … … 4020 4021 4021 4022 /* Must be receipt of response message */ 4022 pj_assert(event->type == PJSIP_EVENT_TSX_STATE && 4023 pj_assert(event->type == PJSIP_EVENT_TSX_STATE && 4023 4024 event->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 4024 4025 rdata = event->body.tsx_state.src.rdata; … … 4026 4027 /* Find Refer-Sub header */ 4027 4028 refer_sub = (pjsip_generic_string_hdr*) 4028 pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, 4029 pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, 4029 4030 &REFER_SUB, NULL); 4030 4031 … … 4037 4038 const pj_str_t ACCEPTED = { "Accepted", 8 }; 4038 4039 pj_bool_t cont = PJ_FALSE; 4039 (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 4040 (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 4040 4041 200, 4041 4042 &ACCEPTED, … … 4052 4053 4053 4054 } else { 4054 /* Notify application about call transfer progress. 4055 /* Notify application about call transfer progress. 4055 4056 * Initially notify with 100/Accepted status. 4056 4057 */ … … 4058 4059 const pj_str_t ACCEPTED = { "Accepted", 8 }; 4059 4060 pj_bool_t cont = PJ_FALSE; 4060 (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 4061 (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 4061 4062 100, 4062 4063 &ACCEPTED, … … 4070 4071 */ 4071 4072 else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE || 4072 pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) 4073 pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) 4073 4074 { 4074 4075 pjsua_call *call; … … 4082 4083 call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 4083 4084 4084 /* When subscription is terminated, clear the xfer_sub member of 4085 /* When subscription is terminated, clear the xfer_sub member of 4085 4086 * the inv_data. 4086 4087 */ … … 4108 4109 body = msg->body; 4109 4110 if (!body) { 4110 PJ_LOG(2,(THIS_FILE, 4111 PJ_LOG(2,(THIS_FILE, 4111 4112 "Warning: received NOTIFY without message body")); 4112 4113 goto on_return; … … 4117 4118 pj_stricmp2(&body->content_type.subtype, "sipfrag") != 0) 4118 4119 { 4119 PJ_LOG(2,(THIS_FILE, 4120 PJ_LOG(2,(THIS_FILE, 4120 4121 "Warning: received NOTIFY with non message/sipfrag " 4121 4122 "content")); … … 4124 4125 4125 4126 /* Try to parse the content */ 4126 status = pjsip_parse_status_line((char*)body->data, body->len, 4127 status = pjsip_parse_status_line((char*)body->data, body->len, 4127 4128 &status_line); 4128 4129 if (status != PJ_SUCCESS) { 4129 PJ_LOG(2,(THIS_FILE, 4130 PJ_LOG(2,(THIS_FILE, 4130 4131 "Warning: received NOTIFY with invalid " 4131 4132 "message/sipfrag content")); … … 4141 4142 is_last = (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED); 4142 4143 cont = !is_last; 4143 (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 4144 (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 4144 4145 status_line.code, 4145 4146 &status_line.reason, … … 4156 4157 pjsip_tx_data *tdata; 4157 4158 4158 status = pjsip_evsub_initiate(sub, &pjsip_subscribe_method, 4159 status = pjsip_evsub_initiate(sub, &pjsip_subscribe_method, 4159 4160 0, &tdata); 4160 4161 if (status == PJ_SUCCESS) … … 4179 4180 4180 4181 /* 4181 * When subscription is terminated, clear the xfer_sub member of 4182 * When subscription is terminated, clear the xfer_sub member of 4182 4183 * the inv_data. 4183 4184 */ … … 4254 4255 */ 4255 4256 ref_by_hdr = (pjsip_hdr*) 4256 pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by, 4257 pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by, 4257 4258 NULL); 4258 4259 … … 4261 4262 if (pjsua_var.ua_cfg.cb.on_call_transfer_request) { 4262 4263 (*pjsua_var.ua_cfg.cb.on_call_transfer_request)(existing_call->index, 4263 &refer_to->hvalue, 4264 &refer_to->hvalue, 4264 4265 &code); 4265 4266 } … … 4268 4269 if (pjsua_var.ua_cfg.cb.on_call_transfer_request2) { 4269 4270 (*pjsua_var.ua_cfg.cb.on_call_transfer_request2)(existing_call->index, 4270 &refer_to->hvalue, 4271 &refer_to->hvalue, 4271 4272 &code, 4272 4273 &call_opt); … … 4284 4285 (int)inv->dlg->remote.info_str.slen, 4285 4286 inv->dlg->remote.info_str.ptr, 4286 (int)refer_to->hvalue.slen, 4287 (int)refer_to->hvalue.slen, 4287 4288 refer_to->hvalue.ptr)); 4288 4289 … … 4295 4296 pjsip_hdr *hdr; 4296 4297 4297 status = pjsip_dlg_create_response(inv->dlg, rdata, code, NULL, 4298 status = pjsip_dlg_create_response(inv->dlg, rdata, code, NULL, 4298 4299 &tdata); 4299 4300 if (status != PJ_SUCCESS) { … … 4304 4305 4305 4306 /* Add Refer-Sub header */ 4306 hdr = (pjsip_hdr*) 4307 hdr = (pjsip_hdr*) 4307 4308 pjsip_generic_string_hdr_create(tdata->pool, &str_refer_sub, 4308 4309 &str_false); … … 4348 4349 pjsip_hdr *hdr; 4349 4350 4350 hdr = (pjsip_hdr*) 4351 pjsip_generic_string_hdr_create(inv->dlg->pool, 4351 hdr = (pjsip_hdr*) 4352 pjsip_generic_string_hdr_create(inv->dlg->pool, 4352 4353 &str_refer_sub, 4353 4354 &str_true); … … 4363 4364 100, NULL, &tdata); 4364 4365 if (status != PJ_SUCCESS) { 4365 pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 4366 pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 4366 4367 status); 4367 4368 goto on_return; … … 4379 4380 * We need to get a null terminated string from a pj_str_t. 4380 4381 * So grab the pointer from the hvalue and NULL terminate it, knowing 4381 * that the NULL position will be occupied by a newline. 4382 * that the NULL position will be occupied by a newline. 4382 4383 */ 4383 4384 uri = refer_to->hvalue.ptr; … … 4399 4400 tmp = pj_str(uri); 4400 4401 status = pjsua_call_make_call(existing_call->acc_id, &tmp, &call_opt, 4401 existing_call->user_data, &msg_data, 4402 existing_call->user_data, &msg_data, 4402 4403 &new_call); 4403 4404 if (status != PJ_SUCCESS) { … … 4408 4409 500, NULL, &tdata); 4409 4410 if (status != PJ_SUCCESS) { 4410 pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 4411 pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 4411 4412 status); 4412 4413 goto on_return; … … 4414 4415 status = pjsip_xfer_send_request(sub, tdata); 4415 4416 if (status != PJ_SUCCESS) { 4416 pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", 4417 pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", 4417 4418 status); 4418 4419 goto on_return; … … 4430 4431 4431 4432 /* Put the invite_data in the subscription. */ 4432 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, 4433 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, 4433 4434 &pjsua_var.calls[new_call]); 4434 4435 } … … 4512 4513 pj_list_push_back(&hdr_list, accept_hdr); 4513 4514 4514 pjsip_dlg_respond( inv->dlg, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE, 4515 pjsip_dlg_respond( inv->dlg, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE, 4515 4516 NULL, &hdr_list, NULL ); 4516 4517 goto on_return; … … 4518 4519 4519 4520 /* Respond with 200 first, so that remote doesn't retransmit in case 4520 * the UI takes too long to process the message. 4521 * the UI takes too long to process the message. 4521 4522 */ 4522 4523 pjsip_dlg_respond( inv->dlg, rdata, 200, NULL, NULL, NULL); … … 4626 4627 4627 4628 if (pjsua_var.ua_cfg.cb.on_call_redirected) { 4628 op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index, 4629 op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index, 4629 4630 target, e); 4630 4631 } else {
Note: See TracChangeset
for help on using the changeset viewer.