Changeset 2315
- Timestamp:
- Sep 24, 2008 10:10:15 AM (16 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r2301 r2315 1231 1231 #endif 1232 1232 1233 /** 1234 * Disconnect other call legs when more than one 2xx responses for 1235 * outgoing INVITE are received due to forking. Currently the library 1236 * is not able to handle simultaneous forked media, so disconnecting 1237 * the other call legs is necessary. 1238 * 1239 * With this setting enabled, the library will handle only one of the 1240 * connected call leg, and the other connected call legs will be 1241 * disconnected. 1242 * 1243 * Default: PJ_TRUE (only disable this setting for testing purposes). 1244 */ 1245 pj_bool_t hangup_forked_call; 1246 1233 1247 } pjsua_config; 1234 1248 -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
r2301 r2315 499 499 pjsip_tpselector *sel); 500 500 501 501 pjsip_dialog* on_dlg_forked(pjsip_dialog *first_set, pjsip_rx_data *res); 502 502 pj_status_t acquire_call(const char *title, 503 503 pjsua_call_id call_id, -
pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
r2271 r2315 581 581 { 582 582 pjsip_dialog *dlg; 583 const pjsip_route_hdr *r; 583 const pjsip_msg *msg = rdata->msg_info.msg; 584 const pjsip_hdr *end_hdr, *hdr; 585 const pjsip_contact_hdr *contact; 584 586 pj_status_t status; 585 587 … … 588 590 589 591 /* rdata must be response message. */ 590 PJ_ASSERT_RETURN( rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG,592 PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG, 591 593 PJSIP_ENOTRESPONSEMSG); 592 594 593 595 /* Status code MUST be 1xx (but not 100), or 2xx */ 594 status = rdata->msg_info.msg->line.status.code;596 status = msg->line.status.code; 595 597 PJ_ASSERT_RETURN( (status/100==1 && status!=100) || 596 598 (status/100==2), PJ_EBUG); … … 598 600 /* To tag must present in the response. */ 599 601 PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen != 0, PJSIP_EMISSINGTAG); 602 603 /* Find Contact header in the response */ 604 contact = (const pjsip_contact_hdr*) 605 pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL); 606 if (contact == NULL) 607 return PJSIP_EMISSINGHDR; 600 608 601 609 /* Create the dialog. */ … … 604 612 return status; 605 613 606 /* Clone remote target. */607 dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, first_dlg->target);614 /* Set remote target from the response. */ 615 dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri); 608 616 609 617 /* Clone local info. */ … … 637 645 638 646 /* Dialog state depends on the response. */ 639 status = rdata->msg_info.msg->line.status.code/100;647 status = msg->line.status.code/100; 640 648 if (status == 1 || status == 2) 641 649 dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED; … … 652 660 pjsip_hdr_clone(dlg->pool, first_dlg->call_id); 653 661 654 /* Duplicate Route-Set. */662 /* Get route-set from the response. */ 655 663 pj_list_init(&dlg->route_set); 656 r = first_dlg->route_set.next; 657 while (r != &first_dlg->route_set) { 658 pjsip_route_hdr *h; 659 660 h = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, r); 661 pj_list_push_back(&dlg->route_set, h); 662 663 r = r->next; 664 } 664 end_hdr = &msg->hdr; 665 for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) { 666 if (hdr->type == PJSIP_H_RECORD_ROUTE) { 667 pjsip_route_hdr *r; 668 r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr); 669 pjsip_routing_hdr_set_route(r); 670 pj_list_push_back(&dlg->route_set, r); 671 } 672 } 673 665 674 //dlg->route_set_frozen = PJ_TRUE; 666 675 … … 1814 1823 } 1815 1824 1825 /* Handle the case of forked response, when the application creates 1826 * the forked dialog but not the invite session. In this case, the 1827 * forked 200/OK response will be unhandled, and we must send ACK 1828 * here. 1829 */ 1830 if (dlg->usage_cnt==0) { 1831 pj_status_t status; 1832 1833 if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD && 1834 rdata->msg_info.msg->line.status.code/100 == 2) 1835 { 1836 pjsip_tx_data *ack; 1837 1838 status = pjsip_dlg_create_request(dlg, &pjsip_ack_method, 1839 rdata->msg_info.cseq->cseq, 1840 &ack); 1841 if (status == PJ_SUCCESS) 1842 status = pjsip_dlg_send_request(dlg, ack, -1, NULL); 1843 } else if (rdata->msg_info.msg->line.status.code==401 || 1844 rdata->msg_info.msg->line.status.code==407) 1845 { 1846 pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata); 1847 pjsip_tx_data *tdata; 1848 1849 status = pjsip_auth_clt_reinit_req( &dlg->auth_sess, 1850 rdata, tsx->last_tx, 1851 &tdata); 1852 1853 if (status == PJ_SUCCESS) { 1854 /* Re-send request. */ 1855 status = pjsip_dlg_send_request(dlg, tdata, -1, NULL); 1856 } 1857 } 1858 } 1859 1816 1860 /* Unhandled response does not necessarily mean error because 1817 1861 dialog usages may choose to process the transaction state instead. -
pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c
r2039 r2315 833 833 dlg = (*mod_ua.param.on_dlg_forked)(dlg_set->dlg_list.next, 834 834 rdata); 835 if (dlg == NULL) { 836 pj_mutex_unlock(mod_ua.mutex); 837 return PJ_TRUE; 838 } 835 839 } else { 836 840 dlg = dlg_set->dlg_list.next; -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r2301 r2315 2944 2944 2945 2945 /* 2946 * Callback from UA layer when forked dialog response is received. 2947 */ 2948 pjsip_dialog* on_dlg_forked(pjsip_dialog *dlg, pjsip_rx_data *res) 2949 { 2950 if (dlg->uac_has_2xx && 2951 res->msg_info.cseq->method.id == PJSIP_INVITE_METHOD && 2952 pjsip_rdata_get_tsx(res) == NULL && 2953 res->msg_info.msg->line.status.code/100 == 2) 2954 { 2955 pjsip_dialog *forked_dlg; 2956 pjsip_tx_data *bye; 2957 pj_status_t status; 2958 2959 /* Create forked dialog */ 2960 status = pjsip_dlg_fork(dlg, res, &forked_dlg); 2961 if (status != PJ_SUCCESS) 2962 return NULL; 2963 2964 pjsip_dlg_inc_lock(forked_dlg); 2965 2966 /* Disconnect the call */ 2967 status = pjsip_dlg_create_request(forked_dlg, &pjsip_bye_method, 2968 -1, &bye); 2969 if (status == PJ_SUCCESS) { 2970 status = pjsip_dlg_send_request(forked_dlg, bye, -1, NULL); 2971 } 2972 2973 pjsip_dlg_dec_lock(forked_dlg); 2974 2975 if (status != PJ_SUCCESS) { 2976 return NULL; 2977 } 2978 2979 return forked_dlg; 2980 2981 } else { 2982 return dlg; 2983 } 2984 } 2985 2986 /* 2946 2987 * Disconnect call upon error. 2947 2988 */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r2301 r2315 97 97 cfg->srtp_secure_signaling = PJSUA_DEFAULT_SRTP_SECURE_SIGNALING; 98 98 #endif 99 cfg->hangup_forked_call = PJ_TRUE; 99 100 } 100 101 … … 623 624 pjsua_media_config default_media_cfg; 624 625 const pj_str_t STR_OPTIONS = { "OPTIONS", 7 }; 626 pjsip_ua_init_param ua_init_param; 625 627 pj_status_t status; 626 628 … … 695 697 696 698 /* Initialize UA layer module: */ 697 status = pjsip_ua_init_module( pjsua_var.endpt, NULL ); 699 pj_bzero(&ua_init_param, sizeof(ua_init_param)); 700 if (ua_cfg->hangup_forked_call) { 701 ua_init_param.on_dlg_forked = &on_dlg_forked; 702 } 703 status = pjsip_ua_init_module( pjsua_var.endpt, &ua_init_param); 698 704 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 699 705
Note: See TracChangeset
for help on using the changeset viewer.