Ignore:
Timestamp:
Nov 25, 2007 4:40:07 AM (16 years ago)
Author:
bennylp
Message:

Ticket #416: Allow application to handle sending ACK manually

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r1597 r1598  
    273273    { 
    274274        struct tsx_inv_data *tsx_inv_data; 
    275  
    276         /* Get invite session's transaction data */ 
    277         tsx_inv_data = (struct tsx_inv_data*) tsx->mod_data[mod_inv.mod.id]; 
     275        struct tsx_inv_data dummy; 
     276 
     277        /* Get invite session's transaction data. 
     278         * Note that tsx may be NULL, for example when application sends 
     279         * delayed ACK request (at this time, the original INVITE  
     280         * transaction may have been destroyed. 
     281         */ 
     282        if (tsx) { 
     283            tsx_inv_data = (struct tsx_inv_data*)tsx->mod_data[mod_inv.mod.id]; 
     284        } else { 
     285            tsx_inv_data = &dummy; 
     286            pj_bzero(&dummy, sizeof(dummy)); 
     287            dummy.inv = inv; 
     288        } 
    278289 
    279290        status = inv_negotiate_sdp(inv); 
     
    302313 * Send ACK for 2xx response. 
    303314 */ 
    304 static pj_status_t inv_send_ack(pjsip_inv_session *inv, pjsip_rx_data *rdata) 
    305 { 
     315static pj_status_t inv_send_ack(pjsip_inv_session *inv, pjsip_event *e) 
     316{ 
     317    pjsip_rx_data *rdata; 
    306318    pj_status_t status; 
     319 
     320    if (e->type == PJSIP_EVENT_TSX_STATE) 
     321        rdata = e->body.tsx_state.src.rdata; 
     322    else if (e->type == PJSIP_EVENT_RX_MSG) 
     323        rdata = e->body.rx_msg.rdata; 
     324    else { 
     325        pj_assert(!"Unsupported event type"); 
     326        return PJ_EBUG; 
     327    } 
    307328 
    308329    PJ_LOG(5,(inv->obj_name, "Received %s, sending ACK", 
     
    311332    /* Check if we have cached ACK request */ 
    312333    if (inv->last_ack && rdata->msg_info.cseq->cseq == inv->last_ack_cseq) { 
     334 
    313335        pjsip_tx_data_add_ref(inv->last_ack); 
     336 
     337    } else if (mod_inv.cb.on_send_ack) { 
     338        /* If application handles ACK transmission manually, just notify the 
     339         * callback 
     340         */ 
     341        PJ_LOG(5,(inv->obj_name, "Received %s, notifying application callback", 
     342                  pjsip_rx_data_get_info(rdata))); 
     343 
     344        (*mod_inv.cb.on_send_ack)(inv, rdata); 
     345        return PJ_SUCCESS; 
     346 
    314347    } else { 
    315         const pjmedia_sdp_session *sdp = NULL; 
    316  
    317         /* Destroy last_ack */ 
    318         if (inv->last_ack) { 
    319             pjsip_tx_data_dec_ref(inv->last_ack); 
    320             inv->last_ack = NULL; 
    321         } 
    322  
    323         /* Create new ACK request */ 
    324         status = pjsip_dlg_create_request(inv->dlg, pjsip_get_ack_method(),  
    325                                           rdata->msg_info.cseq->cseq,  
    326                                           &inv->last_ack); 
    327         if (status != PJ_SUCCESS) { 
    328             /* Better luck next time */ 
    329             pj_assert(!"Unable to create ACK!"); 
    330             return status; 
    331         } 
    332  
    333         /* See if we have pending SDP answer to send */ 
    334         sdp = inv_has_pending_answer(inv, inv->invite_tsx); 
    335         if (sdp) { 
    336             inv->last_ack->msg->body=create_sdp_body(inv->last_ack->pool, sdp); 
    337         } 
    338  
    339  
    340         /* Keep this for subsequent response retransmission */ 
    341         inv->last_ack_cseq = rdata->msg_info.cseq->cseq; 
    342         pjsip_tx_data_add_ref(inv->last_ack); 
     348        status = pjsip_inv_create_ack(inv, rdata->msg_info.cseq->cseq, 
     349                                      &inv->last_ack); 
    343350    } 
    344351 
     
    349356        pj_assert(!"Unable to send ACK!"); 
    350357        return status; 
     358    } 
     359 
     360 
     361    /* Set state to CONFIRMED (if we're not in CONFIRMED yet) */ 
     362    if (inv->state != PJSIP_INV_STATE_CONFIRMED) { 
     363        inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e); 
    351364    } 
    352365 
     
    474487        inv->invite_tsx == NULL)  
    475488    { 
    476  
    477         inv_send_ack(inv, rdata); 
     489        pjsip_event e; 
     490 
     491        PJSIP_EVENT_INIT_RX_MSG(e, rdata); 
     492        inv_send_ack(inv, &e); 
    478493        return PJ_TRUE; 
    479494 
     
    19671982 
    19681983    return status; 
     1984} 
     1985 
     1986/* 
     1987 * Create an ACK request. 
     1988 */ 
     1989PJ_DEF(pj_status_t) pjsip_inv_create_ack(pjsip_inv_session *inv, 
     1990                                         int cseq, 
     1991                                         pjsip_tx_data **p_tdata) 
     1992{ 
     1993    const pjmedia_sdp_session *sdp = NULL; 
     1994    pj_status_t status; 
     1995 
     1996    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL); 
     1997 
     1998    /* Lock dialog. */ 
     1999    pjsip_dlg_inc_lock(inv->dlg); 
     2000 
     2001    /* Destroy last_ack */ 
     2002    if (inv->last_ack) { 
     2003        pjsip_tx_data_dec_ref(inv->last_ack); 
     2004        inv->last_ack = NULL; 
     2005    } 
     2006 
     2007    /* Create new ACK request */ 
     2008    status = pjsip_dlg_create_request(inv->dlg, pjsip_get_ack_method(),  
     2009                                      cseq, &inv->last_ack); 
     2010    if (status != PJ_SUCCESS) { 
     2011        pjsip_dlg_dec_lock(inv->dlg); 
     2012        return status; 
     2013    } 
     2014 
     2015    /* See if we have pending SDP answer to send */ 
     2016    sdp = inv_has_pending_answer(inv, inv->invite_tsx); 
     2017    if (sdp) { 
     2018        inv->last_ack->msg->body = create_sdp_body(inv->last_ack->pool, sdp); 
     2019    } 
     2020 
     2021    /* Keep this for subsequent response retransmission */ 
     2022    inv->last_ack_cseq = cseq; 
     2023    pjsip_tx_data_add_ref(inv->last_ack); 
     2024 
     2025    /* Done */ 
     2026    *p_tdata = inv->last_ack; 
     2027 
     2028    /* Unlock dialog. */ 
     2029    pjsip_dlg_dec_lock(inv->dlg); 
     2030 
     2031    return PJ_SUCCESS; 
    19692032} 
    19702033 
     
    25482611                pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 
    25492612 
    2550                 inv_send_ack(inv, e->body.tsx_state.src.rdata); 
    2551                 inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e); 
    2552  
     2613                inv_send_ack(inv, e); 
    25532614 
    25542615            } else  { 
     
    27272788                    pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 
    27282789 
    2729                     inv_send_ack(inv, e->body.tsx_state.src.rdata); 
    2730                     inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e); 
     2790                    inv_send_ack(inv, e); 
    27312791                } 
    27322792 
     
    31683228 
    31693229            /* Send ACK */ 
    3170             inv_send_ack(inv, e->body.tsx_state.src.rdata); 
     3230            inv_send_ack(inv, e); 
    31713231 
    31723232        } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED && 
Note: See TracChangeset for help on using the changeset viewer.