| 
									
										
										
										
											2006-04-03 18:36:30 +00:00
										 |  |  | #ifndef _GNU_SOURCE
 | 
					
						
							| 
									
										
										
										
											2005-06-01 16:00:13 +00:00
										 |  |  | #define _GNU_SOURCE
 | 
					
						
							| 
									
										
										
										
											2006-04-03 18:36:30 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ast_h323.cpp | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * OpenH323 Channel Driver for ASTERISK PBX. | 
					
						
							|  |  |  |  *			By  Jeremy McNamara | 
					
						
							|  |  |  |  *			For The NuFone Network | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-09-30 19:30:49 +00:00
										 |  |  |  * chan_h323 has been derived from code created by | 
					
						
							|  |  |  |  *               Michael Manousos and Mark Spencer | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |  * (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |  * 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. | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-08-25 18:34:10 +00:00
										 |  |  |  * Version Info: $Id$ | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-15 17:21:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | #define VERSION(a,b,c) ((a)*10000+(b)*100+(c))
 | 
					
						
							| 
									
										
										
										
											2008-12-15 17:21:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-26 03:50:14 +00:00
										 |  |  | #include <arpa/inet.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <list>
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <ptlib.h>
 | 
					
						
							|  |  |  | #include <h323.h>
 | 
					
						
							|  |  |  | #include <h323pdu.h>
 | 
					
						
							| 
									
										
										
										
											2006-09-25 07:50:25 +00:00
										 |  |  | #include <h323neg.h>
 | 
					
						
							| 
									
										
										
										
											2004-06-26 03:50:14 +00:00
										 |  |  | #include <mediafmt.h>
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* H323 Plus */ | 
					
						
							|  |  |  | #if VERSION(OPENH323_MAJOR, OPENH323_MINOR, OPENH323_BUILD) > VERSION(1,19,4)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | #include "h450/h4501.h"
 | 
					
						
							|  |  |  | #include "h450/h4504.h"
 | 
					
						
							|  |  |  | #include "h450/h45011.h"
 | 
					
						
							|  |  |  | #include "h450/h450pdu.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef H323_H460
 | 
					
						
							|  |  |  | #include <h460/h4601.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /* !H323 Plus */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-26 03:50:14 +00:00
										 |  |  | #include <lid.h>
 | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | #include "h4501.h"
 | 
					
						
							|  |  |  | #include "h4504.h"
 | 
					
						
							|  |  |  | #include "h45011.h"
 | 
					
						
							|  |  |  | #include "h450pdu.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-06-26 03:50:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | #endif /* H323 Plus */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "compat_h323.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-29 23:06:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-26 03:50:14 +00:00
										 |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							| 
									
										
										
										
											2005-06-01 16:00:13 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-11-20 14:49:32 +00:00
										 |  |  | #include "asterisk/compat.h"
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/logger.h"
 | 
					
						
							| 
									
										
										
										
											2005-06-01 16:00:13 +00:00
										 |  |  | #include "asterisk/channel.h"
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #include "asterisk/astobj.h"
 | 
					
						
							| 
									
										
										
										
											2004-06-26 03:50:14 +00:00
										 |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-29 23:06:56 +00:00
										 |  |  | #undef open
 | 
					
						
							|  |  |  | #undef close
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-26 03:50:14 +00:00
										 |  |  | #include "chan_h323.h"
 | 
					
						
							|  |  |  | #include "ast_h323.h"
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #include "cisco-h225.h"
 | 
					
						
							| 
									
										
										
										
											2006-09-20 19:21:15 +00:00
										 |  |  | #include "caps_h323.h"
 | 
					
						
							| 
									
										
										
										
											2004-01-13 03:07:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 21:18:27 +00:00
										 |  |  | /* PWLIB_MAJOR renamed to PTLIB_MAJOR in 2.x.x */ | 
					
						
							|  |  |  | #if (defined(PTLIB_MAJOR) || VERSION(PWLIB_MAJOR, PWLIB_MINOR, PWLIB_BUILD) >= VERSION(1,12,0))
 | 
					
						
							| 
									
										
										
										
											2008-05-19 15:24:44 +00:00
										 |  |  | #define SKIP_PWLIB_PIPE_BUG_WORKAROUND 1
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | ///////////////////////////////////////////////
 | 
					
						
							|  |  |  | /* We have to have a PProcess running for the life of the instance to give
 | 
					
						
							|  |  |  |  * h323plus a static instance of PProcess to get system information. | 
					
						
							|  |  |  |  * This class is defined with PDECLARE_PROCESS().  See pprocess.h from pwlib. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | /* PWlib Required Components  */ | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | #if VERSION(OPENH323_MAJOR, OPENH323_MINOR, OPENH323_BUILD) > VERSION(1,19,4)
 | 
					
						
							|  |  |  | #define MAJOR_VERSION 1
 | 
					
						
							|  |  |  | #define MINOR_VERSION 19
 | 
					
						
							|  |  |  | #define BUILD_TYPE    ReleaseCode
 | 
					
						
							|  |  |  | #define BUILD_NUMBER  6
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | #define MAJOR_VERSION 1
 | 
					
						
							|  |  |  | #define MINOR_VERSION 0
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | #define BUILD_TYPE    ReleaseCode
 | 
					
						
							|  |  |  | #define BUILD_NUMBER  0
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | const char *h323manufact = "The NuFone Networks"; | 
					
						
							|  |  |  | const char *h323product  = "H.323 Channel Driver for Asterisk"; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | PDECLARE_PROCESS(MyProcess,PProcess,h323manufact,h323product,MAJOR_VERSION,MINOR_VERSION,BUILD_TYPE,BUILD_NUMBER) | 
					
						
							|  |  |  | static MyProcess localProcess;  // active for the life of the DLL
 | 
					
						
							|  |  |  | /* void MyProcess::Main()
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | ////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** Counter for the number of connections */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | static int channelsOpen; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * We assume that only one endPoint should exist. | 
					
						
							|  |  |  |  * The application cannot run the h323_end_point_create() more than once | 
					
						
							|  |  |  |  * FIXME: Singleton this, for safety | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | static MyH323EndPoint *endPoint = NULL; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 21:18:27 +00:00
										 |  |  | #ifndef SKIP_PWLIB_PIPE_BUG_WORKAROUND
 | 
					
						
							|  |  |  | static int _timerChangePipe[2]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | static unsigned traceOptions = PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | class PAsteriskLog : public PObject, public iostream { | 
					
						
							|  |  |  | 	PCLASSINFO(PAsteriskLog, PObject); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 	PAsteriskLog() : iostream(cout.rdbuf()) { init(&buffer); } | 
					
						
							|  |  |  | 	~PAsteriskLog() { flush(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	private: | 
					
						
							|  |  |  | 	PAsteriskLog(const PAsteriskLog &) : iostream(cout.rdbuf()) { } | 
					
						
							|  |  |  | 	PAsteriskLog & operator=(const PAsteriskLog &) { return *this; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	class Buffer : public streambuf { | 
					
						
							|  |  |  | 		public: | 
					
						
							|  |  |  | 		virtual int overflow(int=EOF); | 
					
						
							|  |  |  | 		virtual int underflow(); | 
					
						
							|  |  |  | 		virtual int sync(); | 
					
						
							|  |  |  | 		PString string; | 
					
						
							|  |  |  | 	} buffer; | 
					
						
							|  |  |  | 	friend class Buffer; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PAsteriskLog *logstream = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PAsteriskLog::Buffer::overflow(int c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (pptr() >= epptr()) { | 
					
						
							|  |  |  | 		int ppos = pptr() - pbase(); | 
					
						
							| 
									
										
										
										
											2005-04-29 04:22:47 +00:00
										 |  |  | 		char *newptr = string.GetPointer(string.GetSize() + 2000); | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 		setp(newptr, newptr + string.GetSize() - 1); | 
					
						
							|  |  |  | 		pbump(ppos); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (c != EOF) { | 
					
						
							|  |  |  | 		*pptr() = (char)c; | 
					
						
							|  |  |  | 		pbump(1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PAsteriskLog::Buffer::underflow() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return EOF; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PAsteriskLog::Buffer::sync() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-11 04:06:44 +00:00
										 |  |  | 	char *str = ast_strdup(string); | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	char *s, *s1; | 
					
						
							|  |  |  | 	char c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Pass each line with different ast_verbose() call */ | 
					
						
							|  |  |  | 	for (s = str; s && *s; s = s1) { | 
					
						
							|  |  |  | 		s1 = strchr(s, '\n'); | 
					
						
							|  |  |  | 		if (!s1) | 
					
						
							|  |  |  | 			s1 = s + strlen(s); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			s1++; | 
					
						
							|  |  |  | 		c = *s1; | 
					
						
							|  |  |  | 		*s1 = '\0'; | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 		ast_verbose("%s", s); | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 		*s1 = c; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-11 04:06:44 +00:00
										 |  |  | 	ast_free(str); | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	string = PString(); | 
					
						
							| 
									
										
										
										
											2005-04-29 04:22:47 +00:00
										 |  |  | 	char *base = string.GetPointer(2000); | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	setp(base, base + string.GetSize() - 1); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | static ostream &my_endl(ostream &os) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (logstream) { | 
					
						
							|  |  |  | 		PTrace::SetOptions(traceOptions); | 
					
						
							|  |  |  | 		return PTrace::End(os); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return endl(os); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define cout \
 | 
					
						
							|  |  |  | 	(logstream ? (PTrace::ClearOptions((unsigned)-1), PTrace::Begin(0, __FILE__, __LINE__)) : std::cout) | 
					
						
							|  |  |  | #define endl my_endl
 | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | void MyProcess::Main() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	PTrace::Initialise(PTrace::GetLevel(), NULL, traceOptions); | 
					
						
							|  |  |  | 	PTrace::SetStream(logstream); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	cout << "  == Creating H.323 Endpoint" << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (endPoint) { | 
					
						
							|  |  |  | 		cout << "  == ENDPOINT ALREADY CREATED" << endl; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	endPoint = new MyH323EndPoint(); | 
					
						
							| 
									
										
										
										
											2005-11-03 01:41:32 +00:00
										 |  |  | 	/* Due to a bug in the H.323 recomendation/stack we should request a sane
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	   amount of bandwidth from the GK - this function is ignored if not using a GK | 
					
						
							| 
									
										
										
										
											2005-11-03 01:41:32 +00:00
										 |  |  | 	   We are requesting 128 (64k in each direction), which is the worst case codec. */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	endPoint->SetInitialBandwidth(1280); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | void PAssertFunc(const char *msg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ast_log(LOG_ERROR, "%s\n", msg); | 
					
						
							|  |  |  | 	/* XXX: Probably we need to crash here */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** MyH323EndPoint
 | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  |   */ | 
					
						
							|  |  |  | MyH323EndPoint::MyH323EndPoint() | 
					
						
							|  |  |  | 		: H323EndPoint() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-28 17:36:33 +00:00
										 |  |  | 	/* Capabilities will be negotiated on per-connection basis */ | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	capabilities.RemoveAll(); | 
					
						
							| 
									
										
										
										
											2006-09-28 17:36:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Reset call setup timeout to some more reasonable value than 1 minute */ | 
					
						
							|  |  |  | 	signallingChannelCallTimeout = PTimeInterval(0, 0, 10);	/* 10 minutes */ | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** The fullAddress parameter is used directly in the MakeCall method so
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |   * the General form for the fullAddress argument is : | 
					
						
							|  |  |  |   * [alias@][transport$]host[:port] | 
					
						
							|  |  |  |   * default values:	alias = the same value as host. | 
					
						
							|  |  |  |   *					transport = ip. | 
					
						
							|  |  |  |   *					port = 1720. | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | int MyH323EndPoint::MyMakeCall(const PString & dest, PString & token, void *_callReference, void *_opts) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PString fullAddress; | 
					
						
							| 
									
										
										
										
											2003-05-12 03:57:43 +00:00
										 |  |  | 	MyH323Connection * connection; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	H323Transport *transport = NULL; | 
					
						
							|  |  |  | 	unsigned int *callReference = (unsigned int *)_callReference; | 
					
						
							|  |  |  | 	call_options_t *opts = (call_options_t *)_opts; | 
					
						
							| 
									
										
										
										
											2003-05-12 03:57:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	/* Determine whether we are using a gatekeeper or not. */ | 
					
						
							| 
									
										
										
										
											2004-10-22 19:04:02 +00:00
										 |  |  | 	if (GetGatekeeper()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		fullAddress = dest; | 
					
						
							| 
									
										
										
										
											2004-09-30 19:30:49 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			cout << " -- Making call to " << fullAddress << " using gatekeeper." << endl; | 
					
						
							| 
									
										
										
										
											2004-09-30 19:30:49 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		fullAddress = dest; | 
					
						
							| 
									
										
										
										
											2004-09-30 19:30:49 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-11-11 21:30:30 +00:00
										 |  |  | 			cout << " -- Making call to " << fullAddress << " without gatekeeper." << endl; | 
					
						
							| 
									
										
										
										
											2004-09-30 19:30:49 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		/* Use bindaddr for outgoing calls too if we don't use gatekeeper */ | 
					
						
							|  |  |  | 		if (listeners.GetSize() > 0) { | 
					
						
							|  |  |  | 			H323TransportAddress taddr = listeners[0].GetTransportAddress(); | 
					
						
							|  |  |  | 			PIPSocket::Address addr; | 
					
						
							|  |  |  | 			WORD port; | 
					
						
							|  |  |  | 			if (taddr.GetIpAndPort(addr, port)) { | 
					
						
							|  |  |  | 				/* Create own transport for specific addresses only */ | 
					
						
							|  |  |  | 				if (addr) { | 
					
						
							|  |  |  | 					if (h323debug) | 
					
						
							|  |  |  | 						cout << "Using " << addr << " for outbound call" << endl; | 
					
						
							|  |  |  | 					transport = new MyH323TransportTCP(*this, addr); | 
					
						
							|  |  |  | 					if (!transport) | 
					
						
							|  |  |  | 						cout << "Unable to create transport for outgoing call" << endl; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 				cout << "Unable to get address and port" << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-07-23 02:27:44 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (!(connection = (MyH323Connection *)H323EndPoint::MakeCallLocked(fullAddress, token, opts, transport))) { | 
					
						
							| 
									
										
										
										
											2004-09-30 19:30:49 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			cout << "Error making call to \"" << fullAddress << '"' << endl; | 
					
						
							| 
									
										
										
										
											2004-09-30 19:30:49 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	*callReference = connection->GetCallReference(); | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		cout << "\t-- " << GetLocalUserName() << " is calling host " << fullAddress << endl; | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 		cout << "\t-- Call token is " << (const char *)token << endl; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		cout << "\t-- Call reference is " << *callReference << endl; | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #ifdef PTRACING
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 		cout << "\t-- DTMF Payload is " << connection->dtmfCodec << endl; | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	connection->Unlock(); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323EndPoint::SetEndpointTypeInfo( H225_EndpointType & info ) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	H323EndPoint::SetEndpointTypeInfo(info); | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (terminalType == e_GatewayOnly){ | 
					
						
							|  |  |  | 		info.RemoveOptionalField(H225_EndpointType::e_terminal); | 
					
						
							|  |  |  | 		info.IncludeOptionalField(H225_EndpointType::e_gateway); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	info.m_gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol); | 
					
						
							|  |  |  | 	info.m_gateway.m_protocol.SetSize(1); | 
					
						
							|  |  |  | 	H225_SupportedProtocols &protocol=info.m_gateway.m_protocol[0]; | 
					
						
							|  |  |  | 	protocol.SetTag(H225_SupportedProtocols::e_voice); | 
					
						
							|  |  |  | 	PINDEX as=SupportedPrefixes.GetSize(); | 
					
						
							|  |  |  | 	((H225_VoiceCaps &)protocol).m_supportedPrefixes.SetSize(as); | 
					
						
							|  |  |  | 	for (PINDEX p=0; p<as; p++) { | 
					
						
							| 
									
										
										
										
											2005-11-03 01:41:32 +00:00
										 |  |  | 		H323SetAliasAddress(SupportedPrefixes[p], ((H225_VoiceCaps &)protocol).m_supportedPrefixes[p].m_prefix, H225_AliasAddress::e_dialedDigits); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323EndPoint::SetGateway(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	terminalType = e_GatewayOnly; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323EndPoint::ClearCall(const PString & token, H323Connection::CallEndReason reason) | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #ifdef PTRACING
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 		cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause " << reason << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 		cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause [" << (int)reason << "]" << endl; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return H323EndPoint::ClearCall(token, reason); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323EndPoint::ClearCall(const PString & token) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		cout << "\t-- ClearCall: Request to clear call with token " << token << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-16 04:25:49 +00:00
										 |  |  | 	return H323EndPoint::ClearCall(token, H323Connection::EndedByLocalUser); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323EndPoint::SendUserTone(const PString &token, char tone) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	H323Connection *connection = NULL; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	connection = FindConnectionWithLock(token); | 
					
						
							|  |  |  | 	if (connection != NULL) { | 
					
						
							|  |  |  | 		connection->SendUserInputTone(tone, 500); | 
					
						
							|  |  |  | 		connection->Unlock(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H323Channel & channel) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	channelsOpen--; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t\tchannelsOpen = " << channelsOpen << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	H323EndPoint::OnClosedLogicalChannel(connection, channel); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323EndPoint::OnConnectionForwarded(H323Connection & connection, | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		const PString & forwardParty, | 
					
						
							|  |  |  | 		const H323SignalPDU & pdu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t-- Call Forwarded to " << forwardParty << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	return FALSE; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323EndPoint::ForwardConnection(H323Connection & connection, | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		const PString & forwardParty, | 
					
						
							|  |  |  | 		const H323SignalPDU & pdu) | 
					
						
							| 
									
										
										
										
											2003-09-06 20:29:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t-- Forwarding call to " << forwardParty << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	return H323EndPoint::ForwardConnection(connection, forwardParty, pdu); | 
					
						
							| 
									
										
										
										
											2003-09-06 20:29:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-09-21 18:42:37 +00:00
										 |  |  | 		cout << "\t=-= In OnConnectionEstablished for call " << connection.GetCallReference() << endl; | 
					
						
							|  |  |  | 		cout << "\t\t-- Connection Established with \"" << connection.GetRemotePartyName() << "\"" << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-09-19 16:53:01 +00:00
										 |  |  | 	on_connection_established(connection.GetCallReference(), (const char *)connection.GetCallToken()); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** OnConnectionCleared callback function is called upon the dropping of an established
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |   * H323 connection. | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |   */ | 
					
						
							|  |  |  | void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-05-19 16:17:08 +00:00
										 |  |  | 	PString remoteName = connection.GetRemotePartyName(); | 
					
						
							| 
									
										
										
										
											2004-05-18 10:32:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	switch (connection.GetCallEndReason()) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByCallForwarded: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " has forwarded the call" << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByRemoteUser: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " has cleared the call" << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByCallerAbort: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " has stopped calling" << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByRefusal: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " did not accept your call" << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByRemoteBusy: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " was busy" << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByRemoteCongestion: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Congested link to " << remoteName << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByNoAnswer: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " did not answer your call" << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByTransportFail: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Call with " << remoteName << " ended abnormally" << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByCapabilityExchange: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Could not find common codec with " << remoteName << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByNoAccept: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Did not accept incoming call from " << remoteName << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByAnswerDenied: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Refused incoming call from " << remoteName << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByNoUser: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Remote endpoint could not find user: " << remoteName << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByNoBandwidth: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Call to " << remoteName << " aborted, insufficient bandwidth." << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByUnreachable: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " could not be reached." << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByHostOffline: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- " << remoteName << " is not online." << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByNoEndPoint: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- No phone running for " << remoteName << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		case H323Connection::EndedByConnectFail: | 
					
						
							|  |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | 				cout << "-- Transport error calling " << remoteName << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			if (h323debug) { | 
					
						
							|  |  |  | #ifdef PTRACING
 | 
					
						
							| 
									
										
										
										
											2004-01-06 16:43:24 +00:00
										 |  |  | 				cout << " -- Call with " << remoteName << " completed (" << connection.GetCallEndReason() << ")" << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 				cout << " -- Call with " << remoteName << " completed ([" << (int)connection.GetCallEndReason() << "])" << endl; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-01-06 16:43:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	if (connection.IsEstablished()) { | 
					
						
							|  |  |  | 		if (h323debug) { | 
					
						
							|  |  |  | 			cout << "\t-- Call duration " << setprecision(0) << setw(5) << (PTime() - connection.GetConnectionStartTime()) << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-05-18 10:32:34 +00:00
										 |  |  | 	/* Invoke the PBX application registered callback */ | 
					
						
							| 
									
										
										
										
											2005-05-19 16:17:08 +00:00
										 |  |  | 	on_connection_cleared(connection.GetCallReference(), clearedCallToken); | 
					
						
							| 
									
										
										
										
											2004-05-18 10:32:34 +00:00
										 |  |  | 	return; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference, void *userData, H323Transport *transport, H323SignalPDU *setupPDU) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned options = 0; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	call_options_t *opts = (call_options_t *)userData; | 
					
						
							|  |  |  | 	MyH323Connection *conn; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (opts && opts->fastStart) { | 
					
						
							| 
									
										
										
										
											2004-09-21 18:42:37 +00:00
										 |  |  | 		options |= H323Connection::FastStartOptionEnable; | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		options |= H323Connection::FastStartOptionDisable; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (opts && opts->h245Tunneling) { | 
					
						
							| 
									
										
										
										
											2004-09-21 18:42:37 +00:00
										 |  |  | 		options |= H323Connection::H245TunnelingOptionEnable; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		options |= H323Connection::H245TunnelingOptionDisable; | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | /* Disable until I can figure out the proper way to deal with this */ | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (opts->silenceSuppression) { | 
					
						
							|  |  |  | 		options |= H323Connection::SilenceSuppresionOptionEnable; | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		options |= H323Connection::SilenceSUppressionOptionDisable; | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	conn = new MyH323Connection(*this, callReference, options); | 
					
						
							|  |  |  | 	if (conn) { | 
					
						
							|  |  |  | 		if (opts) | 
					
						
							|  |  |  | 			conn->SetCallOptions(opts, (setupPDU ? TRUE : FALSE)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return conn; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | /* MyH323Connection Implementation */ | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference, | 
					
						
							|  |  |  | 							unsigned options) | 
					
						
							|  |  |  | 	: H323Connection(ep, callReference, options) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | 	/* Dispatcher will free out all registered handlers */ | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 	delete h450dispatcher; | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | 	h450dispatcher = new H450xDispatcher(*this); | 
					
						
							|  |  |  | 	h4502handler = new H4502Handler(*this, *h450dispatcher); | 
					
						
							|  |  |  | 	h4504handler = new MyH4504Handler(*this, *h450dispatcher); | 
					
						
							|  |  |  | 	h4506handler = new H4506Handler(*this, *h450dispatcher); | 
					
						
							|  |  |  | 	h45011handler = new H45011Handler(*this, *h450dispatcher); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	cause = -1; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	sessionId = 0; | 
					
						
							|  |  |  | 	bridging = FALSE; | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | 	holdHandling = progressSetup = progressAlert = 0; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	dtmfMode = 0; | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 	dtmfCodec[0] = dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)0; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	redirect_reason = -1; | 
					
						
							| 
									
										
										
										
											2006-10-07 14:48:32 +00:00
										 |  |  | 	transfer_capability = -1; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #ifdef TUNNELLING
 | 
					
						
							|  |  |  | 	tunnelOptions = remoteTunnelOptions = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << "	== New H.323 Connection created." << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MyH323Connection::~MyH323Connection() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << "	== H.323 Connection deleted." << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnReceivedProgress(const H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	PBoolean isInband; | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	unsigned pi; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!H323Connection::OnReceivedProgress(pdu)) { | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!pdu.GetQ931().GetProgressIndicator(pi)) | 
					
						
							|  |  |  | 		pi = 0; | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t- Progress Indicator: " << pi << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	switch(pi) { | 
					
						
							|  |  |  | 	case Q931::ProgressNotEndToEndISDN: | 
					
						
							|  |  |  | 	case Q931::ProgressInbandInformationAvailable: | 
					
						
							|  |  |  | 		isInband = TRUE; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		isInband = FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	on_progress(GetCallReference(), (const char *)GetCallToken(), isInband); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	return connectionState != ShuttingDownConnection; | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::MySendProgress() | 
					
						
							| 
									
										
										
										
											2006-09-28 13:02:30 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* The code taken from H323Connection::AnsweringCall() but ALWAYS send
 | 
					
						
							|  |  |  | 	   PROGRESS message, including slow start operations */ | 
					
						
							|  |  |  | 	H323SignalPDU progressPDU; | 
					
						
							|  |  |  | 	H225_Progress_UUIE &prog = progressPDU.BuildProgress(*this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!mediaWaitForConnect) { | 
					
						
							|  |  |  | 		if (SendFastStartAcknowledge(prog.m_fastStart)) | 
					
						
							|  |  |  | 			prog.IncludeOptionalField(H225_Progress_UUIE::e_fastStart); | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			if (connectionState == ShuttingDownConnection) | 
					
						
							|  |  |  | 				return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Do early H.245 start */ | 
					
						
							|  |  |  | 			earlyStart = TRUE; | 
					
						
							|  |  |  | 			if (!h245Tunneling) { | 
					
						
							|  |  |  | 				if (!H323Connection::StartControlChannel()) | 
					
						
							|  |  |  | 					return FALSE; | 
					
						
							|  |  |  | 				prog.IncludeOptionalField(H225_Progress_UUIE::e_h245Address); | 
					
						
							|  |  |  | 				controlChannel->SetUpTransportPDU(prog.m_h245Address, TRUE); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	progressPDU.GetQ931().SetProgressIndicator(Q931::ProgressInbandInformationAvailable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef TUNNELLING
 | 
					
						
							|  |  |  | 	EmbedTunneledInfo(progressPDU); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	HandleTunnelPDU(&progressPDU); | 
					
						
							|  |  |  | 	WriteSignalPDU(progressPDU); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | H323Connection::AnswerCallResponse MyH323Connection::OnAnswerCall(const PString & caller, | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 								const H323SignalPDU & setupPDU, | 
					
						
							|  |  |  | 								H323SignalPDU & connectPDU) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	unsigned pi; | 
					
						
							| 
									
										
										
										
											2004-09-19 16:53:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		cout << "\t=-= In OnAnswerCall for call " << GetCallReference() << endl; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	if (connectionState == ShuttingDownConnection) | 
					
						
							|  |  |  | 		return H323Connection::AnswerCallDenied; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	if (!setupPDU.GetQ931().GetProgressIndicator(pi)) { | 
					
						
							|  |  |  | 		pi = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t\t- Progress Indicator: " << pi << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (progressAlert) { | 
					
						
							|  |  |  | 		pi = progressAlert; | 
					
						
							|  |  |  | 	} else if (pi == Q931::ProgressOriginNotISDN) { | 
					
						
							|  |  |  | 		pi = Q931::ProgressInbandInformationAvailable; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (pi && alertingPDU) { | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 		alertingPDU->GetQ931().SetProgressIndicator(pi); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t\t- Inserting PI of " << pi << " into ALERTING message" << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #ifdef TUNNELLING
 | 
					
						
							|  |  |  | 	if (alertingPDU) | 
					
						
							|  |  |  | 		EmbedTunneledInfo(*alertingPDU); | 
					
						
							|  |  |  | 	EmbedTunneledInfo(connectPDU); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | 	if (!on_answer_call(GetCallReference(), (const char *)GetCallToken())) { | 
					
						
							| 
									
										
										
										
											2004-06-15 20:56:06 +00:00
										 |  |  | 		return H323Connection::AnswerCallDenied; | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	/* The call will be answered later with "AnsweringCall()" function.
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	return ((pi || (fastStartState != FastStartDisabled)) ? AnswerCallDeferredWithMedia : AnswerCallDeferred); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnAlerting(const H323SignalPDU & alertingPDU, const PString & username) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		cout << "\t=-= In OnAlerting for call " << GetCallReference() | 
					
						
							|  |  |  | 			<< ": sessionId=" << sessionId << endl; | 
					
						
							|  |  |  | 		cout << "\t-- Ringing phone for \"" << username << "\"" << endl; | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (on_progress) { | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 		PBoolean isInband; | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 		unsigned alertingPI; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!alertingPDU.GetQ931().GetProgressIndicator(alertingPI)) { | 
					
						
							|  |  |  | 			alertingPI = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (h323debug) { | 
					
						
							|  |  |  | 			cout << "\t\t- Progress Indicator: " << alertingPI << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 		switch(alertingPI) { | 
					
						
							|  |  |  | 		case Q931::ProgressNotEndToEndISDN: | 
					
						
							|  |  |  | 		case Q931::ProgressInbandInformationAvailable: | 
					
						
							|  |  |  | 			isInband = TRUE; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			isInband = FALSE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		on_progress(GetCallReference(), (const char *)GetCallToken(), isInband); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	on_chan_ringing(GetCallReference(), (const char *)GetCallToken() ); | 
					
						
							|  |  |  | 	return connectionState != ShuttingDownConnection; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | void MyH323Connection::SetCallOptions(void *o, PBoolean isIncoming) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	call_options_t *opts = (call_options_t *)o; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	progressSetup = opts->progress_setup; | 
					
						
							|  |  |  | 	progressAlert = opts->progress_alert; | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | 	holdHandling = opts->holdHandling; | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 	dtmfCodec[0] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[0]; | 
					
						
							|  |  |  | 	dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[1]; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	dtmfMode = opts->dtmfmode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (isIncoming) { | 
					
						
							|  |  |  | 		fastStartState = (opts->fastStart ? FastStartInitiate : FastStartDisabled); | 
					
						
							|  |  |  | 		h245Tunneling = (opts->h245Tunneling ? TRUE : FALSE); | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2008-02-19 20:31:15 +00:00
										 |  |  | 		sourceE164 = PString(opts->cid_num); | 
					
						
							|  |  |  | 		SetLocalPartyName(PString(opts->cid_name)); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		SetDisplayName(PString(opts->cid_name)); | 
					
						
							|  |  |  | 		if (opts->redirect_reason >= 0) { | 
					
						
							|  |  |  | 			rdnis = PString(opts->cid_rdnis); | 
					
						
							|  |  |  | 			redirect_reason = opts->redirect_reason; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 		cid_presentation = opts->presentation; | 
					
						
							|  |  |  | 		cid_ton = opts->type_of_number; | 
					
						
							| 
									
										
										
										
											2006-10-07 14:48:32 +00:00
										 |  |  | 		if (opts->transfer_capability >= 0) { | 
					
						
							|  |  |  | 			transfer_capability = opts->transfer_capability; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	tunnelOptions = opts->tunnelOptions; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | void MyH323Connection::SetCallDetails(void *callDetails, const H323SignalPDU &setupPDU, PBoolean isIncoming) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PString sourceE164; | 
					
						
							|  |  |  | 	PString destE164; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	PString sourceAliases; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	PString destAliases; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	char *s, *s1; | 
					
						
							|  |  |  | 	call_details_t *cd = (call_details_t *)callDetails; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	memset(cd, 0, sizeof(*cd)); | 
					
						
							|  |  |  | 	cd->call_reference = GetCallReference(); | 
					
						
							|  |  |  | 	cd->call_token = strdup((const char *)GetCallToken()); | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	sourceE164 = ""; | 
					
						
							|  |  |  | 	setupPDU.GetSourceE164(sourceE164); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	cd->call_source_e164 = strdup((const char *)sourceE164); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	destE164 = ""; | 
					
						
							|  |  |  | 	setupPDU.GetDestinationE164(destE164); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	cd->call_dest_e164 = strdup((const char *)destE164); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* XXX Is it possible to have this information for outgoing calls too? XXX */ | 
					
						
							|  |  |  | 	if (isIncoming) { | 
					
						
							|  |  |  | 		PString sourceName; | 
					
						
							|  |  |  | 		PIPSocket::Address Ip; | 
					
						
							|  |  |  | 		WORD sourcePort; | 
					
						
							|  |  |  | 		PString redirect_number; | 
					
						
							|  |  |  | 		unsigned redirect_reason; | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 		unsigned plan, type, screening, presentation; | 
					
						
							| 
									
										
										
										
											2006-10-07 14:48:32 +00:00
										 |  |  | 		Q931::InformationTransferCapability capability; | 
					
						
							|  |  |  | 		unsigned transferRate, codingStandard, userInfoLayer1; | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* Fetch presentation and type information about calling party's number */ | 
					
						
							| 
									
										
										
										
											2006-10-03 18:47:38 +00:00
										 |  |  | 		if (setupPDU.GetQ931().GetCallingPartyNumber(sourceName, &plan, &type, &presentation, &screening, 0, 0)) { | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 			/* Construct fields back */ | 
					
						
							| 
									
										
										
										
											2006-10-03 18:47:38 +00:00
										 |  |  | 			cd->type_of_number = (type << 4) | plan; | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 			cd->presentation = (presentation << 5) | screening; | 
					
						
							| 
									
										
										
										
											2006-09-29 21:13:46 +00:00
										 |  |  | 		} else if (cd->call_source_e164[0]) { | 
					
						
							|  |  |  | 			cd->type_of_number = 0;		/* UNKNOWN */ | 
					
						
							|  |  |  | 			cd->presentation = 0x03;	/* ALLOWED NETWORK NUMBER - Default */ | 
					
						
							|  |  |  | 			if (setupPDU.GetQ931().HasIE(Q931::UserUserIE)) { | 
					
						
							|  |  |  | 				const H225_Setup_UUIE &setup_uuie = setupPDU.m_h323_uu_pdu.m_h323_message_body; | 
					
						
							|  |  |  | 				if (setup_uuie.HasOptionalField(H225_Setup_UUIE::e_presentationIndicator)) | 
					
						
							|  |  |  | 					cd->presentation = (cd->presentation & 0x9f) | (((unsigned int)setup_uuie.m_presentationIndicator.GetTag()) << 5); | 
					
						
							|  |  |  | 				if (setup_uuie.HasOptionalField(H225_Setup_UUIE::e_screeningIndicator)) | 
					
						
							|  |  |  | 					cd->presentation = (cd->presentation & 0xe0) | (((unsigned int)setup_uuie.m_screeningIndicator.GetValue()) & 0x1f); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			cd->type_of_number = 0;		/* UNKNOWN */ | 
					
						
							|  |  |  | 			cd->presentation = 0x43;	/* NUMBER NOT AVAILABLE */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		sourceName = setupPDU.GetQ931().GetDisplayName(); | 
					
						
							|  |  |  | 		cd->call_source_name = strdup((const char *)sourceName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort); | 
					
						
							|  |  |  | 		cd->sourceIp = strdup((const char *)Ip.AsString()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-07 14:48:32 +00:00
										 |  |  | 		if (setupPDU.GetQ931().GetRedirectingNumber(redirect_number, NULL, NULL, NULL, NULL, &redirect_reason, 0, 0, 0)) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			cd->redirect_number = strdup((const char *)redirect_number); | 
					
						
							|  |  |  | 			cd->redirect_reason = redirect_reason; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			cd->redirect_reason = -1; | 
					
						
							| 
									
										
										
										
											2006-09-29 21:13:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-07 14:48:32 +00:00
										 |  |  | 		/* Fetch Q.931's transfer capability */ | 
					
						
							|  |  |  | 		if (((Q931 &)setupPDU.GetQ931()).GetBearerCapabilities(capability, transferRate, &codingStandard, &userInfoLayer1)) | 
					
						
							|  |  |  | 			cd->transfer_capability = ((unsigned int)capability & 0x1f) | (codingStandard << 5); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			cd->transfer_capability = 0x00;	/* ITU coding of Speech */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Don't show local username as called party name */ | 
					
						
							| 
									
										
										
										
											2006-09-29 21:13:46 +00:00
										 |  |  | 		SetDisplayName(cd->call_dest_e164); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-24 22:38:24 +00:00
										 |  |  | 	/* Convert complex strings */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	//  FIXME: deal more than one source alias
 | 
					
						
							|  |  |  | 	sourceAliases = setupPDU.GetSourceAliases(); | 
					
						
							|  |  |  | 	s1 = strdup((const char *)sourceAliases); | 
					
						
							|  |  |  | 	if ((s = strchr(s1, ' ')) != NULL) | 
					
						
							|  |  |  | 		*s = '\0'; | 
					
						
							|  |  |  | 	if ((s = strchr(s1, '\t')) != NULL) | 
					
						
							|  |  |  | 		*s = '\0'; | 
					
						
							|  |  |  | 	cd->call_source_aliases = s1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	destAliases = setupPDU.GetDestinationAlias(); | 
					
						
							|  |  |  | 	s1 = strdup((const char *)destAliases); | 
					
						
							|  |  |  | 	if ((s = strchr(s1, ' ')) != NULL) | 
					
						
							|  |  |  | 		*s = '\0'; | 
					
						
							|  |  |  | 	if ((s = strchr(s1, '\t')) != NULL) | 
					
						
							|  |  |  | 		*s = '\0'; | 
					
						
							|  |  |  | 	cd->call_dest_alias = s1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef TUNNELLING
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | static PBoolean FetchInformationElements(Q931 &q931, const PBYTEArray &data) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PINDEX offset = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (offset < data.GetSize()) { | 
					
						
							|  |  |  | 		// Get field discriminator
 | 
					
						
							|  |  |  | 		int discriminator = data[offset++]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 		/* Do not overwrite existing IEs */ | 
					
						
							|  |  |  | 		if (q931.HasIE((Q931::InformationElementCodes)discriminator)) { | 
					
						
							|  |  |  | 			if ((discriminatir & 0x80) == 0) | 
					
						
							|  |  |  | 				offset += data[offset++]; | 
					
						
							|  |  |  | 			if (offset > data.GetSize()) | 
					
						
							|  |  |  | 				return FALSE; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PBYTEArray * item = new PBYTEArray; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// For discriminator with high bit set there is no data
 | 
					
						
							|  |  |  | 		if ((discriminator & 0x80) == 0) { | 
					
						
							|  |  |  | 			int len = data[offset++]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0		// That is not H.225 but regular Q.931 (ISDN) IEs
 | 
					
						
							|  |  |  | 			if (discriminator == UserUserIE) { | 
					
						
							|  |  |  | 				// Special case of User-user field. See 7.2.2.31/H.225.0v4.
 | 
					
						
							|  |  |  | 				len <<= 8; | 
					
						
							|  |  |  | 				len |= data[offset++]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// we also have a protocol discriminator, which we ignore
 | 
					
						
							|  |  |  | 				offset++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// before decrementing the length, make sure it is not zero
 | 
					
						
							|  |  |  | 				if (len == 0) | 
					
						
							|  |  |  | 					return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// adjust for protocol discriminator
 | 
					
						
							|  |  |  | 				len--; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (offset + len > data.GetSize()) { | 
					
						
							|  |  |  | 				delete item; | 
					
						
							|  |  |  | 				return FALSE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			memcpy(item->GetPointer(len), (const BYTE *)data+offset, len); | 
					
						
							|  |  |  | 			offset += len; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		q931.SetIE((Q931::InformationElementCodes)discriminator, *item); | 
					
						
							|  |  |  | 		delete item; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | static PBoolean FetchCiscoTunneledInfo(Q931 &q931, const H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	PBoolean res = FALSE; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) { | 
					
						
							|  |  |  | 		for(int i = 0; i < uuPDU.m_nonStandardControl.GetSize(); ++i) { | 
					
						
							|  |  |  | 			const H225_NonStandardParameter &np = uuPDU.m_nonStandardControl[i]; | 
					
						
							|  |  |  | 			const H225_NonStandardIdentifier &id = np.m_nonStandardIdentifier; | 
					
						
							|  |  |  | 			if (id.GetTag() == H225_NonStandardIdentifier::e_h221NonStandard) { | 
					
						
							|  |  |  | 				const H225_H221NonStandard &ni = id; | 
					
						
							|  |  |  | 				/* Check for Cisco */ | 
					
						
							|  |  |  | 				if ((ni.m_t35CountryCode == 181) && (ni.m_t35Extension == 0) && (ni.m_manufacturerCode == 18)) { | 
					
						
							|  |  |  | 					const PBYTEArray &data = np.m_data; | 
					
						
							|  |  |  | 					if (h323debug) | 
					
						
							|  |  |  | 						cout << setprecision(0) << "Received non-standard Cisco extension data " << np.m_data << endl; | 
					
						
							|  |  |  | 					CISCO_H225_H323_UU_NonStdInfo c; | 
					
						
							|  |  |  | 					PPER_Stream strm(data); | 
					
						
							|  |  |  | 					if (c.Decode(strm)) { | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 						PBoolean haveIEs = FALSE; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 						if (h323debug) | 
					
						
							|  |  |  | 							cout << setprecision(0) << "H323_UU_NonStdInfo = " << c << endl; | 
					
						
							|  |  |  | 						if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam)) { | 
					
						
							|  |  |  | 							FetchInformationElements(q931, c.m_protoParam.m_qsigNonStdInfo.m_rawMesg); | 
					
						
							|  |  |  | 							haveIEs = TRUE; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam)) { | 
					
						
							|  |  |  | 							FetchInformationElements(q931, c.m_commonParam.m_redirectIEinfo.m_redirectIE); | 
					
						
							|  |  |  | 							haveIEs = TRUE; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (haveIEs && h323debug) | 
					
						
							|  |  |  | 							cout << setprecision(0) << "Information elements collected:" << q931 << endl; | 
					
						
							|  |  |  | 						res = TRUE; | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						cout << "ERROR while decoding non-standard Cisco extension" << endl; | 
					
						
							|  |  |  | 						return FALSE; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | static PBoolean EmbedCiscoTunneledInfo(H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-14 15:44:07 +00:00
										 |  |  | 	static const struct { | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 		Q931::InformationElementCodes ie; | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 		PBoolean dontDelete; | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 	} codes[] = { | 
					
						
							|  |  |  | 		{ Q931::RedirectingNumberIE, }, | 
					
						
							|  |  |  | 		{ Q931::FacilityIE, }, | 
					
						
							| 
									
										
										
										
											2006-09-29 19:13:26 +00:00
										 |  |  | //		{ Q931::CallingPartyNumberIE, TRUE },
 | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	PBoolean res = FALSE; | 
					
						
							|  |  |  | 	PBoolean notRedirOnly = FALSE; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	Q931 tmpQ931; | 
					
						
							|  |  |  | 	Q931 &q931 = pdu.GetQ931(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-08 16:40:28 +00:00
										 |  |  | 	for(unsigned i = 0; i < ARRAY_LEN(codes); ++i) { | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 		if (q931.HasIE(codes[i].ie)) { | 
					
						
							|  |  |  | 			tmpQ931.SetIE(codes[i].ie, q931.GetIE(codes[i].ie)); | 
					
						
							|  |  |  | 			if (!codes[i].dontDelete) | 
					
						
							|  |  |  | 				q931.RemoveIE(codes[i].ie); | 
					
						
							|  |  |  | 			if (codes[i].ie != Q931::RedirectingNumberIE) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 				notRedirOnly = TRUE; | 
					
						
							|  |  |  | 			res = TRUE; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	/* Have something to embed */ | 
					
						
							|  |  |  | 	if (res) { | 
					
						
							|  |  |  | 		PBYTEArray msg; | 
					
						
							|  |  |  | 		if (!tmpQ931.Encode(msg)) | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 		PBYTEArray ies(msg.GetPointer() + 5, msg.GetSize() - 5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; | 
					
						
							|  |  |  | 		if(!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) { | 
					
						
							|  |  |  | 			uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_nonStandardControl); | 
					
						
							|  |  |  | 			uuPDU.m_nonStandardControl.SetSize(0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		H225_NonStandardParameter *np = new H225_NonStandardParameter; | 
					
						
							|  |  |  | 		uuPDU.m_nonStandardControl.Append(np); | 
					
						
							|  |  |  | 		H225_NonStandardIdentifier &nsi = (*np).m_nonStandardIdentifier; | 
					
						
							|  |  |  | 		nsi.SetTag(H225_NonStandardIdentifier::e_h221NonStandard); | 
					
						
							|  |  |  | 		H225_H221NonStandard &ns = nsi; | 
					
						
							|  |  |  | 		ns.m_t35CountryCode = 181; | 
					
						
							|  |  |  | 		ns.m_t35Extension = 0; | 
					
						
							|  |  |  | 		ns.m_manufacturerCode = 18; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		CISCO_H225_H323_UU_NonStdInfo c; | 
					
						
							|  |  |  | 		c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_version); | 
					
						
							|  |  |  | 		c.m_version = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (notRedirOnly) { | 
					
						
							|  |  |  | 			c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam); | 
					
						
							|  |  |  | 			CISCO_H225_QsigNonStdInfo &qsigInfo = c.m_protoParam.m_qsigNonStdInfo; | 
					
						
							|  |  |  | 			qsigInfo.m_iei = ies[0]; | 
					
						
							|  |  |  | 			qsigInfo.m_rawMesg = ies; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam); | 
					
						
							|  |  |  | 			c.m_commonParam.m_redirectIEinfo.m_redirectIE = ies; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PPER_Stream stream; | 
					
						
							|  |  |  | 		c.Encode(stream); | 
					
						
							|  |  |  | 		stream.CompleteEncoding(); | 
					
						
							|  |  |  | 		(*np).m_data = stream; | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char OID_QSIG[] = "1.3.12.9"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | static PBoolean FetchQSIGTunneledInfo(Q931 &q931, const H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	PBoolean res = FALSE; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; | 
					
						
							|  |  |  | 	if (uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage)) { | 
					
						
							|  |  |  | 		const H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage; | 
					
						
							|  |  |  | 		const H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id; | 
					
						
							|  |  |  | 		if ((proto.GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) && | 
					
						
							|  |  |  | 				(((const PASN_ObjectId &)proto).AsString() == OID_QSIG)) { | 
					
						
							|  |  |  | 			const H225_ArrayOf_PASN_OctetString &sigs = sig.m_messageContent; | 
					
						
							|  |  |  | 			for(int i = 0; i < sigs.GetSize(); ++i) { | 
					
						
							|  |  |  | 				const PASN_OctetString &msg = sigs[i]; | 
					
						
							|  |  |  | 				if (h323debug) | 
					
						
							|  |  |  | 					cout << setprecision(0) << "Q.931 message data is " << msg << endl; | 
					
						
							|  |  |  | 				if(!q931.Decode((const PBYTEArray &)msg)) { | 
					
						
							|  |  |  | 					cout << "Error while decoding Q.931 message" << endl; | 
					
						
							|  |  |  | 					return FALSE; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				res = TRUE; | 
					
						
							|  |  |  | 				if (h323debug) | 
					
						
							|  |  |  | 					cout << setprecision(0) << "Received QSIG message " << q931 << endl; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | static H225_EndpointType *GetEndpointType(H323SignalPDU &pdu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!pdu.GetQ931().HasIE(Q931::UserUserIE)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2004-05-18 10:32:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	H225_H323_UU_PDU_h323_message_body &body = pdu.m_h323_uu_pdu.m_h323_message_body; | 
					
						
							|  |  |  | 	switch (body.GetTag()) { | 
					
						
							|  |  |  | 	case H225_H323_UU_PDU_h323_message_body::e_setup: | 
					
						
							|  |  |  | 		return &((H225_Setup_UUIE &)body).m_sourceInfo; | 
					
						
							|  |  |  | 	case H225_H323_UU_PDU_h323_message_body::e_callProceeding: | 
					
						
							|  |  |  | 		return &((H225_CallProceeding_UUIE &)body).m_destinationInfo; | 
					
						
							|  |  |  | 	case H225_H323_UU_PDU_h323_message_body::e_connect: | 
					
						
							|  |  |  | 		return &((H225_Connect_UUIE &)body).m_destinationInfo; | 
					
						
							|  |  |  | 	case H225_H323_UU_PDU_h323_message_body::e_alerting: | 
					
						
							|  |  |  | 		return &((H225_Alerting_UUIE &)body).m_destinationInfo; | 
					
						
							|  |  |  | 	case H225_H323_UU_PDU_h323_message_body::e_facility: | 
					
						
							|  |  |  | 		return &((H225_Facility_UUIE &)body).m_destinationInfo; | 
					
						
							|  |  |  | 	case H225_H323_UU_PDU_h323_message_body::e_progress: | 
					
						
							|  |  |  | 		return &((H225_Progress_UUIE &)body).m_destinationInfo; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | static PBoolean QSIGTunnelRequested(H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	H225_EndpointType *epType = GetEndpointType(pdu); | 
					
						
							|  |  |  | 	if (epType) { | 
					
						
							|  |  |  | 		if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) { | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols; | 
					
						
							|  |  |  | 		for (int i = 0; i < protos.GetSize(); ++i) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) && | 
					
						
							|  |  |  | 					(((const PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) { | 
					
						
							|  |  |  | 				return TRUE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | static PBoolean EmbedQSIGTunneledInfo(H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-14 15:44:07 +00:00
										 |  |  | 	static const Q931::InformationElementCodes codes[] = | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	{ Q931::RedirectingNumberIE, Q931::FacilityIE }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Q931 &q931 = pdu.GetQ931(); | 
					
						
							|  |  |  | 	PBYTEArray message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	q931.Encode(message); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Remove non-standard IEs */ | 
					
						
							| 
									
										
										
										
											2008-07-08 16:40:28 +00:00
										 |  |  | 	for(unsigned i = 0; i < ARRAY_LEN(codes); ++i) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		if (q931.HasIE(codes[i])) { | 
					
						
							|  |  |  | 			q931.RemoveIE(codes[i]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; | 
					
						
							|  |  |  | 	H225_EndpointType *epType = GetEndpointType(pdu); | 
					
						
							|  |  |  | 	if (epType) { | 
					
						
							|  |  |  | 		if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) { | 
					
						
							|  |  |  | 			(*epType).IncludeOptionalField(H225_EndpointType::e_supportedTunnelledProtocols); | 
					
						
							|  |  |  | 			(*epType).m_supportedTunnelledProtocols.SetSize(0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols; | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 		PBoolean addQSIG = TRUE; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		for (int i = 0; i < protos.GetSize(); ++i) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) && | 
					
						
							| 
									
										
										
										
											2006-09-28 16:01:48 +00:00
										 |  |  | 					(((PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 				addQSIG = FALSE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (addQSIG) { | 
					
						
							|  |  |  | 			H225_TunnelledProtocol *proto = new H225_TunnelledProtocol; | 
					
						
							|  |  |  | 			(*proto).m_id.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID); | 
					
						
							|  |  |  | 			(PASN_ObjectId &)(proto->m_id) = OID_QSIG; | 
					
						
							|  |  |  | 			protos.Append(proto); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage)) | 
					
						
							|  |  |  | 		uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage); | 
					
						
							|  |  |  | 	H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage; | 
					
						
							|  |  |  | 	H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id; | 
					
						
							|  |  |  | 	if ((proto.GetTag() != H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) || | 
					
						
							|  |  |  | 			(((const PASN_ObjectId &)proto).AsString() != OID_QSIG)) { | 
					
						
							|  |  |  | 		proto.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID); | 
					
						
							|  |  |  | 		(PASN_ObjectId &)proto = OID_QSIG; | 
					
						
							|  |  |  | 		sig.m_messageContent.SetSize(0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	PASN_OctetString *msg = new PASN_OctetString; | 
					
						
							|  |  |  | 	sig.m_messageContent.Append(msg); | 
					
						
							|  |  |  | 	*msg = message; | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::EmbedTunneledInfo(H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if ((tunnelOptions & H323_TUNNEL_QSIG) || (remoteTunnelOptions & H323_TUNNEL_QSIG)) | 
					
						
							|  |  |  | 		EmbedQSIGTunneledInfo(pdu); | 
					
						
							|  |  |  | 	if ((tunnelOptions & H323_TUNNEL_CISCO) || (remoteTunnelOptions & H323_TUNNEL_CISCO)) | 
					
						
							|  |  |  | 		EmbedCiscoTunneledInfo(pdu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Handle tunneled messages */ | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::HandleSignalPDU(H323SignalPDU &pdu) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (pdu.GetQ931().HasIE(Q931::UserUserIE)) { | 
					
						
							|  |  |  | 		Q931 tunneledInfo; | 
					
						
							|  |  |  | 		const Q931 *q931Info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		q931Info = NULL; | 
					
						
							|  |  |  | 		if (FetchCiscoTunneledInfo(tunneledInfo, pdu)) { | 
					
						
							|  |  |  | 			q931Info = &tunneledInfo; | 
					
						
							|  |  |  | 			remoteTunnelOptions |= H323_TUNNEL_CISCO; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (FetchQSIGTunneledInfo(tunneledInfo, pdu)) { | 
					
						
							|  |  |  | 			q931Info = &tunneledInfo; | 
					
						
							|  |  |  | 			remoteTunnelOptions |= H323_TUNNEL_QSIG; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!(remoteTunnelOptions & H323_TUNNEL_QSIG) && QSIGTunnelRequested(pdu)) { | 
					
						
							|  |  |  | 			remoteTunnelOptions |= H323_TUNNEL_QSIG; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (q931Info) { | 
					
						
							|  |  |  | 			if (q931Info->HasIE(Q931::RedirectingNumberIE)) { | 
					
						
							|  |  |  | 				pdu.GetQ931().SetIE(Q931::RedirectingNumberIE, q931Info->GetIE(Q931::RedirectingNumberIE)); | 
					
						
							|  |  |  | 				if (h323debug) { | 
					
						
							|  |  |  | 					PString number; | 
					
						
							|  |  |  | 					unsigned reason; | 
					
						
							|  |  |  | 					if(q931Info->GetRedirectingNumber(number, NULL, NULL, NULL, NULL, &reason, 0, 0, 0)) | 
					
						
							|  |  |  | 						cout << "Got redirection from " << number << ", reason " << reason << endl; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return H323Connection::HandleSignalPDU(pdu); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	call_details_t cd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t--Received SETUP message" << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (connectionState == ShuttingDownConnection) | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetCallDetails(&cd, setupPDU, TRUE); | 
					
						
							| 
									
										
										
										
											2004-05-20 21:56:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	/* Notify Asterisk of the request */ | 
					
						
							| 
									
										
										
										
											2005-05-19 16:17:08 +00:00
										 |  |  | 	call_options_t *res = on_incoming_call(&cd); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!res) { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			cout << "\t-- Call Failed" << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	SetCallOptions(res, TRUE); | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-25 07:50:25 +00:00
										 |  |  | 	/* Disable fastStart if requested by remote side */ | 
					
						
							|  |  |  | 	if (h245Tunneling && !setupPDU.m_h323_uu_pdu.m_h245Tunneling) { | 
					
						
							|  |  |  | 		masterSlaveDeterminationProcedure->Stop(); | 
					
						
							|  |  |  | 		capabilityExchangeProcedure->Stop(); | 
					
						
							|  |  |  | 		PTRACE(3, "H225\tFast Start DISABLED!"); | 
					
						
							|  |  |  | 		h245Tunneling = FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return H323Connection::OnReceivedSignalSetup(setupPDU); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	call_details_t cd; | 
					
						
							| 
									
										
										
										
											2004-05-18 10:32:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t-- Sending SETUP message" << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-16 02:03:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	if (connectionState == ShuttingDownConnection) | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (progressSetup) | 
					
						
							|  |  |  | 		setupPDU.GetQ931().SetProgressIndicator(progressSetup); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (redirect_reason >= 0) { | 
					
						
							|  |  |  | 		setupPDU.GetQ931().SetRedirectingNumber(rdnis, 0, 0, 0, 0, redirect_reason); | 
					
						
							|  |  |  | 		/* OpenH323 incorrectly fills number IE when redirecting reason is specified - fix it */ | 
					
						
							|  |  |  | 		PBYTEArray IE(setupPDU.GetQ931().GetIE(Q931::RedirectingNumberIE)); | 
					
						
							|  |  |  | 		IE[0] = IE[0] & 0x7f; | 
					
						
							|  |  |  | 		IE[1] = IE[1] & 0x7f; | 
					
						
							|  |  |  | 		setupPDU.GetQ931().SetIE(Q931::RedirectingNumberIE, IE); | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-05-19 16:17:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-07 14:48:32 +00:00
										 |  |  | 	if (transfer_capability) | 
					
						
							|  |  |  | 		setupPDU.GetQ931().SetBearerCapabilities((Q931::InformationTransferCapability)(transfer_capability & 0x1f), 1, ((transfer_capability >> 5) & 3)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	SetCallDetails(&cd, setupPDU, FALSE); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-19 16:17:08 +00:00
										 |  |  | 	int res = on_outgoing_call(&cd); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	if (!res) { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 			cout << "\t-- Call Failed" << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 	/* OpenH323 will build calling party information with default
 | 
					
						
							|  |  |  | 	   type and presentation information, so build it to be recorded | 
					
						
							|  |  |  | 	   by embedding routines */ | 
					
						
							| 
									
										
										
										
											2008-02-19 20:31:15 +00:00
										 |  |  | 	setupPDU.GetQ931().SetCallingPartyNumber(sourceE164, (cid_ton >> 4) & 0x07, | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 			cid_ton & 0x0f, (cid_presentation >> 5) & 0x03, cid_presentation & 0x1f); | 
					
						
							| 
									
										
										
										
											2006-09-29 19:13:26 +00:00
										 |  |  | 	setupPDU.GetQ931().SetDisplayName(GetDisplayName()); | 
					
						
							| 
									
										
										
										
											2006-09-29 18:35:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #ifdef TUNNELLING
 | 
					
						
							|  |  |  | 	EmbedTunneledInfo(setupPDU); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return H323Connection::OnSendSignalSetup(setupPDU); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | static PBoolean BuildFastStartList(const H323Channel & channel, | 
					
						
							| 
									
										
										
										
											2006-09-29 19:13:26 +00:00
										 |  |  | 		H225_ArrayOf_PASN_OctetString & array, | 
					
						
							|  |  |  | 		H323Channel::Directions reverseDirection) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	H245_OpenLogicalChannel open; | 
					
						
							|  |  |  | 	const H323Capability & capability = channel.GetCapability(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (channel.GetDirection() != reverseDirection) { | 
					
						
							|  |  |  | 		if (!capability.OnSendingPDU(open.m_forwardLogicalChannelParameters.m_dataType)) | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		if (!capability.OnSendingPDU(open.m_reverseLogicalChannelParameters.m_dataType)) | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		open.m_forwardLogicalChannelParameters.m_multiplexParameters.SetTag( | 
					
						
							|  |  |  | 				H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters::e_none); | 
					
						
							|  |  |  | 		open.m_forwardLogicalChannelParameters.m_dataType.SetTag(H245_DataType::e_nullData); | 
					
						
							|  |  |  | 		open.IncludeOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!channel.OnSendingPDU(open)) | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PTRACE(4, "H225\tBuild fastStart:\n	" << setprecision(2) << open); | 
					
						
							|  |  |  | 	PINDEX last = array.GetSize(); | 
					
						
							|  |  |  | 	array.SetSize(last+1); | 
					
						
							|  |  |  | 	array[last].EncodeSubType(open); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PTRACE(3, "H225\tBuilt fastStart for " << capability); | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | H323Connection::CallEndReason MyH323Connection::SendSignalSetup(const PString & alias, | 
					
						
							|  |  |  | 		const H323TransportAddress & address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// Start the call, first state is asking gatekeeper
 | 
					
						
							|  |  |  | 	connectionState = AwaitingGatekeeperAdmission; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Indicate the direction of call.
 | 
					
						
							|  |  |  | 	if (alias.IsEmpty()) | 
					
						
							|  |  |  | 		remotePartyName = remotePartyAddress = address; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		remotePartyName = alias; | 
					
						
							|  |  |  | 		remotePartyAddress = alias + '@' + address; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Start building the setup PDU to get various ID's
 | 
					
						
							|  |  |  | 	H323SignalPDU setupPDU; | 
					
						
							|  |  |  | 	H225_Setup_UUIE & setup = setupPDU.BuildSetup(*this, address); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | 	h450dispatcher->AttachToSetup(setupPDU); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Save the identifiers generated by BuildSetup
 | 
					
						
							|  |  |  | 	setupPDU.GetQ931().GetCalledPartyNumber(remotePartyNumber); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	H323TransportAddress gatekeeperRoute = address; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check for gatekeeper and do admission check if have one
 | 
					
						
							|  |  |  | 	H323Gatekeeper * gatekeeper = endpoint.GetGatekeeper(); | 
					
						
							|  |  |  | 	H225_ArrayOf_AliasAddress newAliasAddresses; | 
					
						
							|  |  |  | 	if (gatekeeper != NULL) { | 
					
						
							|  |  |  | 		H323Gatekeeper::AdmissionResponse response; | 
					
						
							|  |  |  | 		response.transportAddress = &gatekeeperRoute; | 
					
						
							|  |  |  | 		response.aliasAddresses = &newAliasAddresses; | 
					
						
							|  |  |  | 		if (!gkAccessTokenOID) | 
					
						
							|  |  |  | 			response.accessTokenData = &gkAccessTokenData; | 
					
						
							|  |  |  | 		while (!gatekeeper->AdmissionRequest(*this, response, alias.IsEmpty())) { | 
					
						
							|  |  |  | 			PTRACE(1, "H225\tGatekeeper refused admission: " | 
					
						
							|  |  |  | 					<< (response.rejectReason == UINT_MAX | 
					
						
							|  |  |  | 					? PString("Transport error") | 
					
						
							|  |  |  | 					: H225_AdmissionRejectReason(response.rejectReason).GetTagName())); | 
					
						
							|  |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | 			h4502handler->onReceivedAdmissionReject(H4501_GeneralErrorList::e_notAvailable); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			switch (response.rejectReason) { | 
					
						
							|  |  |  | 			case H225_AdmissionRejectReason::e_calledPartyNotRegistered: | 
					
						
							|  |  |  | 				return EndedByNoUser; | 
					
						
							|  |  |  | 			case H225_AdmissionRejectReason::e_requestDenied: | 
					
						
							|  |  |  | 				return EndedByNoBandwidth; | 
					
						
							|  |  |  | 			case H225_AdmissionRejectReason::e_invalidPermission: | 
					
						
							|  |  |  | 			case H225_AdmissionRejectReason::e_securityDenial: | 
					
						
							|  |  |  | 				return EndedBySecurityDenial; | 
					
						
							|  |  |  | 			case H225_AdmissionRejectReason::e_resourceUnavailable: | 
					
						
							|  |  |  | 				return EndedByRemoteBusy; | 
					
						
							|  |  |  | 			case H225_AdmissionRejectReason::e_incompleteAddress: | 
					
						
							|  |  |  | 				if (OnInsufficientDigits()) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				// Then default case
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				return EndedByGatekeeper; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			PString lastRemotePartyName = remotePartyName; | 
					
						
							|  |  |  | 			while (lastRemotePartyName == remotePartyName) { | 
					
						
							|  |  |  | 				Unlock(); // Release the mutex as can deadlock trying to clear call during connect.
 | 
					
						
							|  |  |  | 				digitsWaitFlag.Wait(); | 
					
						
							|  |  |  | 				if (!Lock()) // Lock while checking for shutting down.
 | 
					
						
							|  |  |  | 					return EndedByCallerAbort; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mustSendDRQ = TRUE; | 
					
						
							|  |  |  | 		if (response.gatekeeperRouted) { | 
					
						
							|  |  |  | 			setup.IncludeOptionalField(H225_Setup_UUIE::e_endpointIdentifier); | 
					
						
							|  |  |  | 			setup.m_endpointIdentifier = gatekeeper->GetEndpointIdentifier(); | 
					
						
							|  |  |  | 			gatekeeperRouted = TRUE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef H323_TRANSNEXUS_OSP
 | 
					
						
							|  |  |  | 	// check for OSP server (if not using GK)
 | 
					
						
							|  |  |  | 	if (gatekeeper == NULL) { | 
					
						
							|  |  |  | 		OpalOSP::Provider * ospProvider = endpoint.GetOSPProvider(); | 
					
						
							|  |  |  | 		if (ospProvider != NULL) { | 
					
						
							|  |  |  | 			OpalOSP::Transaction * transaction = new OpalOSP::Transaction(); | 
					
						
							|  |  |  | 			if (transaction->Open(*ospProvider) != 0) { | 
					
						
							|  |  |  | 				PTRACE(1, "H225\tCannot create OSP transaction"); | 
					
						
							|  |  |  | 				return EndedByOSPRefusal; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			OpalOSP::Transaction::DestinationInfo destInfo; | 
					
						
							|  |  |  | 			if (!AuthoriseOSPTransaction(*transaction, destInfo)) { | 
					
						
							|  |  |  | 				delete transaction; | 
					
						
							|  |  |  | 				return EndedByOSPRefusal; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// save the transaction for use by the call
 | 
					
						
							|  |  |  | 			ospTransaction = transaction; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// retreive the call information
 | 
					
						
							|  |  |  | 			gatekeeperRoute = destInfo.destinationAddress; | 
					
						
							|  |  |  | 			newAliasAddresses.Append(new H225_AliasAddress(destInfo.calledNumber)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// insert the token
 | 
					
						
							|  |  |  | 			setup.IncludeOptionalField(H225_Setup_UUIE::e_tokens); | 
					
						
							|  |  |  | 			destInfo.InsertToken(setup.m_tokens); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Update the field e_destinationAddress in the SETUP PDU to reflect the new 
 | 
					
						
							|  |  |  | 	// alias received in the ACF (m_destinationInfo).
 | 
					
						
							|  |  |  | 	if (newAliasAddresses.GetSize() > 0) { | 
					
						
							|  |  |  | 		setup.IncludeOptionalField(H225_Setup_UUIE::e_destinationAddress); | 
					
						
							|  |  |  | 		setup.m_destinationAddress = newAliasAddresses; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Update the Q.931 Information Element (if is an E.164 address)
 | 
					
						
							|  |  |  | 		PString e164 = H323GetAliasAddressE164(newAliasAddresses); | 
					
						
							|  |  |  | 		if (!e164) | 
					
						
							|  |  |  | 			remotePartyNumber = e164; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (addAccessTokenToSetup && !gkAccessTokenOID && !gkAccessTokenData.IsEmpty()) { | 
					
						
							|  |  |  | 		PString oid1, oid2; | 
					
						
							|  |  |  | 		PINDEX comma = gkAccessTokenOID.Find(','); | 
					
						
							|  |  |  | 		if (comma == P_MAX_INDEX) | 
					
						
							|  |  |  | 			oid1 = oid2 = gkAccessTokenOID; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			oid1 = gkAccessTokenOID.Left(comma); | 
					
						
							|  |  |  | 			oid2 = gkAccessTokenOID.Mid(comma+1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		setup.IncludeOptionalField(H225_Setup_UUIE::e_tokens); | 
					
						
							|  |  |  | 		PINDEX last = setup.m_tokens.GetSize(); | 
					
						
							|  |  |  | 		setup.m_tokens.SetSize(last+1); | 
					
						
							|  |  |  | 		setup.m_tokens[last].m_tokenOID = oid1; | 
					
						
							|  |  |  | 		setup.m_tokens[last].IncludeOptionalField(H235_ClearToken::e_nonStandard); | 
					
						
							|  |  |  | 		setup.m_tokens[last].m_nonStandard.m_nonStandardIdentifier = oid2; | 
					
						
							|  |  |  | 		setup.m_tokens[last].m_nonStandard.m_data = gkAccessTokenData; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!signallingChannel->SetRemoteAddress(gatekeeperRoute)) { | 
					
						
							|  |  |  | 		PTRACE(1, "H225\tInvalid " | 
					
						
							|  |  |  | 					 << (gatekeeperRoute != address ? "gatekeeper" : "user") | 
					
						
							|  |  |  | 					 << " supplied address: \"" << gatekeeperRoute << '"'); | 
					
						
							|  |  |  | 		connectionState = AwaitingTransportConnect; | 
					
						
							|  |  |  | 		return EndedByConnectFail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Do the transport connect
 | 
					
						
							|  |  |  | 	connectionState = AwaitingTransportConnect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Release the mutex as can deadlock trying to clear call during connect.
 | 
					
						
							|  |  |  | 	Unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	signallingChannel->SetWriteTimeout(100); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	PBoolean connectFailed = !signallingChannel->Connect(); | 
					
						
							| 
									
										
										
										
											2006-09-29 19:13:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Lock while checking for shutting down.
 | 
					
						
							|  |  |  | 	if (!Lock()) | 
					
						
							|  |  |  | 		return EndedByCallerAbort; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// See if transport connect failed, abort if so.
 | 
					
						
							|  |  |  | 	if (connectFailed) { | 
					
						
							|  |  |  | 		connectionState = NoConnectionActive; | 
					
						
							|  |  |  | 		switch (signallingChannel->GetErrorNumber()) { | 
					
						
							|  |  |  | 			case ENETUNREACH : | 
					
						
							|  |  |  | 				return EndedByUnreachable; | 
					
						
							|  |  |  | 			case ECONNREFUSED : | 
					
						
							|  |  |  | 				return EndedByNoEndPoint; | 
					
						
							|  |  |  | 			case ETIMEDOUT : | 
					
						
							|  |  |  | 				return EndedByHostOffline; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return EndedByConnectFail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PTRACE(3, "H225\tSending Setup PDU"); | 
					
						
							|  |  |  | 	connectionState = AwaitingSignalConnect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Put in all the signalling addresses for link
 | 
					
						
							|  |  |  | 	setup.IncludeOptionalField(H225_Setup_UUIE::e_sourceCallSignalAddress); | 
					
						
							|  |  |  | 	signallingChannel->SetUpTransportPDU(setup.m_sourceCallSignalAddress, TRUE); | 
					
						
							|  |  |  | 	if (!setup.HasOptionalField(H225_Setup_UUIE::e_destCallSignalAddress)) { | 
					
						
							|  |  |  | 		setup.IncludeOptionalField(H225_Setup_UUIE::e_destCallSignalAddress); | 
					
						
							|  |  |  | 		signallingChannel->SetUpTransportPDU(setup.m_destCallSignalAddress, FALSE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// If a standard call do Fast Start (if required)
 | 
					
						
							|  |  |  | 	if (setup.m_conferenceGoal.GetTag() == H225_Setup_UUIE_conferenceGoal::e_create) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Get the local capabilities before fast start is handled
 | 
					
						
							|  |  |  | 		OnSetLocalCapabilities(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Ask the application what channels to open
 | 
					
						
							|  |  |  | 		PTRACE(3, "H225\tCheck for Fast start by local endpoint"); | 
					
						
							|  |  |  | 		fastStartChannels.RemoveAll(); | 
					
						
							|  |  |  | 		OnSelectLogicalChannels(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// If application called OpenLogicalChannel, put in the fastStart field
 | 
					
						
							|  |  |  | 		if (!fastStartChannels.IsEmpty()) { | 
					
						
							|  |  |  | 			PTRACE(3, "H225\tFast start begun by local endpoint"); | 
					
						
							|  |  |  | 			for (PINDEX i = 0; i < fastStartChannels.GetSize(); i++) | 
					
						
							|  |  |  | 				BuildFastStartList(fastStartChannels[i], setup.m_fastStart, H323Channel::IsReceiver); | 
					
						
							|  |  |  | 			if (setup.m_fastStart.GetSize() > 0) | 
					
						
							|  |  |  | 				setup.IncludeOptionalField(H225_Setup_UUIE::e_fastStart); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Search the capability set and see if we have video capability
 | 
					
						
							|  |  |  | 		for (PINDEX i = 0; i < localCapabilities.GetSize(); i++) { | 
					
						
							|  |  |  | 			switch (localCapabilities[i].GetMainType()) { | 
					
						
							|  |  |  | 			case H323Capability::e_Audio: | 
					
						
							|  |  |  | 			case H323Capability::e_UserInput: | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default:	// Is video or other data (eg T.120)
 | 
					
						
							|  |  |  | 				setupPDU.GetQ931().SetBearerCapabilities(Q931::TransferUnrestrictedDigital, 6); | 
					
						
							|  |  |  | 				i = localCapabilities.GetSize(); // Break out of the for loop
 | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!OnSendSignalSetup(setupPDU)) | 
					
						
							|  |  |  | 		return EndedByNoAccept; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Do this again (was done when PDU was constructed) in case
 | 
					
						
							|  |  |  | 	// OnSendSignalSetup() changed something.
 | 
					
						
							|  |  |  | //	setupPDU.SetQ931Fields(*this, TRUE);
 | 
					
						
							|  |  |  | 	setupPDU.GetQ931().GetCalledPartyNumber(remotePartyNumber); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fastStartState = FastStartDisabled; | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	PBoolean set_lastPDUWasH245inSETUP = FALSE; | 
					
						
							| 
									
										
										
										
											2006-09-29 19:13:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (h245Tunneling && doH245inSETUP) { | 
					
						
							|  |  |  | 		h245TunnelTxPDU = &setupPDU; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Try and start the master/slave and capability exchange through the tunnel
 | 
					
						
							|  |  |  | 		// Note: this used to be disallowed but is now allowed as of H323v4
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 		PBoolean ok = StartControlNegotiations(); | 
					
						
							| 
									
										
										
										
											2006-09-29 19:13:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		h245TunnelTxPDU = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!ok) | 
					
						
							|  |  |  | 			return EndedByTransportFail; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (setup.m_fastStart.GetSize() > 0) { | 
					
						
							|  |  |  | 			// Now if fast start as well need to put this in setup specific field
 | 
					
						
							|  |  |  | 			// and not the generic H.245 tunneling field
 | 
					
						
							|  |  |  | 			setup.IncludeOptionalField(H225_Setup_UUIE::e_parallelH245Control); | 
					
						
							|  |  |  | 			setup.m_parallelH245Control = setupPDU.m_h323_uu_pdu.m_h245Control; | 
					
						
							|  |  |  | 			setupPDU.m_h323_uu_pdu.RemoveOptionalField(H225_H323_UU_PDU::e_h245Control); | 
					
						
							|  |  |  | 			set_lastPDUWasH245inSETUP = TRUE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Send the initial PDU
 | 
					
						
							|  |  |  | 	setupTime = PTime(); | 
					
						
							|  |  |  | 	if (!WriteSignalPDU(setupPDU)) | 
					
						
							|  |  |  | 		return EndedByTransportFail; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// WriteSignalPDU always resets lastPDUWasH245inSETUP.
 | 
					
						
							|  |  |  | 	// So set it here if required
 | 
					
						
							|  |  |  | 	if (set_lastPDUWasH245inSETUP) | 
					
						
							|  |  |  | 		lastPDUWasH245inSETUP = TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set timeout for remote party to answer the call
 | 
					
						
							|  |  |  | 	signallingChannel->SetReadTimeout(endpoint.GetSignallingChannelCallTimeout()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NumCallEndReasons; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnSendReleaseComplete(H323SignalPDU & releaseCompletePDU) | 
					
						
							| 
									
										
										
										
											2003-05-12 00:55:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		cout << "\t-- Sending RELEASE COMPLETE" << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	if (cause > 0) | 
					
						
							|  |  |  | 		releaseCompletePDU.GetQ931().SetCause((Q931::CauseValues)cause); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef TUNNELLING
 | 
					
						
							|  |  |  | 	EmbedTunneledInfo(releaseCompletePDU); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-12 00:55:52 +00:00
										 |  |  | 	return H323Connection::OnSendReleaseComplete(releaseCompletePDU); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnReceivedFacility(const H323SignalPDU & pdu) | 
					
						
							| 
									
										
										
										
											2003-05-12 00:55:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		cout << "\t-- Received Facility message... " << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-05-12 00:55:52 +00:00
										 |  |  | 	return H323Connection::OnReceivedFacility(pdu); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | void MyH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		cout << "\t-- Received RELEASE COMPLETE message..." << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	if (on_hangup) | 
					
						
							|  |  |  | 		on_hangup(GetCallReference(), (const char *)GetCallToken(), pdu.GetQ931().GetCause()); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return H323Connection::OnReceivedReleaseComplete(pdu); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnClosingLogicalChannel(H323Channel & channel) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		cout << "\t-- Closing logical channel..." << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return H323Connection::OnClosingLogicalChannel(channel); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | void MyH323Connection::SendUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	SendUserInputModes mode = GetRealSendUserInputMode(); | 
					
						
							|  |  |  | //	That is recursive call... Why?
 | 
					
						
							|  |  |  | //	on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken());
 | 
					
						
							|  |  |  | 	if ((tone != ' ') || (mode == SendUserInputAsTone) || (mode == SendUserInputAsInlineRFC2833)) { | 
					
						
							|  |  |  | 		if (h323debug) { | 
					
						
							|  |  |  | 			cout << "\t-- Sending user input tone (" << tone << ") to remote" << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		H323Connection::SendUserInputTone(tone, duration); | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 	/* Why we should check this? */ | 
					
						
							|  |  |  | 	if ((dtmfMode & (H323_DTMF_CISCO | H323_DTMF_RFC2833 | H323_DTMF_SIGNAL)) != 0) { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 			cout << "\t-- Received user input tone (" << tone << ") from remote" << endl; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken(), duration); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323Connection::OnUserInputString(const PString &value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t-- Received user input string (" << value << ") from remote." << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	on_receive_digit(GetCallReference(), value[0], (const char *)GetCallToken(), 0); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PINDEX i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	H323Connection::OnSendCapabilitySet(pdu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	H245_ArrayOf_CapabilityTableEntry & tables = pdu.m_capabilityTable; | 
					
						
							|  |  |  | 	for(i = 0; i < tables.GetSize(); i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		H245_CapabilityTableEntry & entry = tables[i]; | 
					
						
							|  |  |  | 		if (entry.HasOptionalField(H245_CapabilityTableEntry::e_capability)) { | 
					
						
							|  |  |  | 			H245_Capability & cap = entry.m_capability; | 
					
						
							|  |  |  | 			if (cap.GetTag() == H245_Capability::e_receiveRTPAudioTelephonyEventCapability) { | 
					
						
							|  |  |  | 				H245_AudioTelephonyEventCapability & atec = cap; | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 				atec.m_dynamicRTPPayloadType = dtmfCodec[0]; | 
					
						
							|  |  |  | //				on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec[0]);
 | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #ifdef PTRACING
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 				if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 					cout << "\t-- Receiving RFC2833 on payload " << | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 						atec.m_dynamicRTPPayloadType << endl; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | void MyH323Connection::OnSetLocalCapabilities() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (on_setcapabilities) | 
					
						
							|  |  |  | 		on_setcapabilities(GetCallReference(), (const char *)callToken); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps, | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 							const H245_MultiplexCapability * muxCap, | 
					
						
							|  |  |  | 							H245_TerminalCapabilitySetReject & reject) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct __codec__ { | 
					
						
							|  |  |  | 		unsigned int asterisk_codec; | 
					
						
							|  |  |  | 		unsigned int h245_cap; | 
					
						
							|  |  |  | 		const char *oid; | 
					
						
							| 
									
										
										
										
											2006-09-21 18:48:53 +00:00
										 |  |  | 		const char *formatName; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 	static const struct __codec__ codecs[] = { | 
					
						
							|  |  |  | 		{ AST_FORMAT_G723_1, H245_AudioCapability::e_g7231 }, | 
					
						
							|  |  |  | 		{ AST_FORMAT_GSM, H245_AudioCapability::e_gsmFullRate }, | 
					
						
							|  |  |  | 		{ AST_FORMAT_ULAW, H245_AudioCapability::e_g711Ulaw64k }, | 
					
						
							|  |  |  | 		{ AST_FORMAT_ALAW, H245_AudioCapability::e_g711Alaw64k }, | 
					
						
							|  |  |  | 		{ AST_FORMAT_G729A, H245_AudioCapability::e_g729AnnexA }, | 
					
						
							|  |  |  | 		{ AST_FORMAT_G729A, H245_AudioCapability::e_g729 }, | 
					
						
							| 
									
										
										
										
											2006-09-21 18:48:53 +00:00
										 |  |  | 		{ AST_FORMAT_G726_AAL2, H245_AudioCapability::e_nonStandard, NULL, CISCO_G726r32 }, | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #ifdef AST_FORMAT_MODEM
 | 
					
						
							|  |  |  | 		{ AST_FORMAT_MODEM, H245_DataApplicationCapability_application::e_t38fax }, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		{ 0 } | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	static const struct __codec__ vcodecs[] = { | 
					
						
							|  |  |  | #ifdef HAVE_H261
 | 
					
						
							|  |  |  | 		{ AST_FORMAT_H261, H245_VideoCapability::e_h261VideoCapability }, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_H263
 | 
					
						
							|  |  |  | 		{ AST_FORMAT_H263, H245_VideoCapability::e_h263VideoCapability }, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_H264
 | 
					
						
							|  |  |  | 		{ AST_FORMAT_H264, H245_VideoCapability::e_genericVideoCapability, "0.0.8.241.0.0.1" }, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		{ 0 } | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 	struct ast_codec_pref prefs; | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 	RTP_DataFrame::PayloadTypes pt; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) { | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 	memset(&prefs, 0, sizeof(prefs)); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	int peer_capabilities = 0; | 
					
						
							|  |  |  | 	for (int i = 0; i < remoteCapabilities.GetSize(); ++i) { | 
					
						
							|  |  |  | 		unsigned int subType = remoteCapabilities[i].GetSubType(); | 
					
						
							|  |  |  | 		if (h323debug) { | 
					
						
							|  |  |  | 			cout << "Peer capability is " << remoteCapabilities[i] << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		switch(remoteCapabilities[i].GetMainType()) { | 
					
						
							|  |  |  | 		case H323Capability::e_Audio: | 
					
						
							|  |  |  | 			for (int x = 0; codecs[x].asterisk_codec > 0; ++x) { | 
					
						
							| 
									
										
										
										
											2006-09-21 18:48:53 +00:00
										 |  |  | 				if ((subType == codecs[x].h245_cap) && (!codecs[x].formatName || (!strcmp(codecs[x].formatName, (const char *)remoteCapabilities[i].GetFormatName())))) { | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 					int ast_codec = codecs[x].asterisk_codec; | 
					
						
							|  |  |  | 					int ms = 0; | 
					
						
							|  |  |  | 					if (!(peer_capabilities & ast_codec)) { | 
					
						
							|  |  |  | 						struct ast_format_list format; | 
					
						
							|  |  |  | 						ast_codec_pref_append(&prefs, ast_codec); | 
					
						
							|  |  |  | 						format = ast_codec_pref_getsize(&prefs, ast_codec); | 
					
						
							|  |  |  | 						if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) { | 
					
						
							|  |  |  | 							ms = remoteCapabilities[i].GetTxFramesInPacket(); | 
					
						
							|  |  |  | 						} else | 
					
						
							|  |  |  | 							ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms; | 
					
						
							|  |  |  | 						ast_codec_pref_setsize(&prefs, ast_codec, ms); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 					if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 						cout << "Found peer capability " << remoteCapabilities[i] << ", Asterisk code is " << ast_codec << ", frame size (in ms) is " << ms << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 					peer_capabilities |= ast_codec; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 		case H323Capability::e_Data: | 
					
						
							|  |  |  | 			if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), CISCO_DTMF_RELAY)) { | 
					
						
							|  |  |  | 				pt = remoteCapabilities[i].GetPayloadType(); | 
					
						
							|  |  |  | 				if ((dtmfMode & H323_DTMF_CISCO) != 0) { | 
					
						
							|  |  |  | 					on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 1); | 
					
						
							|  |  |  | //					if (sendUserInputMode == SendUserInputAsTone)
 | 
					
						
							|  |  |  | //						sendUserInputMode = SendUserInputAsInlineRFC2833;
 | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #ifdef PTRACING
 | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 				if (h323debug) { | 
					
						
							|  |  |  | 					cout << "\t-- Outbound Cisco RTP DTMF on payload " << pt << endl; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case H323Capability::e_UserInput: | 
					
						
							|  |  |  | 			if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833])) { | 
					
						
							|  |  |  | 				pt = remoteCapabilities[i].GetPayloadType(); | 
					
						
							|  |  |  | 				if ((dtmfMode & H323_DTMF_RFC2833) != 0) { | 
					
						
							|  |  |  | 					on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 0); | 
					
						
							|  |  |  | //					if (sendUserInputMode == SendUserInputAsTone)
 | 
					
						
							|  |  |  | //						sendUserInputMode = SendUserInputAsInlineRFC2833;
 | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #ifdef PTRACING
 | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 				if (h323debug) { | 
					
						
							|  |  |  | 					cout << "\t-- Outbound RFC2833 on payload " << pt << endl; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-08-30 15:40:18 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 		case H323Capability::e_Video: | 
					
						
							|  |  |  | 			for (int x = 0; vcodecs[x].asterisk_codec > 0; ++x) { | 
					
						
							|  |  |  | 				if (subType == vcodecs[x].h245_cap) { | 
					
						
							|  |  |  | 					H245_CapabilityIdentifier *cap = NULL; | 
					
						
							|  |  |  | 					H245_GenericCapability y; | 
					
						
							|  |  |  | 					if (vcodecs[x].oid) { | 
					
						
							|  |  |  | 						cap = new H245_CapabilityIdentifier(H245_CapabilityIdentifier::e_standard); | 
					
						
							|  |  |  | 						PASN_ObjectId &object_id = *cap; | 
					
						
							|  |  |  | 						object_id = vcodecs[x].oid; | 
					
						
							|  |  |  | 						y.m_capabilityIdentifier = *cap; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if ((subType != H245_VideoCapability::e_genericVideoCapability) || | 
					
						
							|  |  |  | 							(vcodecs[x].oid && ((const H323GenericVideoCapability &)remoteCapabilities[i]).IsGenericMatch((const H245_GenericCapability)y))) { | 
					
						
							|  |  |  | 						if (h323debug) { | 
					
						
							|  |  |  | 							cout << "Found peer video capability " << remoteCapabilities[i] << ", Asterisk code is " << vcodecs[x].asterisk_codec << endl; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						peer_capabilities |= vcodecs[x].asterisk_codec; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if (cap) | 
					
						
							|  |  |  | 						delete(cap); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 		char caps_str[1024], caps2_str[1024]; | 
					
						
							|  |  |  | 		ast_codec_pref_string(&prefs, caps2_str, sizeof(caps2_str)); | 
					
						
							|  |  |  | 		cout << "Peer capabilities = " << ast_getformatname_multiple(caps_str, sizeof(caps_str), peer_capabilities) | 
					
						
							|  |  |  | 				<< ", ordered list is " << caps2_str << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	redir_capabilities &= peer_capabilities; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	if (on_setpeercapabilities) | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 		on_setpeercapabilities(GetCallReference(), (const char *)callToken, peer_capabilities, &prefs); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability, | 
					
						
							|  |  |  | 									H323Channel::Directions dir, | 
					
						
							|  |  |  | 									unsigned sessionID, | 
					
						
							|  |  |  | 									const H245_H2250LogicalChannelParameters * /*param*/, | 
					
						
							|  |  |  | 									RTP_QOS * /*param*/ ) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-28 11:12:58 +00:00
										 |  |  | 	/* Do not open tx channel when transmitter has been paused by empty TCS */ | 
					
						
							|  |  |  | 	if ((dir == H323Channel::IsTransmitter) && transmitterSidePaused) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** This callback function is invoked once upon creation of each
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |   * channel for an H323 session | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |   */ | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::OnStartLogicalChannel(H323Channel & channel) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	/* Increase the count of channels we have open */ | 
					
						
							| 
									
										
										
										
											2004-05-25 02:27:59 +00:00
										 |  |  | 	channelsOpen++; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		cout << "\t-- Started logical channel: " | 
					
						
							|  |  |  | 				<< ((channel.GetDirection() == H323Channel::IsTransmitter) ? "sending " : ((channel.GetDirection() == H323Channel::IsReceiver) ? "receiving " : " ")) | 
					
						
							|  |  |  | 				<< (const char *)(channel.GetCapability()).GetFormatName() << endl; | 
					
						
							|  |  |  | 		cout << "\t\t-- channelsOpen = " << channelsOpen << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	return connectionState != ShuttingDownConnection; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, int pref_codec) | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PINDEX lastcap = -1; /* last common capability index */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	int alreadysent = 0; | 
					
						
							|  |  |  | 	int codec; | 
					
						
							|  |  |  | 	int x, y; | 
					
						
							|  |  |  | 	char caps_str[1024]; | 
					
						
							|  |  |  | 	struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs; | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 	struct ast_format_list format; | 
					
						
							|  |  |  | 	int frames_per_packet; | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 	H323Capability *cap; | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	localCapabilities.RemoveAll(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 		cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), caps) << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		ast_codec_pref_string(prefs, caps_str, sizeof(caps_str)); | 
					
						
							|  |  |  | 		cout << "Capabilities in preference order is " << caps_str << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* Add audio codecs in preference order first, then
 | 
					
						
							|  |  |  | 	   audio codecs without preference as allowed by mask */ | 
					
						
							|  |  |  | 	for (y = 0, x = -1; x < 32 + 32; ++x) { | 
					
						
							|  |  |  | 		if (x < 0) | 
					
						
							|  |  |  | 			codec = pref_codec; | 
					
						
							|  |  |  | 		else if (y || (!(codec = ast_codec_pref_index(prefs, x)))) { | 
					
						
							|  |  |  | 			if (!y) | 
					
						
							|  |  |  | 				y = 1; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				y <<= 1; | 
					
						
							|  |  |  | 			codec = y; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 		if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK)) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		alreadysent |= codec; | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 		/* format.cur_ms will be set to default if packetization is not explicitly set */ | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 		format = ast_codec_pref_getsize(prefs, codec); | 
					
						
							|  |  |  | 		frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		switch(codec) { | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		case AST_FORMAT_SPEEX: | 
					
						
							|  |  |  | 			/* Not real sure if Asterisk acutally supports all
 | 
					
						
							|  |  |  | 			   of the various different bit rates so add them | 
					
						
							|  |  |  | 			   all and figure it out later*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow2AudioCapability()); | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow3AudioCapability()); | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow4AudioCapability()); | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow5AudioCapability()); | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow6AudioCapability()); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		case AST_FORMAT_G729A: | 
					
						
							|  |  |  | 			AST_G729ACapability *g729aCap; | 
					
						
							|  |  |  | 			AST_G729Capability *g729Cap; | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability(frames_per_packet)); | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability(frames_per_packet)); | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 			g729aCap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							|  |  |  | 			g729Cap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case AST_FORMAT_G723_1: | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 			AST_G7231Capability *g7231Cap; | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, TRUE)); | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 			g7231Cap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, FALSE)); | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 			g7231Cap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case AST_FORMAT_GSM: | 
					
						
							|  |  |  | 			AST_GSM0610Capability *gsmCap; | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new AST_GSM0610Capability(frames_per_packet)); | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 			gsmCap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case AST_FORMAT_ULAW: | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 			AST_G711Capability *g711uCap; | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::muLaw)); | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 			g711uCap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case AST_FORMAT_ALAW: | 
					
						
							| 
									
										
										
										
											2006-09-20 16:24:00 +00:00
										 |  |  | 			AST_G711Capability *g711aCap; | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::ALaw)); | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 			g711aCap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-09-21 18:48:53 +00:00
										 |  |  | 		case AST_FORMAT_G726_AAL2: | 
					
						
							|  |  |  | 			AST_CiscoG726Capability *g726Cap; | 
					
						
							|  |  |  | 			lastcap = localCapabilities.SetCapability(0, 0, g726Cap = new AST_CiscoG726Capability(frames_per_packet)); | 
					
						
							| 
									
										
										
										
											2009-04-22 19:23:49 +00:00
										 |  |  | 			g726Cap->SetTxFramesInPacket(format.cur_ms); | 
					
						
							| 
									
										
										
										
											2006-09-21 18:48:53 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			alreadysent &= ~codec; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 	cap = new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245); | 
					
						
							|  |  |  | 	if (cap && cap->IsUsable(*this)) { | 
					
						
							|  |  |  | 		lastcap++; | 
					
						
							|  |  |  | 		lastcap = localCapabilities.SetCapability(0, lastcap, cap); | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 		delete cap;				/* Capability is not usable */ | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	dtmfMode = dtmf_mode; | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "DTMF mode is " << (int)dtmfMode << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (dtmfMode) { | 
					
						
							|  |  |  | 		lastcap++; | 
					
						
							|  |  |  | 		if (dtmfMode == H323_DTMF_INBAND) { | 
					
						
							|  |  |  | 			cap = new H323_UserInputCapability(H323_UserInputCapability::BasicString); | 
					
						
							|  |  |  | 			if (cap && cap->IsUsable(*this)) { | 
					
						
							|  |  |  | 				lastcap = localCapabilities.SetCapability(0, lastcap, cap); | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 				delete cap;		/* Capability is not usable */ | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 			}	 | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 			sendUserInputMode = SendUserInputAsString; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if ((dtmfMode & H323_DTMF_RFC2833) != 0) { | 
					
						
							|  |  |  | 				cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833); | 
					
						
							|  |  |  | 				if (cap && cap->IsUsable(*this)) | 
					
						
							|  |  |  | 					lastcap = localCapabilities.SetCapability(0, lastcap, cap); | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					dtmfMode |= H323_DTMF_SIGNAL; | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 					delete cap;	/* Capability is not usable */ | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if ((dtmfMode & H323_DTMF_CISCO) != 0) { | 
					
						
							|  |  |  | 				/* Try Cisco's RTP DTMF relay too, but prefer RFC2833 or h245-signal */ | 
					
						
							|  |  |  | 				cap = new AST_CiscoDtmfCapability(); | 
					
						
							|  |  |  | 				if (cap && cap->IsUsable(*this)) { | 
					
						
							|  |  |  | 					lastcap = localCapabilities.SetCapability(0, lastcap, cap); | 
					
						
							|  |  |  | 					/* We cannot send Cisco RTP DTMFs, use h245-signal instead */ | 
					
						
							|  |  |  | 					dtmfMode |= H323_DTMF_SIGNAL; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					dtmfMode |= H323_DTMF_SIGNAL; | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 					delete cap;	/* Capability is not usable */ | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if ((dtmfMode & H323_DTMF_SIGNAL) != 0) { | 
					
						
							|  |  |  | 				/* Cisco usually sends DTMF correctly only through h245-alphanumeric or h245-signal */ | 
					
						
							|  |  |  | 				cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245); | 
					
						
							|  |  |  | 				if (cap && cap->IsUsable(*this)) | 
					
						
							|  |  |  | 					lastcap = localCapabilities.SetCapability(0, lastcap, cap); | 
					
						
							| 
									
										
										
										
											2009-06-18 16:37:42 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 					delete cap;	/* Capability is not usable */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			sendUserInputMode = SendUserInputAsTone;	/* RFC2833 transmission handled at Asterisk level */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-25 09:03:14 +00:00
										 |  |  | 		cout << "Allowed Codecs for " << GetCallToken() << " (" << GetSignallingChannel()->GetLocalAddress() << "):\n\t" << setprecision(2) << localCapabilities << endl; | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323Connection::StartControlChannel(const H225_TransportAddress & h245Address) | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	// Check that it is an IP address, all we support at the moment
 | 
					
						
							|  |  |  | 	if (h245Address.GetTag() != H225_TransportAddress::e_ipAddress | 
					
						
							|  |  |  | #if P_HAS_IPV6
 | 
					
						
							|  |  |  | 		&& h245Address.GetTag() != H225_TransportAddress::e_ip6Address | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	) { | 
					
						
							|  |  |  | 		PTRACE(1, "H225\tConnect of H245 failed: Unsupported transport"); | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Already have the H245 channel up.
 | 
					
						
							|  |  |  | 	if (controlChannel != NULL) | 
					
						
							|  |  |  | 		return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PIPSocket::Address addr; | 
					
						
							|  |  |  | 	WORD port; | 
					
						
							|  |  |  | 	GetSignallingChannel()->GetLocalAddress().GetIpAndPort(addr, port); | 
					
						
							|  |  |  | 	if (addr) { | 
					
						
							|  |  |  | 		if (h323debug) | 
					
						
							|  |  |  | 			cout << "Using " << addr << " for outbound H.245 transport" << endl; | 
					
						
							|  |  |  | 		controlChannel = new MyH323TransportTCP(endpoint, addr); | 
					
						
							|  |  |  | 	} else | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | 		controlChannel = new MyH323TransportTCP(endpoint); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (!controlChannel->SetRemoteAddress(h245Address)) { | 
					
						
							|  |  |  | 		PTRACE(1, "H225\tCould not extract H245 address"); | 
					
						
							|  |  |  | 		delete controlChannel; | 
					
						
							|  |  |  | 		controlChannel = NULL; | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!controlChannel->Connect()) { | 
					
						
							|  |  |  | 		PTRACE(1, "H225\tConnect of H245 failed: " << controlChannel->GetErrorText()); | 
					
						
							|  |  |  | 		delete controlChannel; | 
					
						
							|  |  |  | 		controlChannel = NULL; | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	controlChannel->StartControlChannel(*this); | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | void MyH323Connection::OnReceivedLocalCallHold(int linkedId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (on_hold) | 
					
						
							|  |  |  | 		on_hold(GetCallReference(), (const char *)GetCallToken(), 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH323Connection::OnReceivedLocalCallRetrieve(int linkedId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (on_hold) | 
					
						
							|  |  |  | 		on_hold(GetCallReference(), (const char *)GetCallToken(), 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | void MyH323Connection::MyHoldCall(PBoolean isHold) | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (((holdHandling & H323_HOLD_NOTIFY) != 0) || ((holdHandling & H323_HOLD_Q931ONLY) != 0)) { | 
					
						
							|  |  |  | 		PBYTEArray x ((const BYTE *)(isHold ? "\xF9" : "\xFA"), 1); | 
					
						
							|  |  |  | 		H323SignalPDU signal; | 
					
						
							|  |  |  | 		signal.BuildNotify(*this); | 
					
						
							|  |  |  | 		signal.GetQ931().SetIE((Q931::InformationElementCodes)39 /* Q931::NotifyIE */, x); | 
					
						
							|  |  |  | 		if (h323debug) | 
					
						
							|  |  |  | 			cout << "Sending " << (isHold ? "HOLD" : "RETRIEVE") << " notification: " << signal << endl; | 
					
						
							|  |  |  | 		if ((holdHandling & H323_HOLD_Q931ONLY) != 0) { | 
					
						
							|  |  |  | 			PBYTEArray rawData; | 
					
						
							|  |  |  | 			signal.GetQ931().RemoveIE(Q931::UserUserIE); | 
					
						
							|  |  |  | 			signal.GetQ931().Encode(rawData); | 
					
						
							|  |  |  | 			signallingChannel->WritePDU(rawData); | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			WriteSignalPDU(signal); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | 	if ((holdHandling & H323_HOLD_H450) != 0) { | 
					
						
							|  |  |  | 		if (isHold) | 
					
						
							|  |  |  | 			h4504handler->HoldCall(TRUE); | 
					
						
							|  |  |  | 		else if (IsLocalHold()) | 
					
						
							|  |  |  | 			h4504handler->RetrieveCall(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-20 14:29:36 +00:00
										 |  |  | /* MyH323_ExternalRTPChannel */ | 
					
						
							|  |  |  | MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection, | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 							const H323Capability & capability, | 
					
						
							|  |  |  | 							Directions direction, | 
					
						
							|  |  |  | 							unsigned id) | 
					
						
							|  |  |  | 	: H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	struct rtp_info *info; | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	/* Determine the Local (A side) IP Address and port */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	info = on_external_rtp_create(connection.GetCallReference(), (const char *)connection.GetCallToken()); | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	if (!info) { | 
					
						
							|  |  |  | 		cout << "\tERROR: on_external_rtp_create failure" << endl; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2004-10-22 19:04:02 +00:00
										 |  |  | 		localIpAddr = info->addr; | 
					
						
							|  |  |  | 		localPort = info->port; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		/* tell the H.323 stack */ | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 		SetExternalAddress(H323TransportAddress(localIpAddr, localPort), H323TransportAddress(localIpAddr, localPort + 1)); | 
					
						
							|  |  |  | 		/* clean up allocated memory */ | 
					
						
							| 
									
										
										
										
											2009-03-11 04:06:44 +00:00
										 |  |  | 		ast_free(info); | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	/* Get the payload code	*/ | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	OpalMediaFormat format(capability.GetFormatName(), FALSE); | 
					
						
							|  |  |  | 	payloadCode = format.GetPayloadType(); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel() | 
					
						
							| 
									
										
										
										
											2004-03-20 14:29:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\tExternalRTPChannel Destroyed" << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-03-20 14:29:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323_ExternalRTPChannel::Start(void) | 
					
						
							| 
									
										
										
										
											2004-03-20 14:29:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	/* Call ancestor first */ | 
					
						
							|  |  |  | 	if (!H323_ExternalRTPChannel::Start()) { | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-11 13:20:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t\tExternal RTP Session Starting" << endl; | 
					
						
							|  |  |  | 		cout << "\t\tRTP channel id " << sessionID << " parameters:" << endl; | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-03 01:41:32 +00:00
										 |  |  | 	/* Collect the remote information */ | 
					
						
							|  |  |  | 	H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddr, remotePort); | 
					
						
							| 
									
										
										
										
											2005-05-11 13:20:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-03 01:41:32 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\t\t-- remoteIpAddress: " << remoteIpAddr << endl; | 
					
						
							|  |  |  | 		cout << "\t\t-- remotePort: " << remotePort << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		cout << "\t\t-- ExternalIpAddress: " << localIpAddr << endl; | 
					
						
							| 
									
										
										
										
											2005-11-03 01:41:32 +00:00
										 |  |  | 		cout << "\t\t-- ExternalPort: " << localPort << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* Notify Asterisk of remote RTP information */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), remotePort, | 
					
						
							| 
									
										
										
										
											2005-11-03 01:41:32 +00:00
										 |  |  | 		(const char *)connection.GetCallToken(), (int)payloadCode); | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	return TRUE; | 
					
						
							| 
									
										
										
										
											2004-05-25 02:27:59 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | PBoolean MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param) | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "	MyH323_ExternalRTPChannel::OnReceivedAckPDU" << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (H323_ExternalRTPChannel::OnReceivedAckPDU(param)) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		GetRemoteAddress(remoteIpAddr, remotePort); | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 			cout << "		-- remoteIpAddress: " << remoteIpAddr << endl; | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 			cout << "		-- remotePort: " << remotePort << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), | 
					
						
							| 
									
										
										
										
											2004-12-21 00:07:56 +00:00
										 |  |  | 				remotePort, (const char *)connection.GetCallToken(), (int)payloadCode); | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 		return TRUE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | #ifdef H323_H450
 | 
					
						
							|  |  |  | MyH4504Handler::MyH4504Handler(MyH323Connection &_conn, H450xDispatcher &_disp) | 
					
						
							|  |  |  | 	:H4504Handler(_conn, _disp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	conn = &_conn; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH4504Handler::OnReceivedLocalCallHold(int linkedId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (conn) { | 
					
						
							|  |  |  | 		conn->Lock(); | 
					
						
							|  |  |  | 		conn->OnReceivedLocalCallHold(linkedId); | 
					
						
							|  |  |  | 		conn->Unlock(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MyH4504Handler::OnReceivedLocalCallRetrieve(int linkedId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (conn) { | 
					
						
							|  |  |  | 		conn->Lock(); | 
					
						
							|  |  |  | 		conn->OnReceivedLocalCallRetrieve(linkedId); | 
					
						
							|  |  |  | 		conn->Unlock(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | /** IMPLEMENTATION OF C FUNCTIONS */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |  * The extern "C" directive takes care for | 
					
						
							|  |  |  |  * the ANSI-C representation of linkable symbols | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2004-05-25 02:27:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | extern "C" { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | int h323_end_point_exist(void) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (!endPoint) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-04 10:18:06 +00:00
										 |  |  | void h323_end_point_create(void) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	channelsOpen = 0; | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	logstream = new PAsteriskLog(); | 
					
						
							| 
									
										
										
										
											2010-05-24 22:05:15 +00:00
										 |  |  | 	PTrace::SetStream(logstream);  | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | 	endPoint = new MyH323EndPoint(); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void h323_gk_urq(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << " ERROR: [h323_gk_urq] No Endpoint, this is bad" << endl; | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	endPoint->RemoveGatekeeper(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void h323_debug(int flag, unsigned level) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (flag) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		PTrace:: SetLevel(level); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		PTrace:: SetLevel(0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Installs the callback functions on behalf of the PBX application */ | 
					
						
							|  |  |  | void h323_callback_register(setup_incoming_cb		ifunc, | 
					
						
							|  |  |  | 							setup_outbound_cb		sfunc, | 
					
						
							|  |  |  | 							on_rtp_cb				rtpfunc, | 
					
						
							|  |  |  | 							start_rtp_cb			lfunc, | 
					
						
							|  |  |  | 							clear_con_cb			clfunc, | 
					
						
							|  |  |  | 							chan_ringing_cb			rfunc, | 
					
						
							|  |  |  | 							con_established_cb		efunc, | 
					
						
							|  |  |  | 							receive_digit_cb		dfunc, | 
					
						
							|  |  |  | 							answer_call_cb			acfunc, | 
					
						
							|  |  |  | 							progress_cb				pgfunc, | 
					
						
							|  |  |  | 							rfc2833_cb				dtmffunc, | 
					
						
							|  |  |  | 							hangup_cb				hangupfunc, | 
					
						
							|  |  |  | 							setcapabilities_cb		capabilityfunc, | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | 							setpeercapabilities_cb	peercapabilityfunc, | 
					
						
							|  |  |  | 							onhold_cb				holdfunc) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	on_incoming_call = ifunc; | 
					
						
							|  |  |  | 	on_outgoing_call = sfunc; | 
					
						
							| 
									
										
										
										
											2004-10-10 12:20:18 +00:00
										 |  |  | 	on_external_rtp_create = rtpfunc; | 
					
						
							|  |  |  | 	on_start_rtp_channel = lfunc; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	on_connection_cleared = clfunc; | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | 	on_chan_ringing = rfunc; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	on_connection_established = efunc; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	on_receive_digit = dfunc; | 
					
						
							| 
									
										
										
										
											2004-06-15 20:56:06 +00:00
										 |  |  | 	on_answer_call = acfunc; | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	on_progress = pgfunc; | 
					
						
							|  |  |  | 	on_set_rfc2833_payload = dtmffunc; | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	on_hangup = hangupfunc; | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	on_setcapabilities = capabilityfunc; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	on_setpeercapabilities = peercapabilityfunc; | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | 	on_hold = holdfunc; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  |  * Add capability to the capability table of the end point. | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | int h323_set_capabilities(const char *token, int cap, int dtmf_mode, struct ast_codec_pref *prefs, int pref_codec) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	MyH323Connection *conn; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2005-05-21 16:27:57 +00:00
										 |  |  | 		cout << " ERROR: [h323_set_capablities] No Endpoint, this is bad" << endl; | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!token || !*token) { | 
					
						
							|  |  |  | 		cout << " ERROR: [h323_set_capabilities] Invalid call token specified." << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	PString myToken(token); | 
					
						
							|  |  |  | 	conn = (MyH323Connection *)endPoint->FindConnectionWithLock(myToken); | 
					
						
							|  |  |  | 	if (!conn) { | 
					
						
							| 
									
										
										
										
											2005-05-21 16:27:57 +00:00
										 |  |  | 		cout << " ERROR: [h323_set_capabilities] Unable to find connection " << token << endl; | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 		return 1; | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	conn->SetCapabilities((/*conn->bridging ? conn->redir_capabilities :*/ cap), dtmf_mode, prefs, pref_codec); | 
					
						
							| 
									
										
										
										
											2005-05-19 19:13:19 +00:00
										 |  |  | 	conn->Unlock(); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Start the H.323 listener */ | 
					
						
							| 
									
										
										
										
											2003-05-31 18:42:09 +00:00
										 |  |  | int h323_start_listener(int listenPort, struct sockaddr_in bindaddr) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << "ERROR: [h323_start_listener] No Endpoint, this is bad!" << endl; | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	PIPSocket::Address interfaceAddress(bindaddr.sin_addr); | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	if (!listenPort) { | 
					
						
							| 
									
										
										
										
											2003-05-20 23:36:40 +00:00
										 |  |  | 		listenPort = 1720; | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	/** H.323 listener */ | 
					
						
							| 
									
										
										
										
											2004-01-06 16:43:24 +00:00
										 |  |  | 	H323ListenerTCP *tcpListener; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	tcpListener = new H323ListenerTCP(*endPoint, interfaceAddress, (WORD)listenPort); | 
					
						
							|  |  |  | 	if (!endPoint->StartListener(tcpListener)) { | 
					
						
							|  |  |  | 		cout << "ERROR: Could not open H.323 listener port on " << ((H323ListenerTCP *) tcpListener)->GetListenerPort() << endl; | 
					
						
							| 
									
										
										
										
											2003-06-01 22:13:29 +00:00
										 |  |  | 		delete tcpListener; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-06-01 22:13:29 +00:00
										 |  |  | 	cout << "  == H.323 listener started" << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | /* Addition of functions just to make the channel driver compile with H323Plus */ | 
					
						
							|  |  |  | #if VERSION(OPENH323_MAJOR, OPENH323_MINOR, OPENH323_BUILD) > VERSION(1,19,4)
 | 
					
						
							|  |  |  | /* Alternate RTP port information for Same NAT */ | 
					
						
							|  |  |  | BOOL MyH323_ExternalRTPChannel::OnReceivedAltPDU(const H245_ArrayOf_GenericInformation & alternate ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Alternate RTP port information for Same NAT */ | 
					
						
							|  |  |  | BOOL MyH323_ExternalRTPChannel::OnSendingAltPDU(H245_ArrayOf_GenericInformation & alternate) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Alternate RTP port information for Same NAT */ | 
					
						
							|  |  |  | void MyH323_ExternalRTPChannel::OnSendOpenAckAlt(H245_ArrayOf_GenericInformation & alternate) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Alternate RTP port information for Same NAT */ | 
					
						
							|  |  |  | BOOL MyH323_ExternalRTPChannel::OnReceivedAckAltPDU(const H245_ArrayOf_GenericInformation & alternate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | int h323_set_alias(struct oh323_alias *alias) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-03-20 14:24:20 +00:00
										 |  |  | 	char *p; | 
					
						
							|  |  |  | 	char *num; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	PString h323id(alias->name); | 
					
						
							| 
									
										
										
										
											2004-03-20 14:24:20 +00:00
										 |  |  | 	PString e164(alias->e164); | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 	char *prefix; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl; | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	cout << "== Adding alias \"" << h323id << "\" to endpoint" << endl; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	endPoint->AddAliasName(h323id); | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | 	endPoint->RemoveAliasName(PProcess::Current().GetName()); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-20 14:24:20 +00:00
										 |  |  | 	if (!e164.IsEmpty()) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		cout << "== Adding E.164 \"" << e164 << "\" to endpoint" << endl; | 
					
						
							| 
									
										
										
										
											2004-03-20 14:24:20 +00:00
										 |  |  | 		endPoint->AddAliasName(e164); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-03-20 14:24:20 +00:00
										 |  |  | 	if (strlen(alias->prefix)) { | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 		p = prefix = strdup(alias->prefix); | 
					
						
							|  |  |  | 		while((num = strsep(&p, ",")) != (char *)NULL) { | 
					
						
							| 
									
										
										
										
											2005-05-21 16:27:57 +00:00
										 |  |  | 			cout << "== Adding Prefix \"" << num << "\" to endpoint" << endl; | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 			endPoint->SupportedPrefixes += PString(num); | 
					
						
							|  |  |  | 			endPoint->SetGateway(); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 		if (prefix) | 
					
						
							| 
									
										
										
										
											2009-03-11 04:06:44 +00:00
										 |  |  | 			ast_free(prefix); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-03 07:11:52 +00:00
										 |  |  | void h323_set_id(char *id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PString h323id(id); | 
					
						
							| 
									
										
										
										
											2003-06-04 07:14:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (h323debug) { | 
					
						
							| 
									
										
										
										
											2003-06-20 06:03:34 +00:00
										 |  |  | 		cout << "  == Using '" << h323id << "' as our H.323ID for this call" << endl; | 
					
						
							| 
									
										
										
										
											2003-06-04 07:14:10 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-06-03 07:11:52 +00:00
										 |  |  | 	/* EVIL HACK */ | 
					
						
							|  |  |  | 	endPoint->SetLocalUserName(h323id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-06 16:43:24 +00:00
										 |  |  | void h323_show_tokens(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	cout << "Current call tokens: " << setprecision(2) << endPoint->GetAllConnections() << endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-17 20:47:31 +00:00
										 |  |  | void h323_show_version(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     cout << "H.323 version: " << OPENH323_MAJOR << "." << OPENH323_MINOR << "." << OPENH323_BUILD << endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | /** Establish Gatekeeper communiations, if so configured,
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  |   *	register aliases for the H.323 endpoint to respond to. | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | int h323_set_gk(int gatekeeper_discover, char *gatekeeper, char *secret) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PString gkName = PString(gatekeeper); | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	PString pass = PString(secret); | 
					
						
							| 
									
										
										
										
											2004-01-13 03:07:15 +00:00
										 |  |  | 	H323TransportUDP *rasChannel; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << "ERROR: [h323_set_gk] No Endpoint, this is bad!" << endl; | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!gatekeeper) { | 
					
						
							|  |  |  | 		cout << "Error: Gatekeeper cannot be NULL" << endl; | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (strlen(secret)) { | 
					
						
							|  |  |  | 		endPoint->SetGatekeeperPassword(pass); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (gatekeeper_discover) { | 
					
						
							|  |  |  | 		/* discover the gk using multicast */ | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		if (endPoint->DiscoverGatekeeper(new MyH323TransportUDP(*endPoint))) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 			cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 			cout << "Warning: Could not find a gatekeeper." << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			return 1; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		rasChannel = new MyH323TransportUDP(*endPoint); | 
					
						
							| 
									
										
										
										
											2004-01-11 02:22:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-13 03:07:15 +00:00
										 |  |  | 		if (!rasChannel) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 			cout << "Error: No RAS Channel, this is bad" << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-01-13 03:07:15 +00:00
										 |  |  | 		if (endPoint->SetGatekeeper(gkName, rasChannel)) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 			cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 			cout << "Error registering with gatekeeper \"" << gkName << "\". " << endl; | 
					
						
							| 
									
										
										
										
											2003-06-01 22:13:29 +00:00
										 |  |  | 			/* XXX Maybe we should fire a new thread to attempt to re-register later and not kill asterisk here? */ | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Send a DTMF tone over the H323Connection with the
 | 
					
						
							|  |  |  |   * specified token. | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | void h323_send_tone(const char *call_token, char tone) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << "ERROR: [h323_send_tone] No Endpoint, this is bad!" << endl; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	PString token = PString(call_token); | 
					
						
							|  |  |  | 	endPoint->SendUserTone(token, tone); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Make a call to the remote endpoint.
 | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | int h323_make_call(char *dest, call_details_t *cd, call_options_t *call_options) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	PString	token; | 
					
						
							| 
									
										
										
										
											2004-11-11 21:30:30 +00:00
										 |  |  | 	PString	host(dest); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-11-11 21:30:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	res = endPoint->MyMakeCall(host, token, &cd->call_reference, call_options); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength()); | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | int h323_clear_call(const char *call_token, int cause) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 	H225_ReleaseCompleteReason dummy; | 
					
						
							| 
									
										
										
										
											2004-12-16 04:25:49 +00:00
										 |  |  | 	H323Connection::CallEndReason r = H323Connection::EndedByLocalUser; | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	MyH323Connection *connection; | 
					
						
							|  |  |  | 	const PString currentToken(call_token); | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 19:54:18 +00:00
										 |  |  | 	if (!h323_end_point_exist()) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-16 04:25:49 +00:00
										 |  |  | 	if (cause) { | 
					
						
							|  |  |  | 		r = H323TranslateToCallEndReason((Q931::CauseValues)(cause), dummy); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-15 23:24:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 	connection = (MyH323Connection *)endPoint->FindConnectionWithLock(currentToken); | 
					
						
							|  |  |  | 	if (connection) { | 
					
						
							|  |  |  | 		connection->SetCause(cause); | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 		connection->SetCallEndReason(r); | 
					
						
							| 
									
										
										
										
											2005-04-04 07:06:26 +00:00
										 |  |  | 		connection->Unlock(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	endPoint->ClearCall(currentToken, r); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | /* Send Alerting PDU to H.323 caller */ | 
					
						
							|  |  |  | int h323_send_alerting(const char *token) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	const PString currentToken(token); | 
					
						
							|  |  |  | 	H323Connection * connection; | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	if (h323debug) { | 
					
						
							|  |  |  | 		cout << "\tSending alerting" << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	connection = endPoint->FindConnectionWithLock(currentToken); | 
					
						
							|  |  |  | 	if (!connection) { | 
					
						
							|  |  |  | 		cout << "No connection found for " << token << endl; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	connection->AnsweringCall(H323Connection::AnswerCallPending); | 
					
						
							|  |  |  | 	connection->Unlock(); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Send Progress PDU to H.323 caller */ | 
					
						
							|  |  |  | int h323_send_progress(const char *token) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	const PString currentToken(token); | 
					
						
							|  |  |  | 	H323Connection * connection; | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	connection = endPoint->FindConnectionWithLock(currentToken); | 
					
						
							|  |  |  | 	if (!connection) { | 
					
						
							|  |  |  | 		cout << "No connection found for " << token << endl; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-28 13:02:30 +00:00
										 |  |  | #if 1
 | 
					
						
							|  |  |  | 	((MyH323Connection *)connection)->MySendProgress(); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia); | 
					
						
							| 
									
										
										
										
											2006-09-28 13:02:30 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	connection->Unlock(); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2004-05-20 07:07:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | /** This function tells the h.323 stack to either
 | 
					
						
							|  |  |  |     answer or deny an incoming call */ | 
					
						
							|  |  |  | int h323_answering_call(const char *token, int busy) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const PString currentToken(token); | 
					
						
							|  |  |  | 	H323Connection * connection; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	connection = endPoint->FindConnectionWithLock(currentToken); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	if (!connection) { | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		cout << "No connection found for " << token << endl; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-07-21 16:36:10 +00:00
										 |  |  | 	if (!busy) { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							|  |  |  | 			cout << "\tAnswering call " << token << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		connection->AnsweringCall(H323Connection::AnswerCallNow); | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 		if (h323debug) { | 
					
						
							|  |  |  | 			cout << "\tdenying call " << token << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		connection->AnsweringCall(H323Connection::AnswerCallDenied); | 
					
						
							| 
									
										
										
										
											2004-07-21 16:36:10 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	connection->Unlock(); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-06 16:43:24 +00:00
										 |  |  | int h323_soft_hangup(const char *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PString token(data); | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	PBoolean result; | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	cout << "Soft hangup" << endl; | 
					
						
							|  |  |  | 	result = endPoint->ClearCall(token); | 
					
						
							| 
									
										
										
										
											2004-01-06 16:43:24 +00:00
										 |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | /* alas, this doesn't work :( */ | 
					
						
							| 
									
										
										
										
											2004-07-22 04:24:50 +00:00
										 |  |  | void h323_native_bridge(const char *token, const char *them, char *capability) | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	H323Channel *channel; | 
					
						
							| 
									
										
										
										
											2003-08-25 18:34:10 +00:00
										 |  |  | 	MyH323Connection *connection = (MyH323Connection *)endPoint->FindConnectionWithLock(token); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-23 02:43:41 +00:00
										 |  |  | 	if (!connection) { | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 		cout << "ERROR: No connection found, this is bad" << endl; | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 	cout << "Native Bridge:  them [" << them << "]" << endl; | 
					
						
							| 
									
										
										
										
											2003-08-25 18:34:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	channel = connection->FindChannel(connection->sessionId, TRUE); | 
					
						
							|  |  |  | 	connection->bridging = TRUE; | 
					
						
							|  |  |  | 	connection->CloseLogicalChannelNumber(channel->GetNumber()); | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-25 18:34:10 +00:00
										 |  |  | 	connection->Unlock(); | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | 	return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | int h323_hold_call(const char *token, int is_hold) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MyH323Connection *conn = (MyH323Connection *)endPoint->FindConnectionWithLock(token); | 
					
						
							|  |  |  | 	if (!conn) { | 
					
						
							|  |  |  | 		cout << "ERROR: No connection found, this is bad" << endl; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-18 20:11:57 +00:00
										 |  |  | 	conn->MyHoldCall((PBoolean)is_hold); | 
					
						
							| 
									
										
										
										
											2006-09-28 10:41:38 +00:00
										 |  |  | 	conn->Unlock(); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | #undef cout
 | 
					
						
							| 
									
										
										
										
											2006-09-19 17:07:22 +00:00
										 |  |  | #undef endl
 | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | void h323_end_process(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (endPoint) { | 
					
						
							|  |  |  | 		delete endPoint; | 
					
						
							|  |  |  | 		endPoint = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-18 21:18:27 +00:00
										 |  |  | #ifndef SKIP_PWLIB_PIPE_BUG_WORKAROUND
 | 
					
						
							|  |  |  | 	close(_timerChangePipe[0]); | 
					
						
							|  |  |  | 	close(_timerChangePipe[1]); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 	if (logstream) { | 
					
						
							| 
									
										
										
										
											2010-05-24 22:05:15 +00:00
										 |  |  | 		PTrace::SetStream(NULL); | 
					
						
							| 
									
										
										
										
											2005-05-11 13:39:33 +00:00
										 |  |  | 		delete logstream; | 
					
						
							|  |  |  | 		logstream = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-31 07:13:36 +00:00
										 |  |  | } /* extern "C" */ | 
					
						
							| 
									
										
										
										
											2003-12-24 22:38:24 +00:00
										 |  |  | 
 |