Changeset 4715


Ignore:
Timestamp:
Jan 24, 2014 9:32:27 AM (7 years ago)
Author:
riza
Message:

Re #1722:

  • add handler for 502/503 response to refresh request.
  • add expire timer for refresher.
Location:
pjproject/trunk/pjsip
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip-ua/sip_timer.h

    r3553 r4715  
    201201                                              pjsip_status_code *st_code); 
    202202 
     203/** 
     204 * Process Session Timers refresh error, this function will process 
     205 * error from refresh request. The error will be handle according the 
     206 * error code, i.e : BYE will be sent after error 503 (Transport Error). 
     207 * 
     208 * @param inv            The invite session. 
     209 * @param event          The event that trigger the error. 
     210 * 
     211 * @return               PJ_SUCCESS on successful. 
     212 */ 
     213PJ_DECL(pj_status_t)  pjsip_timer_handle_refresh_error( 
     214                                            pjsip_inv_session *inv, 
     215                                            pjsip_event *event); 
    203216 
    204217/** 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r4713 r4715  
    33353335        handled = PJ_TRUE; 
    33363336    } 
     3337 
     3338    /* Process 502/503 error */ 
     3339    else if ((tsx->state == PJSIP_TSX_STATE_TERMINATED) && 
     3340             (tsx->status_code == 503 || tsx->status_code == 502)) 
     3341    { 
     3342        status = pjsip_timer_handle_refresh_error(inv, e); 
     3343 
     3344        handled = PJ_TRUE; 
     3345    } 
    33373346     
    33383347    /* Get/attach invite session's transaction data */ 
     
    36073616        return PJ_TRUE; /* Handled */ 
    36083617 
    3609     } else { 
     3618    }  
     3619    /* Process 502/503 error */ 
     3620    else if ((tsx->state == PJSIP_TSX_STATE_TERMINATED) && 
     3621             (tsx->status_code == 503 || tsx->status_code == 502)) 
     3622    { 
     3623        pjsip_timer_handle_refresh_error(inv, e); 
     3624 
     3625        return PJ_TRUE; 
     3626    }     
     3627    else { 
    36103628        return PJ_FALSE; /* Unhandled */ 
    36113629    } 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_timer.c

    r4695 r4715  
    2020#include <pjsip/print_util.h> 
    2121#include <pjsip/sip_endpoint.h> 
     22#include <pjsip/sip_event.h> 
     23#include <pjsip/sip_transaction.h> 
    2224#include <pj/log.h> 
    2325#include <pj/math.h> 
     
    2931 
    3032/* Constant of Session Timers */ 
    31 #define ABS_MIN_SE              90      /* Absolute Min-SE, in seconds      */ 
    32  
     33#define ABS_MIN_SE                  90  /* Absolute Min-SE, in seconds      */ 
     34#define REFRESHER_EXPIRE_TIMER_ID   2   /* Refresher expire timer id        */  
    3335 
    3436/* String definitions */ 
     
    6264    pj_bool_t                    with_sdp;      /**< SDP in UPDATE?         */ 
    6365    pjsip_role_e                 role;          /**< Role in last INVITE/ 
    64                                                      UPDATE transaction.    */ 
    65  
     66                                                     UPDATE transaction.    */     
     67    void                        *refresh_tdata; /**< The tdata of refresh  
     68                                                     request                */ 
     69    pj_timer_entry               expire_timer;  /**< Timer entry for expire  
     70                                                     refresher              */ 
    6671}; 
    6772 
     
    332337    pj_assert(inv); 
    333338 
    334     inv->timer->timer.id = 0; 
    335  
    336339    PJ_UNUSED_ARG(timer_heap); 
    337340 
     
    342345    as_refresher = 
    343346        (inv->timer->refresher == TR_UAC && inv->timer->role == PJSIP_ROLE_UAC) || 
    344         (inv->timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS); 
    345  
    346     /* Do action based on role, refresher or refreshee */ 
    347     if (as_refresher) { 
     347        (inv->timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS);     
     348 
     349    /* Do action based on role(refresher or refreshee).  
     350     * As refresher: 
     351     * - send refresh, or   
     352     * - end session if there is no response to the refresh request. 
     353     * As refreshee: 
     354     * - end session if there is no refresh request received. 
     355     */ 
     356    if (as_refresher && (entry->id != REFRESHER_EXPIRE_TIMER_ID)) { 
    348357        pj_time_val now; 
    349358 
    350359        /* As refresher, reshedule the refresh request on the following: 
    351          *  - msut not send re-INVITE if another INVITE or SDP negotiation 
     360         *  - must not send re-INVITE if another INVITE or SDP negotiation 
    352361         *    is in progress. 
    353362         *  - must not send UPDATE with SDP if SDP negotiation is in progress 
    354363         */ 
    355364        pjmedia_sdp_neg_state neg_state = pjmedia_sdp_neg_get_state(inv->neg); 
     365 
     366        inv->timer->timer.id = 0; 
     367 
    356368        if ( (!inv->timer->use_update && ( 
    357369                        inv->invite_tsx != NULL || 
     
    411423        pj_time_val now; 
    412424 
    413         /* Refreshee, terminate the session */ 
     425        if (as_refresher) 
     426            inv->timer->expire_timer.id = 0; 
     427        else 
     428            inv->timer->timer.id = 0; 
     429 
     430        /* Terminate the session */ 
    414431        status = pjsip_inv_end_session(inv, PJSIP_SC_REQUEST_TIMEOUT,  
    415432                                       NULL, &tdata); 
     
    417434        pj_gettimeofday(&now); 
    418435        PJ_LOG(3, (inv->pool->obj_name,  
    419                    "No session refresh received after %ds " 
     436                   "No session %s received after %ds " 
    420437                   "(expiration period=%ds), stopping session now!", 
     438                   (as_refresher?"refresh response":"refresh"), 
    421439                   (now.sec-inv->timer->last_refresh.sec), 
    422440                   inv->timer->setting.sess_expires)); 
     441 
    423442    } 
    424443 
     
    428447    /* Send message, if any */ 
    429448    if (tdata && status == PJ_SUCCESS) { 
    430         status = pjsip_inv_send_msg(inv, tdata); 
     449        inv->timer->refresh_tdata = tdata; 
     450 
     451        status = pjsip_inv_send_msg(inv, tdata);         
    431452    } 
    432453 
     
    434455    if (status != PJ_SUCCESS) { 
    435456        PJ_PERROR(2, (inv->pool->obj_name, status, 
    436                       "Error in %s session timer", 
    437                       (as_refresher? "refreshing" : "terminating"))); 
     457                     "Error in %s session timer", 
     458                     ((as_refresher && entry->id != REFRESHER_EXPIRE_TIMER_ID)?  
     459                       "refreshing" : "terminating"))); 
    438460    } 
    439461} 
     
    467489        (timer->refresher == TR_UAS && inv->timer->role == PJSIP_ROLE_UAS)) 
    468490    { 
     491        /* Add refresher expire timer */ 
     492        pj_timer_entry_init(&timer->expire_timer, 
     493                            REFRESHER_EXPIRE_TIMER_ID,      /* id */ 
     494                            inv,                            /* user data */ 
     495                            timer_cb);                      /* callback */ 
     496 
     497        delay.sec = timer->setting.sess_expires; 
     498        /* Schedule the timer */ 
     499        pjsip_endpt_schedule_timer(inv->dlg->endpt, &timer->expire_timer,  
     500                                   &delay); 
     501 
    469502        /* Next refresh, the delay is half of session expire */ 
    470503        delay.sec = timer->setting.sess_expires / 2; 
     
    491524    if (inv->timer->timer.id != 0) { 
    492525        pjsip_endpt_cancel_timer(inv->dlg->endpt, &inv->timer->timer); 
    493         inv->timer->timer.id = 0; 
     526        inv->timer->timer.id = 0;        
     527    } 
     528 
     529    if (inv->timer->expire_timer.id != 0) { 
     530        pjsip_endpt_cancel_timer(inv->dlg->endpt, &inv->timer->expire_timer); 
     531        inv->timer->expire_timer.id = 0; 
    494532    } 
    495533} 
     
    710748        return PJ_SUCCESS; 
    711749    } 
    712  
     750     
    713751    if (msg->line.status.code == PJSIP_SC_SESSION_TIMER_TOO_SMALL) { 
    714752        /* Our Session-Expires is too small, let's update it based on 
     
    887925            inv->timer->with_sdp = PJ_TRUE; 
    888926            timer_cb(NULL, &inv->timer->timer); 
     927        } 
     928    } 
     929 
     930    return PJ_SUCCESS; 
     931} 
     932 
     933PJ_DEF(pj_status_t)  pjsip_timer_handle_refresh_error( 
     934                                            pjsip_inv_session *inv, 
     935                                            pjsip_event *event) 
     936{     
     937    PJ_ASSERT_RETURN(inv && event, PJ_EINVAL); 
     938 
     939    /* Check if Session Timers is supported */ 
     940    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0) 
     941        return PJ_SUCCESS;     
     942 
     943    pj_assert(is_initialized); 
     944 
     945    if (inv->timer && inv->timer->active) { 
     946        pj_bool_t as_refresher; 
     947 
     948        /* Check our role */ 
     949        as_refresher = ((inv->timer->refresher == TR_UAC) &&  
     950                        (inv->timer->role == PJSIP_ROLE_UAC)) || 
     951                       ((inv->timer->refresher == TR_UAS) &&  
     952                        (inv->timer->role == PJSIP_ROLE_UAS)); 
     953 
     954 
     955        if ((as_refresher) && (event->type == PJSIP_EVENT_TSX_STATE) &&  
     956            (inv->timer->refresh_tdata == event->body.tsx_state.tsx->last_tx))  
     957        { 
     958            pjsip_status_code st_code; 
     959            pjsip_tx_data *bye; 
     960            pj_status_t status; 
     961 
     962            st_code =  
     963                    (pjsip_status_code)event->body.tsx_state.tsx->status_code; 
     964 
     965            PJ_LOG(3, (inv->pool->obj_name,  
     966                        "Receive error %d for refresh request %.*s/cseq=%d, " 
     967                        "stopping session now", st_code,  
     968                        event->body.tsx_state.tsx->method.name.slen, 
     969                        event->body.tsx_state.tsx->method.name.ptr, 
     970                        event->body.tsx_state.tsx->cseq)); 
     971 
     972            status = pjsip_inv_end_session(inv,  
     973                                    event->body.tsx_state.tsx->status_code,  
     974                                    pjsip_get_status_text(st_code),  
     975                                    &bye); 
     976 
     977            if (status == PJ_SUCCESS && bye) 
     978                status = pjsip_inv_send_msg(inv, bye); 
     979 
    889980        } 
    890981    } 
Note: See TracChangeset for help on using the changeset viewer.