Ignore:
Timestamp:
Dec 28, 2016 3:40:07 AM (8 years ago)
Author:
nanang
Message:

Re #1900: More merged from trunk (r5512 mistakenly contains merged changes in third-party dir only).

Location:
pjproject/branches/projects/uwp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/uwp

  • pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_call.c

    r5185 r5513  
    570570{ 
    571571    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); 
    573574} 
    574575 
     
    609610    call->opt = *opt; 
    610611 
     612    if (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) { 
     613        pjsua_media_channel_deinit(call->index); 
     614    } 
     615 
    611616    /* If call is established or media channel hasn't been initialized, 
    612617     * reinit media channel. 
     
    614619    if ((call->inv && call->inv->state == PJSIP_INV_STATE_CONNECTING && 
    615620         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)) 
    617623    { 
    618624        pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC; 
     
    632638 
    633639    return PJ_SUCCESS; 
     640} 
     641 
     642static 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    } 
    634661} 
    635662 
     
    773800    pjsip_dlg_inc_lock(dlg); 
    774801 
    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); 
    792803 
    793804    /* Calculate call's secure level */ 
     
    954965    struct call_answer *answer, *next; 
    955966 
     967    /* No initial answer yet, this function should be called again later */ 
     968    if (!call->inv->last_answer) 
     969        return; 
     970 
    956971    answer = call->async_call.call_var.inc_call.answers.next; 
    957972    while (answer != &call->async_call.call_var.inc_call.answers) { 
     
    983998    pjsip_tx_data *response = NULL; 
    984999    unsigned options = 0; 
     1000    pjsip_dialog *dlg = call->async_call.dlg; 
    9851001    int sip_err_code = (info? info->sip_err_code: 0); 
    9861002    pj_status_t status = (info? info->status: PJ_SUCCESS); 
    9871003 
    9881004    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);     
    9891013 
    9901014    if (status != PJ_SUCCESS) { 
     
    9971021        pjsua_media_channel_deinit(call->index); 
    9981022        call->med_ch_cb = NULL; 
     1023        pjsip_dlg_dec_lock(dlg); 
    9991024        PJSUA_UNLOCK(); 
    10001025        return PJ_SUCCESS; 
     
    10681093        } 
    10691094    } 
    1070  
     1095     
     1096    pjsip_dlg_dec_lock(dlg); 
     1097     
    10711098    PJSUA_UNLOCK(); 
    10721099    return status; 
     
    10891116    pjsip_inv_session *inv = NULL; 
    10901117    int acc_id; 
    1091     pjsua_call *call; 
     1118    pjsua_call *call = NULL; 
    10921119    int call_id = -1; 
    10931120    int sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR; 
     
    12101237            goto on_return; 
    12111238        } 
     1239    } 
     1240 
     1241    if (!replaced_dlg) { 
     1242        /* Clone rdata. */ 
     1243        pjsip_rx_data_clone(rdata, 0, &call->incoming_data); 
    12121244    } 
    12131245 
     
    13521384 
    13531385    /* 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); 
    13561388    if (status != PJ_SUCCESS) { 
    13571389        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, 
     
    14601492    call->async_call.dlg = dlg; 
    14611493    pj_list_init(&call->async_call.call_var.inc_call.answers); 
     1494 
     1495    pjsip_dlg_inc_session(dlg, &pjsua_var.mod); 
    14621496 
    14631497    /* Init media channel, only when there is offer or call replace request. 
     
    15021536            pjsip_dlg_dec_lock(dlg); 
    15031537 
     1538            pjsip_dlg_dec_session(dlg, &pjsua_var.mod); 
     1539 
    15041540            call->inv = NULL; 
    15051541            call->async_call.dlg = NULL; 
     
    16101646        if (pjsua_var.ua_cfg.cb.on_incoming_call) { 
    16111647            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            } 
    16121661        } else { 
    16131662            pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE, 
     
    16191668    /* This INVITE request has been handled. */ 
    16201669on_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     
    16211679    pj_log_pop_indent(); 
    16221680    PJSUA_UNLOCK(); 
     
    21892247    /* If media transport creation is not yet completed, we will answer 
    21902248     * 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). 
    21912251     */ 
    2192     if (call->med_ch_cb) { 
     2252    if (call->med_ch_cb || !call->inv->last_answer) { 
    21932253        struct call_answer *answer; 
    21942254 
     
    22042264        } 
    22052265        if (reason) { 
     2266            answer->reason = PJ_POOL_ZALLOC_T(call->inv->pool_prov, pj_str_t); 
    22062267            pj_strdup(call->inv->pool_prov, answer->reason, reason); 
    22072268        } 
     
    22922353     * the call in the media transport creation callback instead. 
    22932354     */ 
    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    { 
    22952358        PJ_LOG(4,(THIS_FILE, "Pending call %d hangup upon completion " 
    22962359                             "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 
    22982366        if (code == 0) 
    22992367            call->last_code = PJSIP_SC_REQUEST_TERMINATED; 
     
    24382506    } 
    24392507 
     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 
    24402514    /* Create re-INVITE with new offer */ 
    24412515    status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata); 
     
    25592633    } 
    25602634 
     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 
    25612641    /* Create re-INVITE with new offer */ 
    25622642    status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata); 
     
    26682748    } 
    26692749 
     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 
    26702756    /* Create UPDATE with new offer */ 
    26712757    status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata); 
     
    27842870    pj_str_t str_dest; 
    27852871    int len; 
     2872    char call_id_dest_buf[PJSIP_MAX_URL_SIZE * 2]; 
     2873    int call_id_len; 
    27862874    pjsip_uri *uri; 
    27872875    pj_status_t status; 
     2876    const pjsip_parser_const_t *pconst; 
    27882877 
    27892878 
     
    28302919 
    28312920    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    } 
    28332937 
    28342938    /* Build the URI */ 
     
    28412945                           ((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ? 
    28422946                            "" : "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, 
    28452949                           (int)dest_dlg->remote.info->tag.slen, 
    28462950                           dest_dlg->remote.info->tag.ptr, 
     
    40504154    } 
    40514155 
     4156    cleanup_call_setting_flag(&call->opt); 
     4157 
    40524158    if (pjsua_var.ua_cfg.cb.on_call_rx_offer) { 
    40534159        pjsip_status_code code = PJSIP_SC_OK; 
    40544160        pjsua_call_setting opt; 
    40554161 
    4056         cleanup_call_setting_flag(&call->opt); 
    40574162        opt = call->opt; 
    4058  
    40594163        (*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL, 
    40604164                                                &code, &opt); 
     
    41824286#endif 
    41834287 
     4288    cleanup_call_setting_flag(&call->opt); 
     4289 
    41844290    if (pjsua_var.ua_cfg.cb.on_call_tx_offer) { 
    4185         cleanup_call_setting_flag(&call->opt); 
    41864291        (*pjsua_var.ua_cfg.cb.on_call_tx_offer)(call->index, NULL, 
    41874292                                                &call->opt); 
     
    44714576 
    44724577    if (refer_sub) { 
    4473         if (!pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0) 
     4578        if (pj_strnicmp2(&refer_sub->hvalue, "true", 4)!=0) 
    44744579            no_refer_sub = PJ_TRUE; 
    44754580    } 
     
    47774882               tsx->state >= PJSIP_TSX_STATE_COMPLETED && 
    47784883               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 && 
    47804886                tsx->status_code!=422)) 
    47814887    { 
     
    48224928               tsx->state >= PJSIP_TSX_STATE_COMPLETED && 
    48234929               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 && 
    48254932                tsx->status_code!=422)) 
    48264933    { 
Note: See TracChangeset for help on using the changeset viewer.