[Asterisk-Dev] Zombie channel doesn't free
Miroslaw KLABA
totoro at ovh.net
Sat May 3 09:41:10 MST 2003
Hello,
I have a problem with zombie channels. I've maid a try to transfer calls on chan_h323 and
it's nearly done. I miss just why the zombie calls doesn't hangup.
I use ast_chan_masquerade to make the transfer and it works well. But a ZOMBIE is created
from the channel previously used and evezn if I hangup each side of the call, the ZOMBIE
doesn't free.
-When I have a call, it's like this:
*CLI> show channels
Channel (Context Extension Pri ) State Appl. Data
H323/miro ( 1 ) Up Bridged Call H323/ip$10.48.200.101:2244/17768
H323/ip$10.48.200.101:2244/17768 (remote s 5 ) Up Dial H323/miro|15
2 active channel(s)
-When the transfer is done:
*CLI> show channels
Channel (Context Extension Pri ) State Appl. Data
H323/miro<ZOMBIE> ( 1 ) Ringing (None) (None)
H323/oles ( 1 ) Up Bridged Call H323/ip$10.48.200.101:2244/17768
H323/ip$10.48.200.101:2244/17768 (remote s 5 ) Up Dial H323/miro|15
3 active channel(s)
-And when both parties are hanged up:
*CLI> show channels
Channel (Context Extension Pri ) State Appl. Data
H323/miro<ZOMBIE> ( 1 ) Ringing (None) (None)
1 active channel(s)
The channels is still here but the phone that transfered the call has cleared the call so there's
nobody at the other end.
How can I free it?
Thanks
Miro
PS: I attach the patch against asterisk-0.4.0 but it's not yet usable because of the
zombie problem and some cleanup...
PS2: Tell me also if there's something wrong in the code...
-------------- next part --------------
diff -ur /temp/asterisk/asterisk-0.4.0/channels/h323/ast_h323.cpp h323/ast_h323.cpp
--- /temp/asterisk/asterisk-0.4.0/channels/h323/ast_h323.cpp Tue Apr 8 20:22:39 2003
+++ h323/ast_h323.cpp Sat May 3 18:05:34 2003
@@ -242,6 +242,81 @@
return capabilities;
}
+H323Connection * MyH323EndPoint::SetupTransfer(const PString & token, const PString & callIdentity, const PString & remoteParty, PString & newToken, void * userData)
+{
+ PString fullAddress;
+ PString alias;
+ H323TransportAddress address;
+
+ H323Connection *newH323Con;
+ H323Connection *oldH323Con;
+
+ PINDEX at = remoteParty.FindLast('@');
+ if (remoteParty.GetLength() == at+1)
+ fullAddress = remoteParty.Left(at);
+ else
+ fullAddress = remoteParty;
+
+ if (h323debug) {
+ cout << " -- Setup transfer of " << callIdentity << ":" << endl;
+ cout << " -- Call from " << token << endl;
+ cout << " -- Call to " << fullAddress << endl;
+ cout << " -- NewToken " << newToken << endl;
+ }
+
+
+
+
+ if (GetGatekeeper() != NULL) {
+ if (h323debug)
+ cout << " -- Making call to " << fullAddress << " using gatekeeper." << endl;
+ } else {
+ if (h323debug)
+ cout << " -- Making call to " << fullAddress << "." << endl;
+ }
+
+ // Making call to remoteParty
+ if (!H323EndPoint::MakeCall(fullAddress, newToken)) {
+ if (h323debug)
+ cout << "Error making call to \"" << fullAddress << '"' << endl;
+ return NULL;
+ }
+
+ newH323Con = FindConnectionWithLock(newToken);
+ oldH323Con = FindConnectionWithLock(token);
+
+ if (newH323Con != NULL && oldH323Con != NULL) {
+ unsigned int new_call_reference = newH323Con->GetCallReference();
+ unsigned int old_call_reference = oldH323Con->GetCallReference();
+ if (h323debug) {
+ cout << " -- New call reference " << new_call_reference << endl;
+ cout << " -- Old call reference " << old_call_reference << endl;
+ cout << " -- NewToken " << newToken << endl;
+ }
+ newH323Con->Unlock();
+ oldH323Con->Unlock();
+ // Setup transfer then
+ if (setup_transfer(old_call_reference, new_call_reference, fullAddress)) {
+ if (h323debug)
+ cout << " -- Transfer succeded" << endl;
+ return newH323Con;
+ } else {
+ if (h323debug)
+ cout << " -- Transfer failed " << endl;
+ return NULL;
+ }
+ } else {
+ //Clean all mess
+ if (newH323Con != NULL)
+ newH323Con->Unlock();
+ if (oldH323Con != NULL)
+ oldH323Con->Unlock();
+ if (h323debug)
+ cout << "Error making call to \"" << fullAddress << '"' << endl;
+ return NULL;
+ }
+}
+
BOOL MyH323EndPoint::ClearCall(const PString & token)
{
if (h323debug)
@@ -268,6 +343,20 @@
H323EndPoint::OnClosedLogicalChannel(connection, channel);
}
+BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection, const PString & forwardParty, const H323SignalPDU & pdu)
+{
+ if (h323debug)
+ cout << " -- Call Forwarded to " << forwardParty << endl;
+ return FALSE;
+}
+
+BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection, const PString & forwardParty, const H323SignalPDU & pdu)
+{
+ if (h323debug)
+ cout << " -- Forwarding call to " << forwardParty << endl;
+ return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);
+}
+
void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
{
if (h323debug)
@@ -298,6 +387,8 @@
switch (connection.GetCallEndReason()) {
case H323Connection::EndedByCallForwarded :
+ if (h323debug)
+ cout << " -- " << remoteName << " has forwarded the call" << endl;
break;
case H323Connection::EndedByRemoteUser :
if (h323debug)
@@ -535,6 +626,13 @@
return H323Connection::OnSendSignalSetup(setupPDU);
}
+BOOL MyH323Connection::OnReceivedFacility(const H323SignalPDU & pdu)
+{
+ if (h323debug)
+ cout << " -- Received Facility message... " << endl;
+ return H323Connection::OnReceivedFacility(pdu);
+}
+
void MyH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu)
{
if (h323debug)
diff -ur /temp/asterisk/asterisk-0.4.0/channels/h323/ast_h323.h h323/ast_h323.h
--- /temp/asterisk/asterisk-0.4.0/channels/h323/ast_h323.h Mon Mar 31 09:13:36 2003
+++ h323/ast_h323.h Thu May 1 16:05:22 2003
@@ -62,6 +62,8 @@
/*! SpeeX Free Compression */
#define AST_FORMAT_SPEEX (1 << 9)
+class MyH323EndPoint;
+class MyH323Connection;
/**This class describes the G.723.1 codec capability.
*/
@@ -103,10 +105,13 @@
public:
int MakeCall(const PString &, PString &, unsigned int *, unsigned int);
+ H323Connection * SetupTransfer(const PString &, const PString &, const PString &, PString &, void *);
BOOL ClearCall(const PString &);
// BOOL OnIncomingCall( H323Connection & connection, const H323SignalPDU &, H323SignalPDU &);
void OnClosedLogicalChannel(H323Connection &, const H323Channel &);
+ BOOL OnConnectionForwarded(H323Connection &, const PString &, const H323SignalPDU &);
+ BOOL ForwardConnection(H323Connection &, const PString &, const H323SignalPDU &);
void OnConnectionEstablished(H323Connection &, const PString &);
void OnConnectionCleared(H323Connection &, const PString &);
H323Connection * CreateConnection(unsigned, void *);
@@ -119,7 +124,6 @@
void SetGateway(void);
};
-
class MyH323Connection : public H323Connection {
PCLASSINFO(MyH323Connection, H323Connection);
@@ -134,6 +138,7 @@
BOOL OnAlerting(const H323SignalPDU &, const PString &);
BOOL OnReceivedSignalSetup(const H323SignalPDU &);
void OnReceivedReleaseComplete(const H323SignalPDU &);
+ BOOL OnReceivedFacility(const H323SignalPDU &);
BOOL OnSendSignalSetup(H323SignalPDU &);
BOOL OnStartLogicalChannel(H323Channel &);
BOOL OnClosingLogicalChannel(H323Channel &);
diff -ur /temp/asterisk/asterisk-0.4.0/channels/h323/chan_h323.c h323/chan_h323.c
--- /temp/asterisk/asterisk-0.4.0/channels/h323/chan_h323.c Fri Apr 11 06:12:41 2003
+++ h323/chan_h323.c Sat May 3 18:01:23 2003
@@ -45,6 +45,7 @@
#include <asterisk/callerid.h>
#include <asterisk/cli.h>
#include <asterisk/dsp.h>
+#include <asterisk/musiconhold.h>
#include <sys/socket.h>
#include <net/if.h>
#include <errno.h>
@@ -404,7 +405,7 @@
res = h323_make_call(called_addr, &(p->cd), p->call_opt);
if (res) {
- printf("h323_make_call failed\n");
+ ast_log(LOG_DEBUG, "h323_make_call failed(%s)\n", c->name);
return -1;
}
@@ -463,6 +464,15 @@
ast_log(LOG_DEBUG, "ClearCall failed.\n");
p->needdestroy = 1;
}
+
+ /* Update usage counter */
+ ast_pthread_mutex_lock(&usecnt_lock);
+ usecnt--;
+ if (usecnt < 0)
+ ast_log(LOG_WARNING, "Usecnt < 0???\n");
+ ast_pthread_mutex_unlock(&usecnt_lock);
+ ast_update_use_count();
+
ast_pthread_mutex_unlock(&p->lock);
@@ -1028,6 +1038,82 @@
#endif
/**
+ * Call-back function that transfers the call
+ *
+ *
+ */
+int setup_transfer(unsigned call_reference, unsigned new_call_reference, const char * fullAddress)
+{
+ /* Find the call with token */
+ struct oh323_pvt *p1, *p2;
+ struct ast_channel *c;
+
+ p1=find_call(call_reference);
+
+ if (!p1) {
+ ast_log(LOG_WARNING, "No such call %d\n", call_reference);
+ return 0;
+ }
+
+ p2=oh323_alloc(new_call_reference);
+ if (!p2) {
+ ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
+ return 0;
+ }
+
+ /* Assign a default capability */
+ p2->capability = capability;
+ p2->outgoing = 1;
+
+ if (p2->dtmfmode) {
+ if (p2->dtmfmode & H323_DTMF_RFC2833)
+ p2->nonCodecCapability |= AST_RTP_DTMF;
+ else
+ p2->nonCodecCapability &= ~AST_RTP_DTMF;
+ }
+
+ /* Clear the call token */
+ if ((p2->cd).call_token == NULL)
+ (p2->cd).call_token = (char *)malloc(128);
+
+ memset((char *)(p2->cd).call_token, 0, 128);
+
+ if (p2->cd.call_token == NULL) {
+ ast_log(LOG_ERROR, "Not enough memory.\n");
+ return -1;
+ }
+
+ p2->cd.call_token = fullAddress;
+ c = oh323_new(p2, AST_STATE_DOWN, p2->cd.call_token);
+ if (!c){
+ ast_log(LOG_WARNING, "Couldn't create channel. This is bad\n");
+// oh323_destroy(p2);
+ return 0;
+ }
+
+ if (!p1->owner || !p2->owner) {
+ ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
+ oh323_destroy(p2);
+ return 0;
+ }
+
+ if (p1->owner->bridge){
+ ast_moh_stop(p1->owner->bridge);
+ ast_moh_stop(p2->owner);
+ ast_moh_stop(p1->owner);
+ if (ast_channel_masquerade(p1->owner, p2->owner)) {
+ ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p1->owner->name, p2->owner->name);
+ return 0;
+ }
+ ast_setstate(c, AST_STATE_RINGING);
+ } else {
+ ast_log(LOG_WARNING, "Transfer attempted with call bridged yet\n");
+ return 0;
+ }
+ return 1;
+}
+
+/**
* Call-back function that gets called for each rtp channel opened
*
* Returns nothing
@@ -1123,6 +1209,13 @@
}
p->alreadygone = 1;
+
+#if 0
+ if (p->owner->masq) {
+ ast_queue_hangup(p->owner->masq,1);
+ p->owner->masq = NULL;
+ }
+#endif
/* Send hangup */
if (p->owner)
@@ -1667,6 +1760,11 @@
ast_log(LOG_WARNING, "Unable to lock the interface list\n");
return -1;
}
+
+ delete_users();
+ delete_aliases();
+ prune_peers();
+
if (!ast_pthread_mutex_lock(&iflock)) {
/* destroy all the interfaces and free their memory */
@@ -1685,6 +1783,17 @@
}
h323_gk_urq();
h323_end_process();
+
+ /* unregister rtp */
+ ast_rtp_proto_unregister(&oh323_rtp);
+
+ /* unregister commands */
+ ast_cli_unregister(&cli_debug);
+ ast_cli_unregister(&cli_no_debug);
+ ast_cli_unregister(&cli_trace);
+ ast_cli_unregister(&cli_no_trace);
+ ast_cli_unregister(&cli_show_codecs);
+ ast_cli_unregister(&cli_gk_cycle);
/* unregister channel type */
ast_channel_unregister(type);
diff -ur /temp/asterisk/asterisk-0.4.0/channels/h323/chan_h323.h h323/chan_h323.h
--- /temp/asterisk/asterisk-0.4.0/channels/h323/chan_h323.h Mon Mar 31 22:26:08 2003
+++ h323/chan_h323.h Sat May 3 18:04:50 2003
@@ -153,7 +153,9 @@
void h323_end_point_create(void);
void h323_end_process(void);
int end_point_exist(void);
-
+
+ int setup_transfer(unsigned, unsigned, const char *);
+
void h323_debug(int, unsigned);
/* callback function handler*/
More information about the asterisk-dev
mailing list