summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsip/sip_transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip/src/pjsip/sip_transaction.c')
-rw-r--r--pjsip/src/pjsip/sip_transaction.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 4dc46520..fcf0646c 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -1396,6 +1396,23 @@ PJ_DEF(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,
/*
+ * Set the UAC absolute transaction timeout.
+ */
+PJ_DEF(pj_status_t) pjsip_tsx_set_uac_timeout(pjsip_transaction *tsx,
+ unsigned msec_time,
+ pjsip_tsx_timeout_policy policy)
+{
+ PJ_ASSERT_RETURN(tsx && tsx->role==PJSIP_ROLE_UAC &&
+ tsx->state==PJSIP_TSX_STATE_NULL, PJ_EINVALIDOP);
+
+ tsx->msec_timeout = msec_time;
+ tsx->timeout_policy = policy;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
* Set transaction status code and reason.
*/
static void tsx_set_status_code(pjsip_transaction *tsx,
@@ -1896,10 +1913,22 @@ static pj_status_t tsx_on_state_null( pjsip_transaction *tsx,
}
/* Start Timer B (or called timer F for non-INVITE) for transaction
- * timeout.
+ * timeout. If user has configured the timeout value with
+ * pjsip_tsx_set_uac_timeout(), use the timeout value there.
*/
- pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
- &timeout_timer_val);
+ if (tsx->msec_timeout > 0) {
+ pj_time_val timeout;
+
+ timeout.sec = tsx->msec_timeout / 1000;
+ timeout.msec = tsx->msec_timeout % 1000;
+
+ pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
+ &timeout);
+
+ } else {
+ pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
+ &timeout_timer_val);
+ }
/* Start Timer A (or timer E) for retransmission only if unreliable
* transport is being used.
@@ -1967,7 +1996,7 @@ static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,
} else if (event->type == PJSIP_EVENT_RX_MSG) {
pjsip_msg *msg;
- //int code;
+ int code;
/* Get message instance */
msg = event->body.rx_msg.rdata->msg_info.msg;
@@ -1984,8 +2013,18 @@ static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,
tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
- /* Cancel timer B (transaction timeout) */
- pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
+ /* Cancel timer B (transaction timeout) but look at the timeout policy
+ * as set by pjsip_tsx_set_uac_timeout().
+ */
+ code = msg->line.status.code;
+ if ((code==100 && tsx->timeout_policy==PJSIP_TSX_IGNORE_100) ||
+ (code<200 && tsx->timeout_policy==PJSIP_TSX_IGNORE_1xx))
+ {
+ /* Don't cancel the timeout timer */
+ }
+ else {
+ pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
+ }
/* Discard retransmission message if it is not INVITE.
* The INVITE tdata is needed in case we have to generate ACK for
@@ -2372,6 +2411,14 @@ static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,
PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
}
+ } else if (event->type == PJSIP_EVENT_TIMER &&
+ event->body.timer.entry == &tsx->timeout_timer) {
+
+ /* Inform TU. */
+ tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
+ PJSIP_EVENT_TIMER, &tsx->timeout_timer);
+
+
} else if (tsx->status_code >= 300 && tsx->status_code <= 699) {