[Asterisk-Dev] how to get requested channel if p->call not NULL
Abhishek Tiwari
abhitiwari at gmail.com
Fri Apr 29 07:25:36 MST 2005
Hi,
I am facing a problem that my pbx side sometimes doesnt respond to
the DISCONNECT sent to it and while requesting that channel the
available() function in chan_zap.c returns 0 since p->call is not
NULL. Repetitive attempts for the same fail. I tried to do a fix so
that I send RELEASE on that channel, do a destroycall and set p->call
to NULL. This alone does not work in my case since the next time
available() returns 1 and SETUP is sent on this channel, but
pri_fixup_channel moves this call to some other channel, which is not
acceptable to me. So in addition I also do a reset on that channel in
available(), so that the channel is available when it is used. Works
fine and does the job, for some time.
This is the code that i added in available() (attached is the patch
for CVS HEAD chan_zap.c)
======================================================
if (!p->owner) {
/* Trust PRI */
#ifdef ZAPATA_PRI
if (p->pri) {
/****** my code starts here *******/
if(p->call)
{
ast_log(LOG_WARNING, "************ Call not
null for %d channel on span %d, Foring Restart
************\n",PRI_CHANNEL(channelmatch), p->pri->span);
ast_mutex_lock(&p->lock);
if (p->pri && p->pri->pri) {
if (!pri_grab(p, p->pri)) {
// 26 as casue to send
release, though call state would do the same
pri_hangup(p->pri->pri, p->call, 26);
pri_destroycall(p->pri->pri, p->call);
pri_rel(p->pri);
} else
ast_log(LOG_WARNING, "Failed
to grab PRI!\n");
} else
ast_log(LOG_WARNING, "The PRI Call
have not been destroyed\n");
p->call = NULL;
pri_reset(p->pri->pri, PVT_TO_CHANNEL(p));
p->resetting = 1;
ast_mutex_unlock(&p->lock);
return 0;
}
/****** my code ends here *******/
if (p->resetting || p->call)
return 0;
else
return 1;
}
======================================================
This frees up the channels as wanted, the next time it is
requested, but the problem is that after 3-4 hours of smooth running
asterisk crashes. all the crashes have been in or around
pri_disconnect_timeout or pri_release_timeout (depeding whether I use
-1 or 26 in pri_hangup). Mark had pointed out that this is because of
double freeing occuring, though I could not find out where. Will
taking p->lock earlier help ? when ? will decreasing the t305 and t308
timers instead of this fix be of any help ? (havent tried that yet,
will try tomorrow)
Below is the "bt full" of the thread for the last crash. I have
been trying this for some time now, but nothing works for long. Any
solutions ?
sorry, cant get the bt full, m/c remote and inaccessible now, though
here's "bt" from the screen
==================================================
#0 0xb6f6776b in q921_transmit_iframe (pri=0x825dfd8, buf=0xb6ebd704,
len=9, cr=1) at q921.c:385
385 for (f=pri->txqueue; f; f = f->next) prev = f;
(gdb) bt
#0 0xb6f6776b in q921_transmit_iframe (pri=0x825dfd8, buf=0xb6ebd704,
len=9, cr=1) at q921.c:385
#1 0xb6f6dbaf in q931_xmit (pri=0x825dfd8, h=0xb6ebd704, len=9, cr=1)
at q931.c:2476
#2 0xb6f6deb4 in send_message (pri=0x825dfd8, c=0x8244ef8,
msgtype=77, ies=0xb6f7bd78) at q931.c:2537
#3 0xb6f6e7bd in q931_release (pri=0x825dfd8, c=0x8244ef8, cause=16)
at q931.c:2800
#4 0xb6f6e587 in pri_disconnect_timeout (data=0x8244ef8) at q931.c:2751
#5 0xb6f6907f in __pri_schedule_run (pri=0x81e9d18, tv=0xb6ebdbbc) at
prisched.c:97
#6 0xb6f690e4 in pri_schedule_run (pri=0x81e9d18) at prisched.c:109
#7 0xb6fb425b in pri_dchannel (vpri=0xb6fcff50) at chan_zap.c:7691
#8 0xb7589e51 in pthread_start_thread () from /lib/i686/libpthread.so.0
#9 0xb747cd8a in clone () from /lib/i686/libc.so.6
(gdb) p pri
$1 = (struct pri *) 0x825dfd8
(gdb) p pri->txqueue
$2 = (struct q921_frame *) 0xb7
=========================================================
regards,
Abhishek
Drishti-Soft Solutions Pvt Ltd
http://www.drishti-soft.com
-------------- next part --------------
--- chan_zap.c 2005-04-22 13:39:47.000000000 +0530
+++ chan_zap.c.modified 2005-04-29 19:40:04.462463001 +0530
@@ -6867,6 +6867,30 @@
/* Trust PRI */
#ifdef ZAPATA_PRI
if (p->pri) {
+
+ if(p->call)
+ {
+ ast_log(LOG_WARNING, "************ Call not null for %d channel on span %d, Forcing Restart ************\n",PRI_CHANNEL(channelmatch), p->pri->span);
+
+ ast_mutex_lock(&p->lock);
+ if (p->pri && p->pri->pri) {
+ if (!pri_grab(p, p->pri)) {
+ pri_hangup(p->pri->pri, p->call, -1);
+ pri_destroycall(p->pri->pri, p->call);
+ pri_rel(p->pri);
+ } else
+ ast_log(LOG_WARNING, "Failed to grab PRI!\n");
+ } else
+ ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
+
+ p->call = NULL;
+
+ pri_reset(p->pri->pri, PVT_TO_CHANNEL(p));
+ p->resetting = 1;
+ ast_mutex_unlock(&p->lock);
+ return 0;
+ }
+
if (p->resetting || p->call)
return 0;
else
More information about the asterisk-dev
mailing list