| 
									
										
										
										
											2006-09-19 19:04:13 +00:00
										 |  |  | #ifndef _GNU_SOURCE
 | 
					
						
							|  |  |  | #define _GNU_SOURCE
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * ast_h323.cpp | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * OpenH323 Channel Driver for ASTERISK PBX. | 
					
						
							|  |  |  |  *			By  Jeremy McNamara | 
					
						
							|  |  |  |  *			For The NuFone Network | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * chan_h323 has been derived from code created by | 
					
						
							|  |  |  |  *               Michael Manousos and Mark Spencer | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is part of the chan_h323 driver for Asterisk | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * chan_h323 is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation; either version 2 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version.  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * chan_h323 is distributed WITHOUT ANY WARRANTY; without even  | 
					
						
							|  |  |  |  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  | 
					
						
							|  |  |  |  * PURPOSE. See the GNU General Public License for more details.  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Version Info: $Id$ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <ptlib.h>
 | 
					
						
							|  |  |  | #include <h323.h>
 | 
					
						
							|  |  |  | #include <transports.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ast_h323.h"
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | #include "compat_h323.h"
 | 
					
						
							| 
									
										
										
										
											2006-09-19 19:04:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if VERSION(OPENH323_MAJOR,OPENH323_MINOR,OPENH323_BUILD) < VERSION(1,17,3)
 | 
					
						
							|  |  |  | MyH323TransportTCP::MyH323TransportTCP( | 
					
						
							|  |  |  | 				H323EndPoint & endpoint, | 
					
						
							|  |  |  | 				PIPSocket::Address binding, | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 				PBoolean listen) | 
					
						
							| 
									
										
										
										
											2006-09-19 19:04:13 +00:00
										 |  |  | 	: H323TransportTCP(endpoint, binding, listen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323TransportTCP::Connect() | 
					
						
							| 
									
										
										
										
											2006-09-19 19:04:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (IsListening()) | 
					
						
							|  |  |  | 		return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PTCPSocket * socket = new PTCPSocket(remotePort); | 
					
						
							|  |  |  | 	Open(socket); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	channelPointerMutex.StartRead(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	socket->SetReadTimeout(10000/*endpoint.GetSignallingChannelConnectTimeout()*/); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	localPort = endpoint.GetNextTCPPort(); | 
					
						
							|  |  |  | 	WORD firstPort = localPort; | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		PTRACE(4, "H323TCP\tConnecting to " | 
					
						
							|  |  |  | 				<< remoteAddress << ':' << remotePort | 
					
						
							|  |  |  | 				<< " (local port=" << localPort << ')'); | 
					
						
							|  |  |  | 		if (socket->Connect(localAddress, localPort, remoteAddress)) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		int errnum = socket->GetErrorNumber(); | 
					
						
							|  |  |  | 		if (localPort == 0 || (errnum != EADDRINUSE && errnum != EADDRNOTAVAIL)) { | 
					
						
							|  |  |  | 			PTRACE(1, "H323TCP\tCould not connect to " | 
					
						
							|  |  |  | 					<< remoteAddress << ':' << remotePort | 
					
						
							|  |  |  | 					<< " (local port=" << localPort << ") - " | 
					
						
							|  |  |  | 					<< socket->GetErrorText() << '(' << errnum << ')'); | 
					
						
							|  |  |  | 			channelPointerMutex.EndRead(); | 
					
						
							|  |  |  | 			return SetErrorValues(socket->GetErrorCode(), errnum); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		localPort = endpoint.GetNextTCPPort(); | 
					
						
							|  |  |  | 		if (localPort == firstPort) { | 
					
						
							|  |  |  | 			PTRACE(1, "H323TCP\tCould not bind to any port in range " << | 
					
						
							|  |  |  | 					endpoint.GetTCPPortBase() << " to " << endpoint.GetTCPPortMax()); | 
					
						
							|  |  |  | 			channelPointerMutex.EndRead(); | 
					
						
							|  |  |  | 			return SetErrorValues(socket->GetErrorCode(), errnum); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	socket->SetReadTimeout(PMaxTimeInterval); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	channelPointerMutex.EndRead(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OnOpen(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323TransportUDP::DiscoverGatekeeper(H323Gatekeeper &gk, H323RasPDU &pdu, const H323TransportAddress &address) | 
					
						
							| 
									
										
										
										
											2006-09-19 19:04:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PThread *thd = PThread::Current(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* If we run in OpenH323's thread use it instead of creating new one */ | 
					
						
							|  |  |  | 	if (thd) | 
					
						
							|  |  |  | 		return H323TransportUDP::DiscoverGatekeeper(gk, pdu, address); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Make copy of arguments to pass them into thread */ | 
					
						
							|  |  |  | 	discoverGatekeeper = &gk; | 
					
						
							|  |  |  | 	discoverPDU = &pdu; | 
					
						
							|  |  |  | 	discoverAddress = &address; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Assume discovery thread isn't finished */ | 
					
						
							|  |  |  | 	discoverReady = FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Create discovery thread */ | 
					
						
							|  |  |  | 	thd = PThread::Create(PCREATE_NOTIFIER(DiscoverMain), 0, | 
					
						
							|  |  |  | 							PThread::NoAutoDeleteThread, | 
					
						
							|  |  |  | 							PThread::NormalPriority, | 
					
						
							|  |  |  | 							"GkDiscovery:%x"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Wait until discovery thread signal us its finished */  | 
					
						
							|  |  |  | 	for(;;) { | 
					
						
							|  |  |  | 		discoverMutex.Wait(); | 
					
						
							|  |  |  | 		if (discoverReady)		/* Thread has been finished */ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		discoverMutex.Signal(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	discoverMutex.Signal(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Cleanup/delete thread */ | 
					
						
							|  |  |  | 	thd->WaitForTermination(); | 
					
						
							|  |  |  | 	delete thd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return discoverResult; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323TransportUDP::DiscoverMain(PThread &thread, INT arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PWaitAndSignal m(discoverMutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	discoverResult = H323TransportUDP::DiscoverGatekeeper(*discoverGatekeeper, *discoverPDU, *discoverAddress); | 
					
						
							|  |  |  | 	discoverReady = TRUE; | 
					
						
							|  |  |  | } |