Changeset 1598
- Timestamp:
- Nov 25, 2007 4:40:07 AM (17 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h
r1477 r1598 191 191 void (*on_media_update)(pjsip_inv_session *inv_ses, 192 192 pj_status_t status); 193 194 /** 195 * This callback is called when the framework needs to send 196 * ACK request after it receives incoming 2xx response for 197 * INVITE. It allows application to manually handle the 198 * transmission of ACK request, which is required by some 3PCC 199 * scenarios. If this callback is not implemented, the framework 200 * will handle the ACK transmission automatically. 201 * 202 * When this callback is overridden, application may delay the 203 * sending of the ACK request (for example, when it needs to 204 * wait for answer from the other call leg, in 3PCC scenarios). 205 * 206 * Application creates the ACK request 207 * 208 * Once it has sent the ACK request, the framework will keep 209 * this ACK request in the cache. Subsequent receipt of 2xx response 210 * will not cause this callback to be called, and instead automatic 211 * retransmission of this ACK request from the cache will be done 212 * by the framework. 213 * 214 * This callback is optional. 215 */ 216 void (*on_send_ack)(pjsip_inv_session *inv, pjsip_rx_data *rdata); 193 217 194 218 } pjsip_inv_callback; … … 588 612 589 613 /** 614 * Create an ACK request. Normally ACK request transmission is handled 615 * by the framework. Application only needs to use this function if it 616 * handles the ACK transmission manually, by overriding \a on_send_ack() 617 * callback in #pjsip_inv_callback. 618 * 619 * Note that if the invite session has a pending offer to be answered 620 * (for example when the last 2xx response to INVITE contains an offer), 621 * application MUST have set the SDP answer with #pjsip_create_sdp_body() 622 * prior to creating the ACK request. In this case, the ACK request 623 * will be added with SDP message body. 624 * 625 * @param inv The invite session. 626 * @param cseq Mandatory argument to specify the CSeq of the 627 * ACK request. This value MUST match the value 628 * of the INVITE transaction to be acknowledged. 629 * @param p_tdata Pointer to receive the ACK request message to 630 * be created. 631 * 632 * @return PJ_SUCCESS if ACK request has been created. 633 */ 634 PJ_DECL(pj_status_t) pjsip_inv_create_ack(pjsip_inv_session *inv, 635 int cseq, 636 pjsip_tx_data **p_tdata); 637 638 639 /** 590 640 * Send request or response message in tdata. 591 641 * … … 603 653 604 654 605 606 655 /** 607 656 * Get the invite session for the dialog, if any. -
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r1597 r1598 273 273 { 274 274 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 } 278 289 279 290 status = inv_negotiate_sdp(inv); … … 302 313 * Send ACK for 2xx response. 303 314 */ 304 static pj_status_t inv_send_ack(pjsip_inv_session *inv, pjsip_rx_data *rdata) 305 { 315 static pj_status_t inv_send_ack(pjsip_inv_session *inv, pjsip_event *e) 316 { 317 pjsip_rx_data *rdata; 306 318 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 } 307 328 308 329 PJ_LOG(5,(inv->obj_name, "Received %s, sending ACK", … … 311 332 /* Check if we have cached ACK request */ 312 333 if (inv->last_ack && rdata->msg_info.cseq->cseq == inv->last_ack_cseq) { 334 313 335 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 314 347 } 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); 343 350 } 344 351 … … 349 356 pj_assert(!"Unable to send ACK!"); 350 357 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); 351 364 } 352 365 … … 474 487 inv->invite_tsx == NULL) 475 488 { 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); 478 493 return PJ_TRUE; 479 494 … … 1967 1982 1968 1983 return status; 1984 } 1985 1986 /* 1987 * Create an ACK request. 1988 */ 1989 PJ_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; 1969 2032 } 1970 2033 … … 2548 2611 pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 2549 2612 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); 2553 2614 2554 2615 } else { … … 2727 2788 pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 2728 2789 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); 2731 2791 } 2732 2792 … … 3168 3228 3169 3229 /* Send ACK */ 3170 inv_send_ack(inv, e ->body.tsx_state.src.rdata);3230 inv_send_ack(inv, e); 3171 3231 3172 3232 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&
Note: See TracChangeset
for help on using the changeset viewer.