Changeset 3215 for pjproject/trunk/pjsip/src/pjsip-ua/sip_timer.c
- Timestamp:
- Jun 21, 2010 1:28:55 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_timer.c
r2934 r3215 60 60 pj_bool_t use_update; /**< Use UPDATE method to 61 61 refresh the session */ 62 pj_bool_t with_sdp; /**< SDP in UPDATE? */ 62 63 pjsip_role_e role; /**< Role in last INVITE/ 63 64 UPDATE transaction. */ … … 322 323 * the session. 323 324 */ 324 void timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)325 static void timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry) 325 326 { 326 327 pjsip_inv_session *inv = (pjsip_inv_session*) entry->user_data; … … 331 332 pj_assert(inv); 332 333 334 inv->timer->timer.id = 0; 335 333 336 PJ_UNUSED_ARG(timer_heap); 334 335 /* When there is a pending INVITE transaction, delay/reschedule this timer336 * for five seconds to cover the case that pending INVITE fails and the337 * previous session is still active. If the pending INVITE is successful,338 * timer state will be updated, i.e: restarted or stopped.339 */340 if (inv->invite_tsx != NULL) {341 pj_time_val delay = {5};342 343 inv->timer->timer.id = 1;344 pjsip_endpt_schedule_timer(inv->dlg->endpt, &inv->timer->timer, &delay);345 return;346 }347 337 348 338 /* Lock dialog. */ … … 350 340 351 341 /* Check our role */ 352 as_refresher = 342 as_refresher = 353 343 (inv->timer->refresher == TR_UAC && inv->timer->role == PJSIP_ROLE_UAC) || 354 344 (inv->timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS); … … 356 346 /* Do action based on role, refresher or refreshee */ 357 347 if (as_refresher) { 358 359 348 pj_time_val now; 349 350 /* As refresher, reshedule the refresh request on the following: 351 * - msut not send re-INVITE if another INVITE or SDP negotiation 352 * is in progress. 353 * - must not send UPDATE with SDP if SDP negotiation is in progress 354 */ 355 pjmedia_sdp_neg_state neg_state = pjmedia_sdp_neg_get_state(inv->neg); 356 if ( (!inv->timer->use_update && ( 357 inv->invite_tsx != NULL || 358 neg_state != PJMEDIA_SDP_NEG_STATE_DONE) 359 ) 360 || 361 (inv->timer->use_update && inv->timer->with_sdp && 362 neg_state != PJMEDIA_SDP_NEG_STATE_DONE 363 ) 364 ) 365 { 366 pj_time_val delay = {1, 0}; 367 368 inv->timer->timer.id = 1; 369 pjsip_endpt_schedule_timer(inv->dlg->endpt, &inv->timer->timer, 370 &delay); 371 pjsip_dlg_dec_lock(inv->dlg); 372 return; 373 } 360 374 361 375 /* Refresher, refresh the session */ 362 376 if (inv->timer->use_update) { 363 /* Create UPDATE request without offer */ 364 status = pjsip_inv_update(inv, NULL, NULL, &tdata); 377 const pjmedia_sdp_session *offer = NULL; 378 379 if (inv->timer->with_sdp) { 380 pjmedia_sdp_neg_get_active_local(inv->neg, &offer); 381 } 382 status = pjsip_inv_update(inv, NULL, offer, &tdata); 365 383 } else { 366 384 /* Create re-INVITE without modifying session */ … … 385 403 386 404 pj_gettimeofday(&now); 387 PJ_LOG(4, (inv->pool->obj_name, 388 "Refresh session after %ds (expiration period=%ds)",405 PJ_LOG(4, (inv->pool->obj_name, 406 "Refreshing session after %ds (expiration period=%ds)", 389 407 (now.sec-inv->timer->last_refresh.sec), 390 408 inv->timer->setting.sess_expires)); … … 415 433 /* Print error message, if any */ 416 434 if (status != PJ_SUCCESS) { 417 char errmsg[PJ_ERR_MSG_SIZE];418 419 435 if (tdata) 420 436 pjsip_tx_data_dec_ref(tdata); 421 437 422 pj_strerror(status, errmsg, sizeof(errmsg)); 423 PJ_LOG(2, (inv->pool->obj_name, "Session timer fails in %s session, " 424 "err code=%d (%s)", 425 (as_refresher? "refreshing" : 426 "terminating"), 427 status, errmsg)); 438 PJ_PERROR(2, (inv->pool->obj_name, status, 439 "Error in %s session timer", 440 (as_refresher? "refreshing" : "terminating"))); 428 441 } 429 442 } … … 432 445 static void start_timer(pjsip_inv_session *inv) 433 446 { 447 const pj_str_t UPDATE = { "UPDATE", 6 }; 434 448 pjsip_timer *timer = inv->timer; 435 449 pj_time_val delay = {0}; … … 438 452 439 453 stop_timer(inv); 454 455 inv->timer->use_update = 456 (pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, 457 &UPDATE) == PJSIP_DIALOG_CAP_SUPPORTED); 458 if (!inv->timer->use_update) { 459 /* INVITE always needs SDP */ 460 inv->timer->with_sdp = PJ_TRUE; 461 } 440 462 441 463 pj_timer_entry_init(&timer->timer, … … 838 860 inv->timer->refresher = TR_UAC; 839 861 840 PJ_TODO(CHECK_IF_REMOTE_SUPPORT_UPDATE);841 842 862 /* Remember our role in this transaction */ 843 863 inv->timer->role = PJSIP_ROLE_UAC; … … 846 866 inv->timer->active = PJ_TRUE; 847 867 start_timer(inv); 868 869 } else if (pjsip_method_cmp(&rdata->msg_info.cseq->method, 870 &pjsip_update_method) == 0 && 871 msg->line.status.code >= 400 && msg->line.status.code < 600) 872 { 873 /* This is to handle error response to previous UPDATE that was 874 * sent without SDP. In this case, retry sending UPDATE but 875 * with SDP this time. 876 * Note: the additional expressions are to check that the 877 * UPDATE was really the one sent by us, not by other 878 * call components (e.g. to change codec) 879 */ 880 if (inv->timer->timer.id == 0 && inv->timer->use_update && 881 inv->timer->with_sdp == PJ_FALSE) 882 { 883 inv->timer->with_sdp = PJ_TRUE; 884 timer_cb(NULL, &inv->timer->timer); 885 } 848 886 } 849 887
Note: See TracChangeset
for help on using the changeset viewer.