[Asterisk-Users] FIXED - 487 Request Terminated ?

Brancaleoni Matteo mbrancaleoni at espia.it
Tue Mar 18 07:33:18 MST 2003


Ok guys, that's it a patch for chan_sip.c

The problem is: some devices transmit late packets,
even when asterisk has already destroyed the channels.
For example 487 is sent by various ipphones , like
kphone, snom & some fxs-sip gw) when a request
is cancelled by the caller (for eg. when the
caller Cancel an Invite Request). But since
487 is sent *after* cancel , the sip channel
are already destroyed to asterisk can't ack them.
That's wrong, since some phone just ignore
the lacking of ack, other keep ringing if not
ack'ed .

So my patch just adds a timer to do_monitor,
in order to wait 10 seconds before destroying
the sip channel.

Probably that will fix also some reported problems
on cisco phones that go on ringing even if the caller
hangs up.

Lemme know.

P.S. I'm not a C-guru . The patch works well , but
if someone wants to improve it, feel free to blame me.

Matteo

Il lun, 2003-03-17 alle 18:06, Matteo Brancaleoni ha scritto:
> I've a sip phone that when called,
> if not answered and you hangup
> on the caller side, sends out
> "487 Request Terminated" .
> But seems that * don't get that
> message (I think * ignore it)
> so the phone don't get an OK
> and keep ringing until timeout,
> even if the caller has hanged
> up.
> 
> Could that be added to *?
> Attached some debug.
> 
> Matteo Brancaleoni
> mbrancaleoni at espia.it
> Emmegi System Administrator
>  
> EspiA - EMMEGI Srl - e*solution provider
> Uffici: Via Pascoli, 37
> 20129 Milano - Italy
> Sede Legale: Corso Sempione 67
> 20149 Milano - Italy
> Tel. +39 0270633354
> Fax. +39 0245487890
> http://www.espia.it
-------------- next part --------------
--- ./asterisk/channels/chan_sip.c	2003-03-18 01:35:29.000000000 +0100
+++ ./myasterisk/channels/chan_sip.c	2003-03-18 15:04:04.000000000 +0100
@@ -183,6 +183,7 @@
 	int initid;							/* Auto-congest ID if appropriate */
 
         int dtmfmode;
+	int needhanguptimer;				/* hangup timer started or not*/
         struct ast_dsp *vad;
 	
 	struct sip_peer *peerpoke;			/* If this calls is to poke a peer, which one */
@@ -3260,6 +3261,7 @@
 					break;
 				}
 				transmit_request(p, "ACK", 0);
+				ast_log(LOG_DEBUG, "ooh, SIP DESTROY 4xx user=%s\n",p->username);
 				__sip_destroy(p, 0);
 				p = NULL;
 			} else
@@ -3711,6 +3713,7 @@
 	struct sip_pvt *sip;
 	struct sip_peer *peer;
 	time_t t;
+	time_t hanguptimer,temptime;
 	/* Add an I/O event to our UDP socket */
 	if (sipsock > -1) 
 		ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
@@ -3724,7 +3727,30 @@
 restartsearch:		
 		sip = iflist;
 		while(sip) {
-			if (sip->needdestroy) {
+			/* Ok, start wait before destroying a channel */
+			/* in order to get late responses and ack them */
+			if ((sip->needdestroy) && !(sip->needhanguptimer)) 
+			{
+				ast_log(LOG_DEBUG, "Starting timer check\n");
+				sip->needhanguptimer = 1;
+				time(&hanguptimer);
+				goto restartsearch;
+			}
+			/* Ok, already started the timer, check it */
+			else if ((sip->needdestroy) && (sip->needhanguptimer)) 
+			{
+				time(&temptime);
+				/* 10 secs for late packets */
+				if((temptime - hanguptimer) > 10)
+				{
+					ast_log(LOG_DEBUG, "Time Expired!\n");
+					sip->needhanguptimer = 2;
+				}
+			}
+			/* If we are here, the timer is started */
+			/* check if it's set as expired , then destroy */
+			if ((sip->needdestroy) && (sip->needhanguptimer == 2)) {
+				ast_log(LOG_DEBUG, "Gotta a SIP Destroy! Username=%s callid=%s \n",sip->username,sip->callid);
 				__sip_destroy(sip, 1);
 				goto restartsearch;
 			}


More information about the asterisk-users mailing list