- Timestamp:
- Feb 13, 2007 2:52:37 AM (18 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip/sip_transaction.h
r882 r942 75 75 76 76 /** 77 * Transaction timeout timer policy, to control the UAC transaction timeout 78 * scheduling (see #pjsip_tsx_set_uac_timeout()). 79 */ 80 typedef enum pjsip_tsx_timeout_policy 81 { 82 PJSIP_TSX_IGNORE_100 = 1, /**< To make the UAC transaction NOT to cancel 83 the timeout timer when 100 response is 84 received.*/ 85 PJSIP_TSX_IGNORE_1xx = 3 /**< To make the UAC transaction NOT to cancel 86 the timeout timer when any 1xx responses 87 are received. */ 88 } pjsip_tsx_timeout_policy; 89 90 91 /** 77 92 * This structure describes SIP transaction object. The transaction object 78 93 * is used to handle both UAS and UAC transaction. … … 131 146 pj_timer_entry timeout_timer; /**< Timeout timer. */ 132 147 148 unsigned msec_timeout; /**< User set timeout. */ 149 pjsip_tsx_timeout_policy timeout_policy; /**< Timeout policy. */ 150 133 151 /** Module specific data. */ 134 152 void *mod_data[PJSIP_MAX_MODULE]; … … 233 251 234 252 /** 253 * Set the UAC absolute transaction timeout. Normally UAC transaction will 254 * stop its timeout timer (timer B for INVITE and timer F for non-INVITE 255 * transactions) after a provisional response is received. 256 * 257 * When this timer is set, the transaction's timer B and F will use this 258 * value, and if the \a flag flag is set, the transaction will continue 259 * the scheduling of the timeout timer even when provisional response has 260 * been received. 261 * 262 * Note that this function MUST be called AFTER the transaction has been 263 * created AND BEFORE any request is transmitted. 264 * 265 * @param tsx The client/UAC transaction. 266 * @param msec_time The timeout value, in miliseconds. Currently this 267 * value must be non-zero (value zero is reserved for 268 * future use). 269 * @param flag Option flags to control whether the transaction should 270 * cancel the timeout timer on arrival of provisional 271 * responses (which is yes according to RFC 3261). 272 * The valid values are: 273 * - PJSIP_TSX_IGNORE_100, to make the UAC transaction 274 * NOT to cancel the timeout timer when 100 response 275 * is received. 276 * - PJSIP_TSX_IGNORE_1xx, to make the UAC transaction 277 * NOT to cancel the timeout timer when any 1xx 278 * responses are received. 279 * 280 * Note that regardless of the values in the \a flag 281 * argument, the provisional response would still be 282 * delivered to transaction user and it will still 283 * affect the transaction state. The \a flag flag only 284 * changes the behavior of the timeout timer of the 285 * transaction. 286 */ 287 PJ_DECL(pj_status_t) pjsip_tsx_set_uac_timeout(pjsip_transaction *tsx, 288 unsigned msec_time, 289 pjsip_tsx_timeout_policy flag); 290 291 292 /** 235 293 * Call this function to manually feed a message to the transaction. 236 294 * For UAS transaction, application MUST call this function after -
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r882 r942 1397 1397 1398 1398 /* 1399 * Set the UAC absolute transaction timeout. 1400 */ 1401 PJ_DEF(pj_status_t) pjsip_tsx_set_uac_timeout(pjsip_transaction *tsx, 1402 unsigned msec_time, 1403 pjsip_tsx_timeout_policy policy) 1404 { 1405 PJ_ASSERT_RETURN(tsx && tsx->role==PJSIP_ROLE_UAC && 1406 tsx->state==PJSIP_TSX_STATE_NULL, PJ_EINVALIDOP); 1407 1408 tsx->msec_timeout = msec_time; 1409 tsx->timeout_policy = policy; 1410 1411 return PJ_SUCCESS; 1412 } 1413 1414 1415 /* 1399 1416 * Set transaction status code and reason. 1400 1417 */ … … 1897 1914 1898 1915 /* Start Timer B (or called timer F for non-INVITE) for transaction 1899 * timeout. 1916 * timeout. If user has configured the timeout value with 1917 * pjsip_tsx_set_uac_timeout(), use the timeout value there. 1900 1918 */ 1901 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 1902 &timeout_timer_val); 1919 if (tsx->msec_timeout > 0) { 1920 pj_time_val timeout; 1921 1922 timeout.sec = tsx->msec_timeout / 1000; 1923 timeout.msec = tsx->msec_timeout % 1000; 1924 1925 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 1926 &timeout); 1927 1928 } else { 1929 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 1930 &timeout_timer_val); 1931 } 1903 1932 1904 1933 /* Start Timer A (or timer E) for retransmission only if unreliable … … 1968 1997 } else if (event->type == PJSIP_EVENT_RX_MSG) { 1969 1998 pjsip_msg *msg; 1970 //int code;1999 int code; 1971 2000 1972 2001 /* Get message instance */ … … 1985 2014 1986 2015 1987 /* Cancel timer B (transaction timeout) */ 1988 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 2016 /* Cancel timer B (transaction timeout) but look at the timeout policy 2017 * as set by pjsip_tsx_set_uac_timeout(). 2018 */ 2019 code = msg->line.status.code; 2020 if ((code==100 && tsx->timeout_policy==PJSIP_TSX_IGNORE_100) || 2021 (code<200 && tsx->timeout_policy==PJSIP_TSX_IGNORE_1xx)) 2022 { 2023 /* Don't cancel the timeout timer */ 2024 } 2025 else { 2026 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 2027 } 1989 2028 1990 2029 /* Discard retransmission message if it is not INVITE. … … 2373 2412 } 2374 2413 2414 } else if (event->type == PJSIP_EVENT_TIMER && 2415 event->body.timer.entry == &tsx->timeout_timer) { 2416 2417 /* Inform TU. */ 2418 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2419 PJSIP_EVENT_TIMER, &tsx->timeout_timer); 2420 2421 2375 2422 } else if (tsx->status_code >= 300 && tsx->status_code <= 699) { 2376 2423 -
pjproject/trunk/pjsip/src/pjsip/sip_util_statefull.c
r932 r942 30 30 struct tsx_data 31 31 { 32 pj_time_val delay;33 pj_timer_entry timeout_timer;34 35 32 void *token; 36 33 void (*cb)(void*, pjsip_event*); … … 72 69 return; 73 70 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 80 71 /* Call the callback, if any, and prevent the callback to be called again 81 72 * by clearing the transaction's module_data. … … 86 77 (*tsx_data->cb)(tsx_data->token, event); 87 78 } 88 }89 90 91 static 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 79 } 112 80 … … 134 102 } 135 103 136 tsx_data = pj_pool_ zalloc(tsx->pool, sizeof(struct tsx_data));104 tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct tsx_data)); 137 105 tsx_data->token = token; 138 106 tsx_data->cb = cb; 139 107 140 108 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 } 109 status = pjsip_tsx_set_uac_timeout(tsx, timeout, PJSIP_TSX_IGNORE_1xx); 110 pj_assert(status == PJ_SUCCESS); 156 111 } 157 112 … … 159 114 160 115 status = pjsip_tsx_send_msg(tsx, NULL); 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 } 116 if (status != PJ_SUCCESS) 166 117 pjsip_tx_data_dec_ref(tdata); 167 }168 118 169 119 return status;
Note: See TracChangeset
for help on using the changeset viewer.