Index: libpri/q931.c =================================================================== RCS file: /usr/cvsroot/libpri/q931.c,v retrieving revision 1.48 diff -u -r1.48 q931.c --- libpri/q931.c 6 Apr 2004 14:50:19 -0000 1.48 +++ libpri/q931.c 9 Apr 2004 15:25:18 -0000 @@ -182,6 +182,7 @@ #define LOC_INTERNATIONAL_NETWORK 0x7 #define LOC_NETWORK_BEYOND_INTERWORKING 0xa +#define T_303 4000 #define T_308 4000 #define T_305 30000 #define T_313 4000 @@ -243,6 +244,7 @@ int retranstimer; /* Timer for retransmitting DISC */ int t308_timedout; /* Whether t308 timed out once */ + int t303_timedout; /* Whether t303 (Setup) timed out once */ int redirectingplan; int redirectingpres; int redirectingreason; @@ -1615,6 +1617,56 @@ return send_message(pri, c, Q931_SETUP_ACKNOWLEDGE, connect_ies); } + +static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_DISPLAY, Q931_PROGRESS_INDICATOR, + Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_SENDING_COMPLETE, -1 }; + +static void q931_setup_finaltimeout(void *data); + +static void q931_setup_timeout(void *data) +{ + struct q931_call *c = data; + struct pri *pri = c->pri; + int res; + + if (pri->debug & PRI_DEBUG_Q931_STATE) + pri_message("Timed out looking for setup ack, call proceeding, connect\n"); + c->t303_timedout++; + c->alive = 1; + if (c->retranstimer) + pri_schedule_del(pri, c->retranstimer); + c->retranstimer = pri_schedule_event(pri, T_303, q931_setup_finaltimeout, c); + + res = send_message(pri, c, Q931_SETUP, setup_ies); + if (!res) { + c->alive = 1; + /* make sure we call PRI_EVENT_HANGUP_ACK once we send/receive RELEASE_COMPLETE */ + c->sendhangupack = 1; + c->ourcallstate = Q931_CALL_STATE_CALL_INITIATED; + c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING; + } +} + +static void q931_setup_finaltimeout(void *data) +{ + struct q931_call *c = data; + struct pri *pri = c->pri; + + c->alive = 1; + if (pri->debug & PRI_DEBUG_Q931_STATE) + pri_message("Final time-out looking for setup ack, call proceeding, connect\n"); + c->t303_timedout++; + c->ourcallstate = Q931_CALL_STATE_NULL; + c->peercallstate = Q931_CALL_STATE_NULL; + pri->schedev = 1; + pri->ev.e = PRI_EVENT_HANGUP_ACK; + pri->ev.hangup.channel = c->channelno; + pri->ev.hangup.cref = c->cr; + pri->ev.hangup.cause = c->cause; + pri->ev.hangup.call = c; + q931_hangup(pri, c, c->cause); +} + static void pri_connect_timeout(void *data) { struct q931_call *c = data; @@ -1753,8 +1805,6 @@ return 0; } -static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_DISPLAY, Q931_PROGRESS_INDICATOR, - Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_SENDING_COMPLETE, -1 }; int q931_setup(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres, char *called, @@ -1762,7 +1812,6 @@ { int res; - if (!channel) return -1; c->transcapability = transmode; @@ -1809,6 +1858,12 @@ c->progress = Q931_PROG_CALLER_NOT_ISDN; else c->progress = -1; + + c->t303_timedout=0; + if (c->retranstimer) + pri_schedule_del(pri, c->retranstimer); + c->retranstimer = pri_schedule_event(pri, T_303, q931_setup_timeout, c); + res = send_message(pri, c, Q931_SETUP, setup_ies); if (!res) { c->alive = 1; @@ -1967,6 +2022,9 @@ pri_error("Unable to locate call %d\n", q931_cr(h)); return -1; } + if (c->retranstimer) + pri_schedule_del(pri, c->retranstimer); + c->retranstimer = 0; /* Preliminary handling */ switch(mh->msg) { case Q931_RESTART: @@ -2017,11 +2075,11 @@ c->progress = -1; break; case Q931_CONNECT_ACKNOWLEDGE: + /* Fall through */ + case Q931_CALL_PROCEEDING: if (c->retranstimer) pri_schedule_del(pri, c->retranstimer); c->retranstimer = 0; - /* Fall through */ - case Q931_CALL_PROCEEDING: /* Do nothing */ break; case Q931_RELEASE: