[asterisk-commits] oej: branch oej/teapot-1.8 r402921 - in /team/oej/teapot-1.8: channels/ chann...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Nov 21 07:29:39 CST 2013
Author: oej
Date: Thu Nov 21 07:29:37 2013
New Revision: 402921
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=402921
Log:
Adding timer C
Added:
team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff (with props)
Modified:
team/oej/teapot-1.8/channels/chan_sip.c
team/oej/teapot-1.8/channels/sip/include/sip.h
team/oej/teapot-1.8/configs/sip.conf.sample
Modified: team/oej/teapot-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/channels/chan_sip.c?view=diff&rev=402921&r1=402920&r2=402921
==============================================================================
--- team/oej/teapot-1.8/channels/chan_sip.c (original)
+++ team/oej/teapot-1.8/channels/chan_sip.c Thu Nov 21 07:29:37 2013
@@ -740,6 +740,7 @@
static int global_t1; /*!< T1 time */
static int global_t1min; /*!< T1 roundtrip time minimum */
static int global_timer_b; /*!< Timer B - RFC 3261 Section 17.1.1.2 */
+static int global_timer_c; /*!< Timer C - RFC 3261 Section 16.6 */
static unsigned int global_autoframing; /*!< Turn autoframing on or off. */
static int global_qualifyfreq; /*!< Qualify frequency */
static int global_qualify_gap; /*!< Time between our group of peer pokes */
@@ -1290,6 +1291,7 @@
static void *registry_unref(struct sip_registry *reg, char *tag);
static int update_call_counter(struct sip_pvt *fup, int event);
static int auto_congest(const void *arg);
+static int dialog_proceeding_timeout(const void *arg);
static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method);
static void free_old_route(struct sip_route *route);
static void list_route(struct sip_route *route);
@@ -4280,6 +4282,9 @@
if (p->timer_b == 0) {
p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */
}
+ if (p->timer_c == 0) {
+ p->timer_c = global_timer_c; /* Set timer C if not set (RFC 3261) */
+ }
ms = p->timer_t1 * 64;
}
if (sip_debug_test_pvt(p)) {
@@ -5798,6 +5803,12 @@
else
dialog->timer_b = 64 * dialog->timer_t1;
+ if (peer->timer_c) {
+ dialog->timer_c = peer->timer_c;
+ } else {
+ dialog->timer_c = global_timer_c;
+ }
+
if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
(ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
dialog->noncodeccapability |= AST_RTP_DTMF;
@@ -5852,6 +5863,7 @@
dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
+ dialog->timer_c = global_timer_c; /* Default SIP transaction timer C (RFC 3261) */
peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
if (peer) {
@@ -5956,6 +5968,30 @@
return 0;
}
+/*! \brief Scheduled congestion on a call when no responses has been received for 3 minutes (or configured)
+ * Only called by the scheduler, must return the reference when done.
+ */
+static int dialog_proceeding_timeout(const void *arg)
+{
+ struct sip_pvt *p = (struct sip_pvt *)arg;
+
+ sip_pvt_lock(p);
+ p->timercid = -1; /* event gone, will not be rescheduled */
+ if (p->owner) {
+ /* XXX fails on possible deadlock */
+ if (!ast_channel_trylock(p->owner)) {
+ append_history(p, "Cong", "Auto-congesting (timer C)");
+ ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+ ast_channel_unlock(p->owner);
+ }
+
+ /* Give the channel a chance to act before we proceed with destruction */
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ }
+ sip_pvt_unlock(p);
+ dialog_unref(p, "unreffing arg passed into timer C callback (p->timerc)");
+ return 0;
+}
/*! \brief Initiate SIP call from PBX
* used from the dial() application */
@@ -8075,6 +8111,7 @@
p->rtcpeventid = -1;
p->initid = -1;
p->waitid = -1;
+ p->timercid = -1;
p->reinviteid = -1;
p->autokillid = -1;
p->request_queue_sched_id = -1;
@@ -8091,6 +8128,7 @@
if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */
p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
+ p->timer_c = global_timer_c; /* Default SIP transaction timer B (RFC 3261) */
}
if (!addr) {
@@ -16758,6 +16796,11 @@
p->timer_b = peer->timer_b;
else
p->timer_b = 64 * p->timer_t1;
+ /* Set timer C to control transaction timeouts */
+ if (peer->timer_c)
+ p->timer_c = peer->timer_c;
+ else
+ p->timer_c = global_timer_c;
p->allowtransfer = peer->allowtransfer;
@@ -18320,6 +18363,7 @@
ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1);
ast_cli(fd, " Timer B : %d\n", peer->timer_b);
+ ast_cli(fd, " Timer C : %d\n", peer->timer_c);
ast_cli(fd, " ToHost : %s\n", peer->tohost);
ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr));
ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr));
@@ -18598,6 +18642,7 @@
"__sip_autodestruct",
"expire_register",
"auto_congest",
+ "dialog_proceeding_timeout",
"sip_reg_timeout",
"sip_poke_peer_s",
"sip_poke_noanswer",
@@ -18607,6 +18652,7 @@
__sip_autodestruct,
expire_register,
auto_congest,
+ dialog_proceeding_timeout,
sip_reg_timeout,
sip_poke_peer_s,
sip_poke_noanswer,
@@ -19029,6 +19075,7 @@
ast_cli(a->fd, " Timer T1: %d\n", global_t1);
ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min);
ast_cli(a->fd, " Timer B: %d\n", global_timer_b);
+ ast_cli(a->fd, " Timer C: %d\n", global_timer_c);
ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter));
ast_cli(a->fd, " Early media focus: %s\n", AST_CLI_YESNO(sip_cfg.early_media_focus));
ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards);
@@ -20893,8 +20940,27 @@
resp = 183;
/* Any response between 100 and 199 is PROCEEDING */
- if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
+ if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) {
p->invitestate = INV_PROCEEDING;
+ if (p->timercid == -1) {
+ /* Trigger timer C */
+ AST_SCHED_REPLACE_UNREF(p->timercid, sched, p->timer_c, dialog_proceeding_timeout, p,
+ dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"),
+ dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
+ dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
+ ast_debug(3, "Setting Timer C to %d \n", p->timer_c);
+ }
+ }
+
+ if (resp >= 200) {
+ /* Delete timer C - we have a response */
+ AST_SCHED_DEL_UNREF(sched, p->timercid, dialog_unref(p, "when you delete the timercid sched, you should dec the refcount for the stored dialog ptr"));
+ ast_debug(3, "Deleting Timer C (response received)\n");
+ } else {
+ /* reset timer C */
+ AST_SCHED_REPLACE_VARIABLE(p->timercid, sched, p->timer_c, dialog_proceeding_timeout, p, 1);
+ ast_debug(3, "Resetting Timer C to %d \n", p->timer_c);
+ }
/* Final response, not 200 ? */
if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
@@ -28267,6 +28333,7 @@
peer->stimer.st_max_se = global_max_se;
peer->timer_t1 = global_t1;
peer->timer_b = global_timer_b;
+ peer->timer_c = global_timer_c;
clear_peer_mailboxes(peer);
peer->disallowed_methods = sip_cfg.disallowed_methods;
peer->transports = default_transports;
@@ -28357,7 +28424,7 @@
int firstpass = 1;
uint16_t port = 0;
int format = 0; /* Ama flags */
- int timerb_set = 0, timert1_set = 0;
+ int timerb_set = 0, timert1_set = 0, timerc_set = 0;
time_t regseconds = 0;
struct ast_flags peerflags[3] = {{(0)}};
struct ast_flags mask[3] = {{(0)}};
@@ -28710,6 +28777,12 @@
peer->timer_b = global_timer_b;
}
timerb_set = 1;
+ } else if (!strcasecmp(v->name, "timerc")) {
+ if ((sscanf(v->value, "%30d", &peer->timer_c) != 1) || (peer->timer_c > 100)) {
+ ast_log(LOG_WARNING, "'%s' is not a valid Timer C time at line %d (above 100, default 180 s). Using configured default %d.\n", v->value, v->lineno, global_timer_c);
+ peer->timer_c = global_timer_c;
+ }
+ timerc_set = 1;
} else if (!strcasecmp(v->name, "setvar")) {
peer->chanvars = add_var(v->value, peer->chanvars);
} else if (!strcasecmp(v->name, "header")) {
@@ -29286,6 +29359,7 @@
global_authfailureevents = FALSE;
global_t1 = DEFAULT_TIMER_T1;
global_timer_b = 64 * DEFAULT_TIMER_T1;
+ global_timer_c = 180; /* 3 minutes per RFC 3261 */
global_t1min = DEFAULT_T1MIN;
global_qualifyfreq = DEFAULT_QUALIFYFREQ;
global_t38_maxdatagram = -1;
@@ -29371,6 +29445,12 @@
ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b);
}
timerb_set = 1;
+ } else if (!strcasecmp(v->name, "timerc")) {
+ int tmp = atoi(v->value);
+ if (tmp < 100) {
+ global_timer_c = DEFAULT_TIMER_C;
+ ast_log(LOG_WARNING, "Invalid value (< 100 s) for timerc ('%s'). Setting to default ('%d').\n", v->value, global_timer_c);
+ }
} else if (!strcasecmp(v->name, "t1min")) {
global_t1min = atoi(v->value);
} else if (!strcasecmp(v->name, "transport")) {
@@ -31973,7 +32053,8 @@
MEMBER(sip_peer, maxms, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, qualifyfreq, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, timer_t1, AST_DATA_MILLISECONDS) \
- MEMBER(sip_peer, timer_b, AST_DATA_MILLISECONDS)
+ MEMBER(sip_peer, timer_b, AST_DATA_MILLISECONDS) \
+ MEMBER(sip_peer, timer_c, AST_DATA_SECONDS)
AST_DATA_STRUCTURE(sip_peer, DATA_EXPORT_SIP_PEER);
Modified: team/oej/teapot-1.8/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/channels/sip/include/sip.h?view=diff&rev=402921&r1=402920&r2=402921
==============================================================================
--- team/oej/teapot-1.8/channels/sip/include/sip.h (original)
+++ team/oej/teapot-1.8/channels/sip/include/sip.h Thu Nov 21 07:29:37 2013
@@ -87,6 +87,7 @@
#define DEFAULT_RETRANS 1000 /*!< How frequently to retransmit Default: 2 * 500 ms in RFC 3261 */
#define DEFAULT_TIMER_T1 500 /*!< SIP timer T1 (according to RFC 3261) */
+#define DEFAULT_TIMER_C 180 /*!< SIP timer C (according to RFC 3261) */
#define SIP_TRANS_TIMEOUT 64 * DEFAULT_TIMER_T1 /*!< SIP request timeout (rfc 3261) 64*T1
* \todo Use known T1 for timeout (peerpoke)
*/
@@ -1036,6 +1037,7 @@
unsigned short req_secure_signaling:1;/*!< Whether we are required to have secure signaling or not */
int timer_t1; /*!< SIP timer T1, ms rtt */
int timer_b; /*!< SIP timer B, ms */
+ int timer_c; /*!< SIP timer B, ms */
unsigned int sipoptions; /*!< Supported SIP options on the other end */
unsigned int reqsipoptions; /*!< Required SIP options on the other end */
struct ast_codec_pref prefs; /*!< codec prefs */
@@ -1096,6 +1098,7 @@
int initid; /*!< Auto-congest ID if appropriate (scheduler) */
int waitid; /*!< Wait ID for scheduler after 491 or other delays */
+ int timercid; /*!< Scheduler ID for timer C delays */
int reinviteid; /*!< Reinvite in case of provisional, but no final response */
int autokillid; /*!< Auto-kill ID (scheduler) */
int rtcpeventid; /*!< Scheduler ID for RTCP Events */
@@ -1297,6 +1300,7 @@
struct sip_st_cfg stimer; /*!< SIP Session-Timers */
int timer_t1; /*!< The maximum T1 value for the peer */
int timer_b; /*!< The maximum timer B (transaction timeouts) */
+ int timer_c; /*!< The timer c (transaction timeouts) */
int fromdomainport; /*!< The From: domain port */
/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
Modified: team/oej/teapot-1.8/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/configs/sip.conf.sample?view=diff&rev=402921&r1=402920&r2=402921
==============================================================================
--- team/oej/teapot-1.8/configs/sip.conf.sample (original)
+++ team/oej/teapot-1.8/configs/sip.conf.sample Thu Nov 21 07:29:37 2013
@@ -534,9 +534,13 @@
;timert1=500 ; Default T1 timer
; Defaults to 500 ms or the measured round-trip
; time to a peer (qualify=yes).
-;timerb=32000 ; Call setup timer. If a provisional response is not received
+;timerb=32000 ; Call setup timer. If a final response is not received
; in this amount of time, the call will autocongest
; Defaults to 64*timert1
+;timerc=420 ; Call setup timer. If a provisional response is not received
+ ; during this time - the call will autocongest. Default 180 secs.
+ ; Needs to be higher than 100. RFC says MUST be higher than
+ ; or equal to 180.
;--------------------------- RTP timers ----------------------------------------------------
; These timers are currently used for both audio and video streams. The RTP timeouts
Added: team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff?view=auto&rev=402921
==============================================================================
--- team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff (added)
+++ team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff Thu Nov 21 07:29:37 2013
@@ -1,0 +1,331 @@
+Index: channels/chan_sip.c
+===================================================================
+--- channels/chan_sip.c (.../branches/1.8) (revision 402920)
++++ channels/chan_sip.c (.../team/oej/grape-sip-timeout-pdd-1.8) (revision 402920)
+@@ -736,6 +736,7 @@
+ static int global_t1; /*!< T1 time */
+ static int global_t1min; /*!< T1 roundtrip time minimum */
+ static int global_timer_b; /*!< Timer B - RFC 3261 Section 17.1.1.2 */
++static int global_timer_c; /*!< Timer C - RFC 3261 Section 16.6 */
+ static unsigned int global_autoframing; /*!< Turn autoframing on or off. */
+ static int global_qualifyfreq; /*!< Qualify frequency */
+ static int global_qualify_gap; /*!< Time between our group of peer pokes */
+@@ -1285,6 +1286,7 @@
+ static void *registry_unref(struct sip_registry *reg, char *tag);
+ static int update_call_counter(struct sip_pvt *fup, int event);
+ static int auto_congest(const void *arg);
++static int dialog_proceeding_timeout(const void *arg);
+ static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method);
+ static void free_old_route(struct sip_route *route);
+ static void list_route(struct sip_route *route);
+@@ -4271,6 +4273,9 @@
+ if (p->timer_b == 0) {
+ p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */
+ }
++ if (p->timer_c == 0) {
++ p->timer_c = global_timer_c; /* Set timer C if not set (RFC 3261) */
++ }
+ ms = p->timer_t1 * 64;
+ }
+ if (sip_debug_test_pvt(p)) {
+@@ -5756,6 +5761,12 @@
+ else
+ dialog->timer_b = 64 * dialog->timer_t1;
+
++ if (peer->timer_c) {
++ dialog->timer_c = peer->timer_c;
++ } else {
++ dialog->timer_c = global_timer_c;
++ }
++
+ if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
+ (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
+ dialog->noncodeccapability |= AST_RTP_DTMF;
+@@ -5806,6 +5817,7 @@
+
+ dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
+ dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
++ dialog->timer_c = global_timer_c; /* Default SIP transaction timer C (RFC 3261) */
+ peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
+
+ if (peer) {
+@@ -5910,7 +5922,31 @@
+ return 0;
+ }
+
++/*! \brief Scheduled congestion on a call when no responses has been received for 3 minutes (or configured)
++ * Only called by the scheduler, must return the reference when done.
++ */
++static int dialog_proceeding_timeout(const void *arg)
++{
++ struct sip_pvt *p = (struct sip_pvt *)arg;
+
++ sip_pvt_lock(p);
++ p->timercid = -1; /* event gone, will not be rescheduled */
++ if (p->owner) {
++ /* XXX fails on possible deadlock */
++ if (!ast_channel_trylock(p->owner)) {
++ append_history(p, "Cong", "Auto-congesting (timer C)");
++ ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
++ ast_channel_unlock(p->owner);
++ }
++
++ /* Give the channel a chance to act before we proceed with destruction */
++ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++ }
++ sip_pvt_unlock(p);
++ dialog_unref(p, "unreffing arg passed into timer C callback (p->timerc)");
++ return 0;
++}
++
+ /*! \brief Initiate SIP call from PBX
+ * used from the dial() application */
+ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
+@@ -8160,6 +8196,7 @@
+ p->method = intended_method;
+ p->initid = -1;
+ p->waitid = -1;
++ p->timercid = -1;
+ p->reinviteid = -1;
+ p->autokillid = -1;
+ p->request_queue_sched_id = -1;
+@@ -8176,6 +8213,7 @@
+ if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */
+ p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
+ p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
++ p->timer_c = global_timer_c; /* Default SIP transaction timer B (RFC 3261) */
+ }
+
+ if (!addr) {
+@@ -16702,6 +16740,11 @@
+ p->timer_b = peer->timer_b;
+ else
+ p->timer_b = 64 * p->timer_t1;
++ /* Set timer C to control transaction timeouts */
++ if (peer->timer_c)
++ p->timer_c = peer->timer_c;
++ else
++ p->timer_c = global_timer_c;
+
+ p->allowtransfer = peer->allowtransfer;
+
+@@ -18257,6 +18300,7 @@
+ ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
+ ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1);
+ ast_cli(fd, " Timer B : %d\n", peer->timer_b);
++ ast_cli(fd, " Timer C : %d\n", peer->timer_c);
+ ast_cli(fd, " ToHost : %s\n", peer->tohost);
+ ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr));
+ ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr));
+@@ -18533,6 +18577,7 @@
+ "__sip_autodestruct",
+ "expire_register",
+ "auto_congest",
++ "dialog_proceeding_timeout",
+ "sip_reg_timeout",
+ "sip_poke_peer_s",
+ "sip_poke_noanswer",
+@@ -18542,6 +18587,7 @@
+ __sip_autodestruct,
+ expire_register,
+ auto_congest,
++ dialog_proceeding_timeout,
+ sip_reg_timeout,
+ sip_poke_peer_s,
+ sip_poke_noanswer,
+@@ -18955,6 +19001,7 @@
+ ast_cli(a->fd, " Timer T1: %d\n", global_t1);
+ ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min);
+ ast_cli(a->fd, " Timer B: %d\n", global_timer_b);
++ ast_cli(a->fd, " Timer C: %d\n", global_timer_c);
+ ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter));
+ ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards);
+
+@@ -20771,9 +20818,28 @@
+ resp = 183;
+
+ /* Any response between 100 and 199 is PROCEEDING */
+- if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
++ if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) {
+ p->invitestate = INV_PROCEEDING;
++ if (p->timercid == -1) {
++ /* Trigger timer C */
++ AST_SCHED_REPLACE_UNREF(p->timercid, sched, p->timer_c, dialog_proceeding_timeout, p,
++ dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"),
++ dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
++ dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
++ ast_debug(3, "Setting Timer C to %d \n", p->timer_c);
++ }
++ }
+
++ if (resp >= 200) {
++ /* Delete timer C - we have a response */
++ AST_SCHED_DEL_UNREF(sched, p->timercid, dialog_unref(p, "when you delete the timercid sched, you should dec the refcount for the stored dialog ptr"));
++ ast_debug(3, "Deleting Timer C (response received)\n");
++ } else {
++ /* reset timer C */
++ AST_SCHED_REPLACE_VARIABLE(p->timercid, sched, p->timer_c, dialog_proceeding_timeout, p, 1);
++ ast_debug(3, "Resetting Timer C to %d \n", p->timer_c);
++ }
++
+ /* Final response, not 200 ? */
+ if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
+ p->invitestate = INV_COMPLETED;
+@@ -27986,6 +28052,7 @@
+ peer->stimer.st_max_se = global_max_se;
+ peer->timer_t1 = global_t1;
+ peer->timer_b = global_timer_b;
++ peer->timer_c = global_timer_c;
+ clear_peer_mailboxes(peer);
+ peer->disallowed_methods = sip_cfg.disallowed_methods;
+ peer->transports = default_transports;
+@@ -28076,7 +28143,7 @@
+ int firstpass = 1;
+ uint16_t port = 0;
+ int format = 0; /* Ama flags */
+- int timerb_set = 0, timert1_set = 0;
++ int timerb_set = 0, timert1_set = 0, timerc_set = 0;
+ time_t regseconds = 0;
+ struct ast_flags peerflags[3] = {{(0)}};
+ struct ast_flags mask[3] = {{(0)}};
+@@ -28429,6 +28496,12 @@
+ peer->timer_b = global_timer_b;
+ }
+ timerb_set = 1;
++ } else if (!strcasecmp(v->name, "timerc")) {
++ if ((sscanf(v->value, "%30d", &peer->timer_c) != 1) || (peer->timer_c > 100)) {
++ ast_log(LOG_WARNING, "'%s' is not a valid Timer C time at line %d (above 100, default 180 s). Using configured default %d.\n", v->value, v->lineno, global_timer_c);
++ peer->timer_c = global_timer_c;
++ }
++ timerc_set = 1;
+ } else if (!strcasecmp(v->name, "setvar")) {
+ peer->chanvars = add_var(v->value, peer->chanvars);
+ } else if (!strcasecmp(v->name, "header")) {
+@@ -29002,6 +29075,7 @@
+ global_authfailureevents = FALSE;
+ global_t1 = DEFAULT_TIMER_T1;
+ global_timer_b = 64 * DEFAULT_TIMER_T1;
++ global_timer_c = 180; /* 3 minutes per RFC 3261 */
+ global_t1min = DEFAULT_T1MIN;
+ global_qualifyfreq = DEFAULT_QUALIFYFREQ;
+ global_t38_maxdatagram = -1;
+@@ -29087,6 +29161,12 @@
+ ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b);
+ }
+ timerb_set = 1;
++ } else if (!strcasecmp(v->name, "timerc")) {
++ int tmp = atoi(v->value);
++ if (tmp < 100) {
++ global_timer_c = DEFAULT_TIMER_C;
++ ast_log(LOG_WARNING, "Invalid value (< 100 s) for timerc ('%s'). Setting to default ('%d').\n", v->value, global_timer_c);
++ }
+ } else if (!strcasecmp(v->name, "t1min")) {
+ global_t1min = atoi(v->value);
+ } else if (!strcasecmp(v->name, "transport")) {
+@@ -31668,7 +31748,8 @@
+ MEMBER(sip_peer, maxms, AST_DATA_MILLISECONDS) \
+ MEMBER(sip_peer, qualifyfreq, AST_DATA_MILLISECONDS) \
+ MEMBER(sip_peer, timer_t1, AST_DATA_MILLISECONDS) \
+- MEMBER(sip_peer, timer_b, AST_DATA_MILLISECONDS)
++ MEMBER(sip_peer, timer_b, AST_DATA_MILLISECONDS) \
++ MEMBER(sip_peer, timer_c, AST_DATA_SECONDS)
+
+ AST_DATA_STRUCTURE(sip_peer, DATA_EXPORT_SIP_PEER);
+
+Index: channels/sip/include/sip.h
+===================================================================
+--- channels/sip/include/sip.h (.../branches/1.8) (revision 402920)
++++ channels/sip/include/sip.h (.../team/oej/grape-sip-timeout-pdd-1.8) (revision 402920)
+@@ -87,6 +87,7 @@
+
+ #define DEFAULT_RETRANS 1000 /*!< How frequently to retransmit Default: 2 * 500 ms in RFC 3261 */
+ #define DEFAULT_TIMER_T1 500 /*!< SIP timer T1 (according to RFC 3261) */
++#define DEFAULT_TIMER_C 180 /*!< SIP timer C (according to RFC 3261) */
+ #define SIP_TRANS_TIMEOUT 64 * DEFAULT_TIMER_T1 /*!< SIP request timeout (rfc 3261) 64*T1
+ * \todo Use known T1 for timeout (peerpoke)
+ */
+@@ -1018,6 +1019,7 @@
+ unsigned short req_secure_signaling:1;/*!< Whether we are required to have secure signaling or not */
+ int timer_t1; /*!< SIP timer T1, ms rtt */
+ int timer_b; /*!< SIP timer B, ms */
++ int timer_c; /*!< SIP timer B, ms */
+ unsigned int sipoptions; /*!< Supported SIP options on the other end */
+ unsigned int reqsipoptions; /*!< Required SIP options on the other end */
+ struct ast_codec_pref prefs; /*!< codec prefs */
+@@ -1078,6 +1080,7 @@
+
+ int initid; /*!< Auto-congest ID if appropriate (scheduler) */
+ int waitid; /*!< Wait ID for scheduler after 491 or other delays */
++ int timercid; /*!< Scheduler ID for timer C delays */
+ int reinviteid; /*!< Reinvite in case of provisional, but no final response */
+ int autokillid; /*!< Auto-kill ID (scheduler) */
+ int t38id; /*!< T.38 Response ID */
+@@ -1271,6 +1274,7 @@
+ struct sip_st_cfg stimer; /*!< SIP Session-Timers */
+ int timer_t1; /*!< The maximum T1 value for the peer */
+ int timer_b; /*!< The maximum timer B (transaction timeouts) */
++ int timer_c; /*!< The timer c (transaction timeouts) */
+ int fromdomainport; /*!< The From: domain port */
+
+ /*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
+Index: configs/sip.conf.sample
+===================================================================
+--- configs/sip.conf.sample (.../branches/1.8) (revision 402920)
++++ configs/sip.conf.sample (.../team/oej/grape-sip-timeout-pdd-1.8) (revision 402920)
+@@ -513,9 +513,13 @@
+ ;timert1=500 ; Default T1 timer
+ ; Defaults to 500 ms or the measured round-trip
+ ; time to a peer (qualify=yes).
+-;timerb=32000 ; Call setup timer. If a provisional response is not received
++;timerb=32000 ; Call setup timer. If a final response is not received
+ ; in this amount of time, the call will autocongest
+ ; Defaults to 64*timert1
++;timerc=420 ; Call setup timer. If a provisional response is not received
++ ; during this time - the call will autocongest. Default 180 secs.
++ ; Needs to be higher than 100. RFC says MUST be higher than
++ ; or equal to 180.
+
+ ;--------------------------- RTP timers ----------------------------------------------------
+ ; These timers are currently used for both audio and video streams. The RTP timeouts
+Index: README.grape
+===================================================================
+--- README.grape (.../branches/1.8) (revision 0)
++++ README.grape (.../team/oej/grape-sip-timeout-pdd-1.8) (revision 402920)
+@@ -0,0 +1,22 @@
++Edvina AB
++Olle E. Johansson
++
++Start date: 2013-11-21
++
++
++
++
++
++
++
++
++Grape - implement timer C in Chan_sip
++=====================================
++
++If we call a server and that server just sends 100 trying, we wait forever. This is not good.
++In order to fix this, this branch will implement a timer C that is normally a proxy timer.
++This fires after 3 minutes if there's no provisional response at all received from a device.
++
++When the timer fires, the call attempt is killed..
++
++The timer is set per channel, or per device.
+
+Property changes on: README.grape
+___________________________________________________________________
+Added: svn:mime-type
+## -0,0 +1 ##
++text/plain
+\ No newline at end of property
+Added: svn:keywords
+## -0,0 +1 ##
++Author Date Id Revision
+\ No newline at end of property
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
Propchange: team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/teapot-1.8/patches/grape-sip-timeout-pdd-1.8.diff
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list