- Timestamp:
- Jun 21, 2010 1:28:55 PM (14 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r3208 r3215 2394 2394 2395 2395 /* Verify arguments. */ 2396 PJ_ASSERT_RETURN(inv && p_tdata && offer, PJ_EINVAL);2396 PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL); 2397 2397 2398 2398 /* Dialog must have been established */ … … 2407 2407 pjsip_dlg_inc_lock(inv->dlg); 2408 2408 2409 /* Process offer */ 2410 if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE) { 2411 PJ_LOG(4,(inv->dlg->obj_name, 2412 "Invalid SDP offer/answer state for UPDATE")); 2413 status = PJ_EINVALIDOP; 2414 goto on_error; 2415 } 2416 2417 /* Notify negotiator about the new offer. This will fix the offer 2418 * with correct SDP origin. 2419 */ 2420 status = pjmedia_sdp_neg_modify_local_offer(inv->pool_prov, inv->neg, 2421 offer); 2422 if (status != PJ_SUCCESS) 2423 goto on_error; 2424 2425 /* Retrieve the "fixed" offer from negotiator */ 2426 pjmedia_sdp_neg_get_neg_local(inv->neg, &offer); 2409 /* Process offer, if any */ 2410 if (offer) { 2411 if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE) { 2412 PJ_LOG(4,(inv->dlg->obj_name, 2413 "Invalid SDP offer/answer state for UPDATE")); 2414 status = PJ_EINVALIDOP; 2415 goto on_error; 2416 } 2417 2418 /* Notify negotiator about the new offer. This will fix the offer 2419 * with correct SDP origin. 2420 */ 2421 status = pjmedia_sdp_neg_modify_local_offer(inv->pool_prov, inv->neg, 2422 offer); 2423 if (status != PJ_SUCCESS) 2424 goto on_error; 2425 2426 /* Retrieve the "fixed" offer from negotiator */ 2427 pjmedia_sdp_neg_get_neg_local(inv->neg, &offer); 2428 } 2427 2429 2428 2430 /* Update Contact if required */ … … 2450 2452 2451 2453 /* Attach SDP body */ 2452 sdp_copy = pjmedia_sdp_session_clone(tdata->pool, offer); 2453 pjsip_create_sdp_body(tdata->pool, sdp_copy, &tdata->msg->body); 2454 if (offer) { 2455 sdp_copy = pjmedia_sdp_session_clone(tdata->pool, offer); 2456 pjsip_create_sdp_body(tdata->pool, sdp_copy, &tdata->msg->body); 2457 } 2454 2458 2455 2459 /* Unlock dialog. */ … … 2880 2884 else 2881 2885 { 2886 /* Session-Timer needs to see any error responses, to determine 2887 * whether peer supports UPDATE with empty body. 2888 */ 2889 if (tsx->state == PJSIP_TSX_STATE_COMPLETED && 2890 tsx->role == PJSIP_ROLE_UAC) 2891 { 2892 status = handle_timer_response(inv, e->body.tsx_state.src.rdata, 2893 PJ_FALSE); 2894 } 2895 2882 2896 tsx_inv_data = (struct tsx_inv_data*)tsx->mod_data[mod_inv.mod.id]; 2883 2897 if (tsx_inv_data == NULL) { -
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 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r3212 r3215 856 856 &pjsua_var.calls[id].med_rtp_addr)) 857 857 { 858 pj_bool_t use_update; 859 const pj_str_t STR_UPDATE = { "UPDATE", 6 }; 860 pjsip_dialog_cap_status support_update; 861 pjsip_dialog *dlg; 862 863 dlg = pjsua_var.calls[id].inv->dlg; 864 support_update = pjsip_dlg_remote_has_cap(dlg, PJSIP_H_ALLOW, 865 NULL, &STR_UPDATE); 866 use_update = (support_update == PJSIP_DIALOG_CAP_SUPPORTED); 867 858 868 PJ_LOG(4,(THIS_FILE, 859 869 "ICE default transport address has changed for " 860 "call %d, sending UPDATE", id)); 861 pjsua_call_update(id, 0, NULL); 870 "call %d, sending %s", id, 871 (use_update ? "UPDATE" : "re-INVITE"))); 872 873 if (use_update) 874 pjsua_call_update(id, 0, NULL); 875 else 876 pjsua_call_reinvite(id, 0, NULL); 862 877 } 863 878 }
Note: See TracChangeset
for help on using the changeset viewer.