Changeset 932


Ignore:
Timestamp:
Feb 5, 2007 6:59:31 PM (17 years ago)
Author:
bennylp
Message:

Fixed ticket #89: implement transaction timeout in REGISTER request (thanks Frank Wiersma for reporting the problem)

Location:
pjproject/trunk/pjsip
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip/sip_util.h

    r797 r932  
    427427 * @param timeout   Optional timeout for final response to be received, or -1  
    428428 *                  if the transaction should not have a timeout restriction. 
     429 *                  The value is in miliseconds. 
    429430 * @param token     Optional token to be associated with the transaction, and  
    430431 *                  to be passed to the callback. 
     
    438439PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt, 
    439440                                               pjsip_tx_data *tdata, 
    440                                                int timeout, 
     441                                               pj_int32_t timeout, 
    441442                                               void *token, 
    442443                                               void (*cb)(void*,pjsip_event*)); 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c

    r908 r932  
    3939#define THIS_FILE               "sip_regc.c" 
    4040 
     41/* Outgoing transaction timeout when server sends 100 but never replies 
     42 * with final response. Value is in MILISECONDS! 
     43 */ 
     44#define REGC_TSX_TIMEOUT        33000 
     45 
     46 
    4147/** 
    4248 * SIP client registration structure. 
     
    743749    regc->has_tsx = PJ_TRUE; 
    744750    ++regc->busy; 
    745     status = pjsip_endpt_send_request(regc->endpt, tdata, -1, regc, &tsx_callback); 
     751    status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT, 
     752                                      regc, &tsx_callback); 
    746753    if (status!=PJ_SUCCESS) { 
    747754        PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status)); 
  • pjproject/trunk/pjsip/src/pjsip/sip_util_statefull.c

    r777 r932  
    2323#include <pjsip/sip_event.h> 
    2424#include <pjsip/sip_errno.h> 
     25#include <pj/assert.h> 
     26#include <pj/log.h> 
    2527#include <pj/pool.h> 
    26 #include <pj/assert.h> 
     28#include <pj/string.h> 
    2729 
    2830struct tsx_data 
    2931{ 
     32    pj_time_val     delay; 
     33    pj_timer_entry  timeout_timer; 
     34 
    3035    void *token; 
    3136    void (*cb)(void*, pjsip_event*); 
     
    6772        return; 
    6873 
     74    /* Cancel timer if any */ 
     75    if (tsx_data->timeout_timer.id != 0) { 
     76        tsx_data->timeout_timer.id = 0; 
     77        pjsip_endpt_cancel_timer(tsx->endpt, &tsx_data->timeout_timer); 
     78    } 
     79 
    6980    /* Call the callback, if any, and prevent the callback to be called again 
    7081     * by clearing the transaction's module_data. 
     
    7889 
    7990 
     91static void mod_util_on_timeout(pj_timer_heap_t *th, pj_timer_entry *te) 
     92{ 
     93    pjsip_transaction *tsx = (pjsip_transaction*) te->user_data; 
     94    struct tsx_data *tsx_data; 
     95 
     96    PJ_UNUSED_ARG(th); 
     97 
     98    tsx_data = tsx->mod_data[mod_stateful_util.id]; 
     99    if (tsx_data == NULL) { 
     100        pj_assert(!"Shouldn't happen"); 
     101        return; 
     102    } 
     103 
     104    tsx_data->timeout_timer.id = 0; 
     105 
     106    PJ_LOG(4,(tsx->obj_name, "Transaction timed out by user timer (%d.%d sec)", 
     107              (int)tsx_data->delay.sec, (int)tsx_data->delay.msec)); 
     108 
     109    /* Terminate the transaction. This will call mod_util_on_tsx_state() */ 
     110    pjsip_tsx_terminate(tsx, PJSIP_SC_TSX_TIMEOUT); 
     111} 
     112 
     113 
    80114PJ_DEF(pj_status_t) pjsip_endpt_send_request(  pjsip_endpoint *endpt, 
    81115                                               pjsip_tx_data *tdata, 
    82                                                int timeout, 
     116                                               pj_int32_t timeout, 
    83117                                               void *token, 
    84118                                               void (*cb)(void*,pjsip_event*)) 
     
    100134    } 
    101135 
    102     tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct tsx_data)); 
     136    tsx_data = pj_pool_zalloc(tsx->pool, sizeof(struct tsx_data)); 
    103137    tsx_data->token = token; 
    104138    tsx_data->cb = cb; 
     139 
     140    if (timeout >= 0) { 
     141        tsx_data->delay.sec = 0; 
     142        tsx_data->delay.msec = timeout; 
     143        pj_time_val_normalize(&tsx_data->delay); 
     144 
     145        tsx_data->timeout_timer.id = PJ_TRUE; 
     146        tsx_data->timeout_timer.user_data = tsx; 
     147        tsx_data->timeout_timer.cb = &mod_util_on_timeout; 
     148         
     149        status = pjsip_endpt_schedule_timer(endpt, &tsx_data->timeout_timer,  
     150                                            &tsx_data->delay); 
     151        if (status != PJ_SUCCESS) { 
     152            pjsip_tsx_terminate(tsx, PJSIP_SC_INTERNAL_SERVER_ERROR); 
     153            pjsip_tx_data_dec_ref(tdata); 
     154            return status; 
     155        } 
     156    } 
     157 
    105158    tsx->mod_data[mod_stateful_util.id] = tsx_data; 
    106159 
    107     PJ_TODO(IMPLEMENT_TIMEOUT_FOR_SEND_REQUEST); 
    108  
    109160    status = pjsip_tsx_send_msg(tsx, NULL); 
    110     if (status != PJ_SUCCESS) 
    111         pjsip_tx_data_dec_ref(tdata); 
     161    if (status != PJ_SUCCESS) { 
     162        if (tsx_data->timeout_timer.id != 0) { 
     163            pjsip_endpt_cancel_timer(endpt, &tsx_data->timeout_timer); 
     164            tsx_data->timeout_timer.id = PJ_FALSE; 
     165        } 
     166        pjsip_tx_data_dec_ref(tdata); 
     167    } 
    112168 
    113169    return status; 
Note: See TracChangeset for help on using the changeset viewer.