Changeset 236 for pjproject/trunk/pjsip/src/pjsua/pjsua_call.c
- Timestamp:
- Feb 26, 2006 9:23:45 PM (18 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua/pjsua_call.c
r226 r236 33 33 * Make outgoing call. 34 34 */ 35 pj_status_t pjsua_invite(const char *cstr_dest_uri, 36 struct pjsua_inv_data **p_inv_data) 35 pj_status_t pjsua_make_call(int acc_index, 36 const char *cstr_dest_uri, 37 int *p_call_index) 37 38 { 38 39 pj_str_t dest_uri; … … 40 41 pjmedia_sdp_session *offer; 41 42 pjsip_inv_session *inv; 42 struct pjsua_inv_data *inv_data;43 int call_index = -1; 43 44 pjsip_tx_data *tdata; 44 int med_sk_index = 0;45 45 pj_status_t status; 46 46 … … 49 49 dest_uri = pj_str((char*)cstr_dest_uri); 50 50 51 /* Find free socket. */52 for ( med_sk_index=0; med_sk_index<PJSUA_MAX_CALLS; ++med_sk_index) {53 if ( !pjsua.med_sock_use[med_sk_index])51 /* Find free call slot. */ 52 for (call_index=0; call_index<pjsua.max_calls; ++call_index) { 53 if (pjsua.calls[call_index].inv == NULL) 54 54 break; 55 55 } 56 56 57 if ( med_sk_index == PJSUA_MAX_CALLS) {57 if (call_index == pjsua.max_calls) { 58 58 PJ_LOG(3,(THIS_FILE, "Error: too many calls!")); 59 59 return PJ_ETOOMANY; 60 60 } 61 61 62 pjsua.med_sock_use[med_sk_index] = 1;63 64 62 /* Create outgoing dialog: */ 65 63 66 status = pjsip_dlg_create_uac( pjsip_ua_instance(), &pjsua.local_uri, 67 &pjsua.contact_uri, &dest_uri, &dest_uri, 64 status = pjsip_dlg_create_uac( pjsip_ua_instance(), 65 &pjsua.acc[acc_index].local_uri, 66 &pjsua.acc[acc_index].contact_uri, 67 &dest_uri, &dest_uri, 68 68 &dlg); 69 69 if (status != PJ_SUCCESS) { … … 74 74 /* Get media capability from media endpoint: */ 75 75 76 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, dlg->pool, 77 1, &pjsua.med_sock_info[med_sk_index],76 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, dlg->pool, 1, 77 &pjsua.calls[call_index].skinfo, 78 78 &offer); 79 79 if (status != PJ_SUCCESS) { … … 93 93 /* Create and associate our data in the session. */ 94 94 95 inv_data = pj_pool_zalloc( dlg->pool, sizeof(struct pjsua_inv_data)); 96 inv_data->inv = inv; 97 inv_data->call_slot = med_sk_index; 98 dlg->mod_data[pjsua.mod.id] = inv_data; 99 inv->mod_data[pjsua.mod.id] = inv_data; 95 pjsua.calls[call_index].inv = inv; 96 97 dlg->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 98 inv->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 100 99 101 100 102 101 /* Set dialog Route-Set: */ 103 102 104 if (!pj_list_empty(&pjsua. route_set))105 pjsip_dlg_set_route_set(dlg, &pjsua. route_set);103 if (!pj_list_empty(&pjsua.acc[acc_index].route_set)) 104 pjsip_dlg_set_route_set(dlg, &pjsua.acc[acc_index].route_set); 106 105 107 106 … … 122 121 123 122 124 /* Add invite session to the list. */125 126 pj_list_push_back(&pjsua.inv_list, inv_data);127 128 129 123 /* Send initial INVITE: */ 130 124 131 125 status = pjsip_inv_send_msg(inv, tdata, NULL); 132 126 if (status != PJ_SUCCESS) { 133 /*134 * Note:135 * inv_data will be removed from the list in the callback136 */137 127 pjsua_perror(THIS_FILE, "Unable to send initial INVITE request", 138 128 status); … … 142 132 143 133 /* Done. */ 144 if (p_inv_data) 145 *p_inv_data = inv_data; 134 135 ++pjsua.call_cnt; 136 137 if (p_call_index) 138 *p_call_index = call_index; 146 139 147 140 return PJ_SUCCESS; … … 149 142 150 143 on_error: 151 152 144 PJ_TODO(DESTROY_DIALOG_ON_FAIL); 153 pjsua.med_sock_use[med_sk_index] = 0; 145 if (call_index != -1) { 146 pjsua.calls[call_index].inv = NULL; 147 } 154 148 return status; 155 149 } … … 159 153 * Handle incoming INVITE request. 160 154 */ 161 pj_bool_t pjsua_ inv_on_incoming(pjsip_rx_data *rdata)155 pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) 162 156 { 163 157 pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata); … … 167 161 unsigned options = 0; 168 162 pjsip_inv_session *inv; 169 struct pjsua_inv_data *inv_data; 163 int acc_index; 164 int call_index = -1; 170 165 pjmedia_sdp_session *answer; 171 int med_sk_index;172 166 pj_status_t status; 173 167 … … 215 209 216 210 /* Find free call slot. */ 217 for ( med_sk_index=0; med_sk_index<PJSUA_MAX_CALLS; ++med_sk_index) {218 if ( !pjsua.med_sock_use[med_sk_index])211 for (call_index=0; call_index < pjsua.max_calls; ++call_index) { 212 if (pjsua.calls[call_index].inv == NULL) 219 213 break; 220 214 } 221 215 222 if ( med_sk_index == PJSUA_MAX_CALLS) {216 if (call_index == PJSUA_MAX_CALLS) { 223 217 pjsip_endpt_respond_stateless(pjsua.endpt, rdata, 224 218 PJSIP_SC_BUSY_HERE, NULL, … … 228 222 229 223 230 pjsua.med_sock_use[med_sk_index] = 1;231 232 224 /* Get media capability from media endpoint: */ 233 225 234 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, rdata->tp_info.pool, 235 1, &pjsua.med_sock_info[med_sk_index],226 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, rdata->tp_info.pool, 1, 227 &pjsua.calls[call_index].skinfo, 236 228 &answer ); 237 229 if (status != PJ_SUCCESS) { … … 239 231 NULL, NULL); 240 232 241 /* Free call socket. */242 pjsua.med_sock_use[med_sk_index] = 0;243 233 return PJ_TRUE; 244 234 } 245 235 236 /* TODO: 237 * 238 * Get which account is most likely to be associated with this incoming 239 * call. We need the account to find which contact URI to put for 240 * the call. 241 */ 242 acc_index = 0; 243 246 244 /* Create dialog: */ 247 245 248 246 status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata, 249 &pjsua.contact_uri, &dlg); 247 &pjsua.acc[acc_index].contact_uri, 248 &dlg); 250 249 if (status != PJ_SUCCESS) { 251 250 pjsip_endpt_respond_stateless(pjsua.endpt, rdata, 500, NULL, 252 251 NULL, NULL); 253 252 254 /* Free call socket. */255 pjsua.med_sock_use[med_sk_index] = 0;256 253 return PJ_TRUE; 257 254 } … … 264 261 265 262 pjsip_dlg_respond(dlg, rdata, 500, NULL); 266 267 /* Free call socket. */268 pjsua.med_sock_use[med_sk_index] = 0;269 263 270 264 // TODO: Need to delete dialog … … 275 269 /* Create and attach pjsua data to the dialog: */ 276 270 277 inv_data = pj_pool_zalloc(dlg->pool, sizeof(struct pjsua_inv_data)); 278 inv_data->inv = inv; 279 inv_data->call_slot = inv_data->call_slot = med_sk_index; 280 dlg->mod_data[pjsua.mod.id] = inv_data; 281 inv->mod_data[pjsua.mod.id] = inv_data; 282 283 pj_list_push_back(&pjsua.inv_list, inv_data); 271 pjsua.calls[call_index].inv = inv; 272 273 dlg->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 274 inv->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 284 275 285 276 … … 296 287 297 288 pjsip_dlg_respond(dlg, rdata, 500, NULL); 298 299 /* Free call socket. */300 pjsua.med_sock_use[med_sk_index] = 0;301 289 302 290 // TODO: Need to delete dialog … … 329 317 } 330 318 319 ++pjsua.call_cnt; 320 331 321 /* This INVITE request has been handled. */ 332 322 return PJ_TRUE; … … 338 328 * session state has changed. 339 329 */ 340 void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) 341 { 342 struct pjsua_inv_data *inv_data; 343 344 inv_data = inv->dlg->mod_data[pjsua.mod.id]; 330 static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 331 pjsip_event *e) 332 { 333 pjsua_call *call = inv->dlg->mod_data[pjsua.mod.id]; 345 334 346 335 /* If this is an outgoing INVITE that was created because of 347 336 * REFER/transfer, send NOTIFY to transferer. 348 337 */ 349 if (inv_data && inv_data->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE) 350 { 338 if (call && call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE) { 351 339 int st_code = -1; 352 340 pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE; 353 341 354 342 355 switch ( inv->state) {343 switch (call->inv->state) { 356 344 case PJSIP_INV_STATE_NULL: 357 345 case PJSIP_INV_STATE_CALLING: … … 383 371 pj_status_t status; 384 372 385 status = pjsip_xfer_notify( inv_data->xfer_sub,373 status = pjsip_xfer_notify( call->xfer_sub, 386 374 ev_state, st_code, 387 375 NULL, &tdata); … … 389 377 pjsua_perror(THIS_FILE, "Unable to create NOTIFY", status); 390 378 } else { 391 status = pjsip_xfer_send_request( inv_data->xfer_sub, tdata);379 status = pjsip_xfer_send_request(call->xfer_sub, tdata); 392 380 if (status != PJ_SUCCESS) { 393 381 pjsua_perror(THIS_FILE, "Unable to send NOTIFY", status); … … 398 386 399 387 388 pjsua_ui_inv_on_state_changed(call->index, e); 389 390 /* call->inv may be NULL now */ 391 400 392 /* Destroy media session when invite session is disconnected. */ 401 393 if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { 402 394 403 pj_assert(inv_data != NULL); 404 405 if (inv_data && inv_data->session) { 406 pjmedia_conf_remove_port(pjsua.mconf, inv_data->conf_slot); 407 pjmedia_session_destroy(inv_data->session); 408 pjsua.med_sock_use[inv_data->call_slot] = 0; 409 inv_data->session = NULL; 395 pj_assert(call != NULL); 396 397 if (call && call->session) { 398 pjmedia_conf_remove_port(pjsua.mconf, call->conf_slot); 399 pjmedia_session_destroy(call->session); 400 call->session = NULL; 410 401 411 402 PJ_LOG(3,(THIS_FILE,"Media session is destroyed")); 412 403 } 413 404 414 if (inv_data) { 415 416 pj_list_erase(inv_data); 417 418 } 419 } 420 421 pjsua_ui_inv_on_state_changed(inv, e); 405 call->inv = NULL; 406 --pjsua.call_cnt; 407 } 422 408 } 423 409 … … 437 423 */ 438 424 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) { 439 struct pjsua_inv_data *inv_data;440 441 inv_data= pjsip_evsub_get_mod_data(sub, pjsua.mod.id);442 if (! inv_data)425 pjsua_call *call; 426 427 call = pjsip_evsub_get_mod_data(sub, pjsua.mod.id); 428 if (!call) 443 429 return; 444 430 445 431 pjsip_evsub_set_mod_data(sub, pjsua.mod.id, NULL); 446 inv_data->xfer_sub = NULL;432 call->xfer_sub = NULL; 447 433 448 434 PJ_LOG(3,(THIS_FILE, "Xfer subscription terminated")); … … 459 445 pj_status_t status; 460 446 pjsip_tx_data *tdata; 461 struct pjsua_inv_data *inv_data; 447 pjsua_call *existing_call; 448 int new_call; 462 449 const pj_str_t str_refer_to = { "Refer-To", 8}; 463 450 pjsip_generic_string_hdr *refer_to; … … 465 452 struct pjsip_evsub_user xfer_cb; 466 453 pjsip_evsub *sub; 454 455 existing_call = inv->dlg->mod_data[pjsua.mod.id]; 467 456 468 457 /* Find the Refer-To header */ … … 524 513 525 514 /* Now make the outgoing call. */ 526 status = pjsua_ invite(uri, &inv_data);515 status = pjsua_make_call(existing_call->acc_index, uri, &new_call); 527 516 if (status != PJ_SUCCESS) { 528 517 … … 548 537 * reported back to the server subscription. 549 538 */ 550 inv_data->xfer_sub = sub;539 pjsua.calls[new_call].xfer_sub = sub; 551 540 552 541 /* Put the invite_data in the subscription. */ 553 pjsip_evsub_set_mod_data(sub, pjsua.mod.id, inv_data);542 pjsip_evsub_set_mod_data(sub, pjsua.mod.id, &pjsua.calls[new_call]); 554 543 } 555 544 … … 559 548 * session. We use this to trap incoming REFER request. 560 549 */ 561 void pjsua_inv_on_tsx_state_changed(pjsip_inv_session *inv, 562 pjsip_transaction *tsx, 563 pjsip_event *e) 564 { 550 static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv, 551 pjsip_transaction *tsx, 552 pjsip_event *e) 553 { 554 pjsua_call *call = inv->dlg->mod_data[pjsua.mod.id]; 555 565 556 if (tsx->role==PJSIP_ROLE_UAS && 566 557 tsx->state==PJSIP_TSX_STATE_TRYING && … … 570 561 * Incoming REFER request. 571 562 */ 572 on_call_transfered( inv, e->body.tsx_state.src.rdata);563 on_call_transfered(call->inv, e->body.tsx_state.src.rdata); 573 564 } 574 565 } … … 579 570 * has forked. 580 571 */ 581 void pjsua_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e) 572 static void pjsua_call_on_forked( pjsip_inv_session *inv, 573 pjsip_event *e) 582 574 { 583 575 PJ_UNUSED_ARG(inv); … … 591 583 * Create inactive SDP for call hold. 592 584 */ 593 static pj_status_t create_inactive_sdp( struct pjsua_inv_data *inv_session,585 static pj_status_t create_inactive_sdp(pjsua_call *call, 594 586 pjmedia_sdp_session **p_answer) 595 587 { … … 601 593 /* Create new offer */ 602 594 status = pjmedia_endpt_create_sdp(pjsua.med_endpt, pjsua.pool, 1, 603 &pjsua.med_sock_info[inv_session->call_slot], 604 &sdp); 595 &call->skinfo, &sdp); 605 596 if (status != PJ_SUCCESS) { 606 597 pjsua_perror(THIS_FILE, "Unable to create local SDP", status); … … 634 625 * Called when session received new offer. 635 626 */ 636 void pjsua_inv_on_rx_offer(pjsip_inv_session *inv,637 638 { 639 struct pjsua_inv_data *inv_data;627 static void pjsua_call_on_rx_offer(pjsip_inv_session *inv, 628 const pjmedia_sdp_session *offer) 629 { 630 pjsua_call *call; 640 631 pjmedia_sdp_conn *conn; 641 632 pjmedia_sdp_session *answer; … … 643 634 pj_status_t status; 644 635 645 inv_data= inv->dlg->mod_data[pjsua.mod.id];636 call = inv->dlg->mod_data[pjsua.mod.id]; 646 637 647 638 /* … … 670 661 /* Supply candidate answer */ 671 662 if (is_remote_active) { 672 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, inv->pool, 1, 673 &pjsua.med_sock_info[inv_data->call_slot], 674 &answer); 663 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, call->inv->pool, 1, 664 &call->skinfo, &answer); 675 665 } else { 676 status = create_inactive_sdp( inv_data, &answer );666 status = create_inactive_sdp( call, &answer ); 677 667 } 678 668 … … 682 672 } 683 673 684 status = pjsip_inv_set_sdp_answer( inv, answer);674 status = pjsip_inv_set_sdp_answer(call->inv, answer); 685 675 if (status != PJ_SUCCESS) { 686 676 pjsua_perror(THIS_FILE, "Unable to set answer", status); … … 696 686 * has succeeded. 697 687 */ 698 void pjsua_inv_on_media_update(pjsip_inv_session *inv, pj_status_t status) 699 { 700 struct pjsua_inv_data *inv_data; 688 static void pjsua_call_on_media_update(pjsip_inv_session *inv, 689 pj_status_t status) 690 { 691 pjsua_call *call; 701 692 const pjmedia_sdp_session *local_sdp; 702 693 const pjmedia_sdp_session *remote_sdp; … … 705 696 char tmp[PJSIP_MAX_URL_SIZE]; 706 697 698 call = inv->dlg->mod_data[pjsua.mod.id]; 699 707 700 if (status != PJ_SUCCESS) { 708 701 … … 714 707 /* Destroy existing media session, if any. */ 715 708 716 inv_data = inv->dlg->mod_data[pjsua.mod.id]; 717 if (inv_data && inv_data->session) { 718 pjmedia_conf_remove_port(pjsua.mconf, inv_data->conf_slot); 719 pjmedia_session_destroy(inv_data->session); 720 pjsua.med_sock_use[inv_data->call_slot] = 0; 721 inv_data->session = NULL; 709 if (call && call->session) { 710 pjmedia_conf_remove_port(pjsua.mconf, call->conf_slot); 711 pjmedia_session_destroy(call->session); 712 call->session = NULL; 722 713 } 723 714 724 715 /* Get local and remote SDP */ 725 716 726 status = pjmedia_sdp_neg_get_active_local( inv->neg, &local_sdp);717 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp); 727 718 if (status != PJ_SUCCESS) { 728 719 pjsua_perror(THIS_FILE, … … 733 724 734 725 735 status = pjmedia_sdp_neg_get_active_remote( inv->neg, &remote_sdp);726 status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp); 736 727 if (status != PJ_SUCCESS) { 737 728 pjsua_perror(THIS_FILE, … … 748 739 749 740 status = pjmedia_session_create( pjsua.med_endpt, 1, 750 & pjsua.med_sock_info[inv_data->call_slot],741 &call->skinfo, 751 742 local_sdp, remote_sdp, 752 inv_data,753 & inv_data->session );743 call, 744 &call->session ); 754 745 if (status != PJ_SUCCESS) { 755 746 pjsua_perror(THIS_FILE, "Unable to create media session", … … 762 753 * We need the port interface to add to the conference bridge. 763 754 */ 764 pjmedia_session_get_port( inv_data->session, 0, &media_port);755 pjmedia_session_get_port(call->session, 0, &media_port); 765 756 766 757 … … 770 761 port_name.ptr = tmp; 771 762 port_name.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, 772 inv_data->inv->dlg->remote.info->uri,763 call->inv->dlg->remote.info->uri, 773 764 tmp, sizeof(tmp)); 774 765 if (port_name.slen < 1) { 775 766 port_name = pj_str("call"); 776 767 } 777 status = pjmedia_conf_add_port( pjsua.mconf, inv->pool,768 status = pjmedia_conf_add_port( pjsua.mconf, call->inv->pool, 778 769 media_port, 779 770 &port_name, 780 & inv_data->conf_slot);771 &call->conf_slot); 781 772 if (status != PJ_SUCCESS) { 782 773 pjsua_perror(THIS_FILE, "Unable to create conference slot", 783 774 status); 784 pjmedia_session_destroy( inv_data->session);785 inv_data->session = NULL;775 pjmedia_session_destroy(call->session); 776 call->session = NULL; 786 777 return; 787 778 } … … 790 781 * port 791 782 */ 792 if (pjsua.wav_file && inv->role == PJSIP_ROLE_UAS) { 783 if (pjsua.auto_play && pjsua.wav_file && 784 call->inv->role == PJSIP_ROLE_UAS) 785 { 793 786 794 787 pjmedia_conf_connect_port( pjsua.mconf, pjsua.wav_slot, 795 inv_data->conf_slot); 788 call->conf_slot); 789 790 } else if (pjsua.auto_loop && call->inv->role == PJSIP_ROLE_UAS) { 791 792 pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot, 793 call->conf_slot); 794 795 } else if (pjsua.auto_conf) { 796 797 int i; 798 799 pjmedia_conf_connect_port( pjsua.mconf, 0, call->conf_slot); 800 pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot, 0); 801 802 for (i=0; i < pjsua.max_calls; ++i) { 803 804 if (!pjsua.calls[i].session) 805 continue; 806 807 pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot, 808 pjsua.calls[i].conf_slot); 809 pjmedia_conf_connect_port( pjsua.mconf, pjsua.calls[i].conf_slot, 810 call->conf_slot); 811 } 796 812 797 813 } else { … … 800 816 * main conference bridge. 801 817 */ 802 pjmedia_conf_connect_port( pjsua.mconf, 0, inv_data->conf_slot);803 pjmedia_conf_connect_port( pjsua.mconf, inv_data->conf_slot, 0);818 pjmedia_conf_connect_port( pjsua.mconf, 0, call->conf_slot); 819 pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot, 0); 804 820 } 805 821 … … 812 828 unsigned i; 813 829 814 pjmedia_session_get_info( inv_data->session, &sess_info);830 pjmedia_session_get_info(call->session, &sess_info); 815 831 for (i=0; i<sess_info.stream_cnt; ++i) { 816 832 int len; … … 851 867 * Hangup call. 852 868 */ 853 void pjsua_inv_hangup(struct pjsua_inv_data *inv_session, int code) 854 { 869 void pjsua_call_hangup(int call_index, int code) 870 { 871 pjsua_call *call; 855 872 pj_status_t status; 856 873 pjsip_tx_data *tdata; 857 874 858 status = pjsip_inv_end_session(inv_session->inv, 859 code, NULL, &tdata); 875 876 call = &pjsua.calls[call_index]; 877 878 if (!call->inv) { 879 PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 880 return; 881 } 882 883 status = pjsip_inv_end_session(call->inv, code, NULL, &tdata); 860 884 if (status != PJ_SUCCESS) { 861 885 pjsua_perror(THIS_FILE, … … 872 896 return; 873 897 874 status = pjsip_inv_send_msg( inv_session->inv, tdata, NULL);898 status = pjsip_inv_send_msg(call->inv, tdata, NULL); 875 899 if (status != PJ_SUCCESS) { 876 900 pjsua_perror(THIS_FILE, … … 885 909 * Put call on-Hold. 886 910 */ 887 void pjsua_ inv_set_hold(struct pjsua_inv_data *inv_session)911 void pjsua_call_set_hold(int call_index) 888 912 { 889 913 pjmedia_sdp_session *sdp; 890 pjs ip_inv_session *inv = inv_session->inv;914 pjsua_call *call; 891 915 pjsip_tx_data *tdata; 892 916 pj_status_t status; 893 917 894 if (inv->state != PJSIP_INV_STATE_CONFIRMED) { 918 call = &pjsua.calls[call_index]; 919 920 if (!call->inv) { 921 PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 922 return; 923 } 924 925 if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) { 895 926 PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed")); 896 927 return; 897 928 } 898 929 899 status = create_inactive_sdp( inv_session, &sdp);930 status = create_inactive_sdp(call, &sdp); 900 931 if (status != PJ_SUCCESS) 901 932 return; 902 933 903 934 /* Send re-INVITE with new offer */ 904 status = pjsip_inv_reinvite( inv_session->inv, NULL, sdp, &tdata);935 status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata); 905 936 if (status != PJ_SUCCESS) { 906 937 pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); … … 908 939 } 909 940 910 status = pjsip_inv_send_msg( inv_session->inv, tdata, NULL);941 status = pjsip_inv_send_msg( call->inv, tdata, NULL); 911 942 if (status != PJ_SUCCESS) { 912 943 pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); … … 919 950 * re-INVITE. 920 951 */ 921 void pjsua_ inv_reinvite(struct pjsua_inv_data *inv_session)952 void pjsua_call_reinvite(int call_index) 922 953 { 923 954 pjmedia_sdp_session *sdp; 924 955 pjsip_tx_data *tdata; 925 pjs ip_inv_session *inv = inv_session->inv;956 pjsua_call *call; 926 957 pj_status_t status; 927 958 928 929 if (inv->state != PJSIP_INV_STATE_CONFIRMED) { 959 call = &pjsua.calls[call_index]; 960 961 if (!call->inv) { 962 PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 963 return; 964 } 965 966 967 if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) { 930 968 PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed")); 931 969 return; … … 933 971 934 972 /* Create SDP */ 935 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, inv->pool, 1,936 & pjsua.med_sock_info[inv_session->call_slot],937 &sdp); 938 if (status != PJ_SUCCESS) { 939 pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",status);973 status = pjmedia_endpt_create_sdp( pjsua.med_endpt, call->inv->pool, 1, 974 &call->skinfo, &sdp); 975 if (status != PJ_SUCCESS) { 976 pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", 977 status); 940 978 return; 941 979 } 942 980 943 981 /* Send re-INVITE with new offer */ 944 status = pjsip_inv_reinvite( inv_session->inv, NULL, sdp, &tdata);982 status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata); 945 983 if (status != PJ_SUCCESS) { 946 984 pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); … … 948 986 } 949 987 950 status = pjsip_inv_send_msg( inv_session->inv, tdata, NULL);988 status = pjsip_inv_send_msg( call->inv, tdata, NULL); 951 989 if (status != PJ_SUCCESS) { 952 990 pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); … … 959 997 * Transfer call. 960 998 */ 961 void pjsua_inv_xfer_call(struct pjsua_inv_data *inv_session, 962 const char *dest) 999 void pjsua_call_xfer(int call_index, const char *dest) 963 1000 { 964 1001 pjsip_evsub *sub; 965 1002 pjsip_tx_data *tdata; 1003 pjsua_call *call; 966 1004 pj_str_t tmp; 967 1005 pj_status_t status; 968 1006 969 1007 1008 call = &pjsua.calls[call_index]; 1009 1010 if (!call->inv) { 1011 PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 1012 return; 1013 } 1014 970 1015 /* Create xfer client subscription. 971 1016 * We're not interested in knowing the transfer result, so we 972 1017 * put NULL as the callback. 973 1018 */ 974 status = pjsip_xfer_create_uac( inv_session->inv->dlg, NULL, &sub);1019 status = pjsip_xfer_create_uac(call->inv->dlg, NULL, &sub); 975 1020 if (status != PJ_SUCCESS) { 976 1021 pjsua_perror(THIS_FILE, "Unable to create xfer", status); … … 1006 1051 void pjsua_inv_shutdown() 1007 1052 { 1008 struct pjsua_inv_data *inv_data, *next; 1009 1010 inv_data = pjsua.inv_list.next; 1011 while (inv_data != &pjsua.inv_list) { 1053 int i; 1054 1055 for (i=0; i<pjsua.max_calls; ++i) { 1012 1056 pjsip_tx_data *tdata; 1013 1014 next = inv_data->next; 1015 1016 if (pjsip_inv_end_session(inv_data->inv, 410, NULL, &tdata)==0) { 1057 pjsua_call *call; 1058 1059 if (pjsua.calls[i].inv == NULL) 1060 continue; 1061 1062 call = &pjsua.calls[i]; 1063 1064 if (pjsip_inv_end_session(call->inv, 410, NULL, &tdata)==0) { 1017 1065 if (tdata) 1018 pjsip_inv_send_msg( inv_data->inv, tdata, NULL);1066 pjsip_inv_send_msg(call->inv, tdata, NULL); 1019 1067 } 1020 1021 inv_data = next; 1022 } 1023 } 1024 1025 1068 } 1069 } 1070 1071 1072 pj_status_t pjsua_call_init(void) 1073 { 1074 /* Initialize invite session callback. */ 1075 pjsip_inv_callback inv_cb; 1076 pj_status_t status; 1077 1078 pj_memset(&inv_cb, 0, sizeof(inv_cb)); 1079 inv_cb.on_state_changed = &pjsua_call_on_state_changed; 1080 inv_cb.on_new_session = &pjsua_call_on_forked; 1081 inv_cb.on_media_update = &pjsua_call_on_media_update; 1082 inv_cb.on_rx_offer = &pjsua_call_on_rx_offer; 1083 inv_cb.on_tsx_state_changed = &pjsua_call_on_tsx_state_changed; 1084 1085 1086 /* Initialize invite session module: */ 1087 status = pjsip_inv_usage_init(pjsua.endpt, &pjsua.mod, &inv_cb); 1088 1089 return status; 1090 }
Note: See TracChangeset
for help on using the changeset viewer.