I'm thinking about a timer variable. Something like:
in h_table.h, add this:
typedef struct cell
{
/* linking data */
struct cell* next_cell;
struct cell* prev_cell;
....omitted.....
unsigned int inv_timer;
}
Then, in tm.c, something like (with the appropriate hooks):
inline static int w_t_inv_timeout( struct sip_msg* msg, char *go_to,
char *foo )
{
struct cell *t;
t = get_t();
if (!t || t==T_UNDEFINED) {
LOG(L_CRIT, "BUG: w_t_on_negative entered without t\n");
return -1;
}
t->inv_timer = (unsigned int)(long)go_to;
return 1;
}
Then, in timer.c, create a new function set_timer_val()
which is exactly like set_timer() except the timeout
value is passed to it:
void set_timer_val( struct timer_link *new_tl, enum lists list_id,
unsigned int timeout )
{
struct timer* list;
if (list_id<FR_TIMER_LIST || list_id>=NR_OF_TIMER_LISTS) {
LOG(L_CRIT, "ERROR: set_timer: unkown list: %d\n",
list_id);
#ifdef EXTRA_DEBUG
abort();
#endif
return;
}
list= &(timertable->timers[ list_id ]);
lock(list->mutex);
/* check first if we are on the "detached" timer_routine list,
* if so do nothing, the timer is not valid anymore
* (sideffect: reset_timer ; set_timer is not safe, a reseted timer
* might be lost, depending on this race condition ) */
if (new_tl->timer_list==DETACHED_LIST){
LOG(L_CRIT, "WARNING: set_timer called on a
\"detached\" timer"
" -- ignoring: %p\n", new_tl);
goto end;
}
/* make sure I'm not already on a list */
remove_timer_unsafe( new_tl );
add_timer_unsafe( list, new_tl, get_ticks()+timeout);
end:
unlock(list->mutex);
}
Then, in t_reply.c, something like:
int reply_received( struct sip_msg *p_msg )
{
....omitted.....
/* update FR/RETR timers on provisional replies */
if (msg_status<200) { /* provisional now */
if (t->is_invite) {
/* invite: change FR to longer FR_INV, do not
attempt to restart retransmission any more
*/
set_timer_val( & uac->request.fr_timer,
FR_INV_TIMER_LIST, t->inv_timer );
}
.....
Then, in your ser.cfg file you would do:
t_inv_timeout(120);
t_relay();
this would override the global, ie:
modparam("tm","fr_inv_timer",25)
What do you think? I think I can get it to work. It is in
the tm module. Is this desirable? I think it would solve
my problem. Also, I think it would allow for some other neat
things, like user controllable timeout before voicemail is
called.
---greg
Greg Fausak wrote:
I have an INVITE timeout problem.
My SIP layout includes:
+---------------+
| EXTERNAL PSTN |
| SIP SERVERS |
+---------------+
|
|
+---------------+
| MAIN INCOMING |
| SIP SERVER |
+---------------+
| |
| |
+------------+ +-----------------+
| SIP SERVER | | SIP SERVER |
| DOMAINA.com| |
OtherDom.com |
+------------+ +-----------------+
| |
| |
+----------+ +---------+
| customerA| |otherCust|
+----------+ +---------+
I hope the ASCII drawing worked!
Calls come in from the top down.
The MAIN INCOMING server uses internal ENUM
to deliver the call to the correct domain
server. Once delivered to that server,
if the customer does not answer his phone before
an INVITE timeout occurs the call is forwarded to
voicemail.
This works great when the call is from an external PSTN
server. It also works great if a user in
DOMAINA.com calls another
user in
DOMAINA.com.
I am experiencing difficulty when a user in
DOMAINA.com
calls a user in
OtherDom.com. The SER at
DOMAINA.com
recognizes that INVITE is going to a foreign domain, and it
t_relays() the INVITE to the MAIN INCOMING SER. It then gets
t_relayed() to
OtherDom.com where the call is delivered.
The problem is both use the same INVITE timer, so the TIMEOUT
on
DOMAINA.com occurs *before* the TIMEOUT on
OtherDom.com, which
means that the call is not delivered to voicemail.
Any ideas?
---greg