[svn-commits] mattf: trunk r43281 - in /trunk: ./ build_tools/ channels/ channels/h323/ doc...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Sep 19 10:07:23 MST 2006


Author: mattf
Date: Tue Sep 19 12:07:22 2006
New Revision: 43281

URL: http://svn.digium.com/view/asterisk?rev=43281&view=rev
Log:
Mergeing in Paul Cadach's chan_h323 changes *holds breath*

Modified:
    trunk/Makefile
    trunk/acinclude.m4
    trunk/build_tools/cflags.xml
    trunk/build_tools/menuselect-deps.in
    trunk/channels/Makefile
    trunk/channels/chan_h323.c
    trunk/channels/h323/Makefile
    trunk/channels/h323/README
    trunk/channels/h323/TODO
    trunk/channels/h323/ast_h323.cpp
    trunk/channels/h323/ast_h323.h
    trunk/channels/h323/chan_h323.h
    trunk/channels/h323/h323.conf.sample
    trunk/configure.ac
    trunk/doc/realtime.txt
    trunk/main/Makefile

Modified: trunk/Makefile
URL: http://svn.digium.com/view/asterisk/trunk/Makefile?rev=43281&r1=43280&r2=43281&view=diff
==============================================================================
--- trunk/Makefile (original)
+++ trunk/Makefile Tue Sep 19 12:07:22 2006
@@ -641,7 +641,7 @@
 	rm -rf $(DESTDIR)$(ASTLOGDIR)
 
 menuselect: menuselect/menuselect menuselect-tree
-	- at menuselect/menuselect $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) menuselect.makeopts && echo "menuselect changes saved!" || echo "menuselect changes NOT saved!"
+	- at menuselect/menuselect $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) menuselect.makeopts && (echo "menuselect changes saved!"; rm -f channels/h323/Makefile.ast main/asterisk) || echo "menuselect changes NOT saved!"
 
 menuselect/menuselect: makeopts menuselect/menuselect.c menuselect/menuselect_curses.c menuselect/menuselect_stub.c menuselect/menuselect.h menuselect/linkedlists.h makeopts
 	@unset CC LD AR RANLIB && $(MAKE) -C menuselect CONFIGURE_SILENT="--silent"

Modified: trunk/acinclude.m4
URL: http://svn.digium.com/view/asterisk/trunk/acinclude.m4?rev=43281&r1=43280&r2=43281&view=diff
==============================================================================
--- trunk/acinclude.m4 (original)
+++ trunk/acinclude.m4 Tue Sep 19 12:07:22 2006
@@ -116,6 +116,320 @@
 AC_SUBST([GNU_MAKE])
 ])
 
+
+AC_DEFUN(
+[AST_CHECK_PWLIB], [
+PWLIB_INCDIR=
+PWLIB_LIBDIR=
+if test "${PWLIBDIR:-unset}" != "unset" ; then
+  AC_CHECK_FILE(${PWLIBDIR}/version.h, HAS_PWLIB=1, )
+fi
+if test "${HAS_PWLIB:-unset}" = "unset" ; then
+  if test "${OPENH323DIR:-unset}" != "unset"; then
+    AC_CHECK_FILE(${OPENH323DIR}/../pwlib/version.h, HAS_PWLIB=1, )
+  fi
+  if test "${HAS_PWLIB:-unset}" != "unset" ; then
+    PWLIBDIR="${OPENH323DIR}/../pwlib"
+  else
+    AC_CHECK_FILE(${HOME}/pwlib/include/ptlib.h, HAS_PWLIB=1, )
+    if test "${HAS_PWLIB:-unset}" != "unset" ; then
+      PWLIBDIR="${HOME}/pwlib"
+    else
+      AC_CHECK_FILE(/usr/local/include/ptlib.h, HAS_PWLIB=1, )
+      if test "${HAS_PWLIB:-unset}" != "unset" ; then
+        AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/bin)
+        if test "${PTLIB_CONFIG:-unset}" = "unset" ; then
+          AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/share/pwlib/make)
+        fi
+        PWLIB_INCDIR="/usr/local/include"
+        PWLIB_LIBDIR="/usr/local/lib"
+      else
+        AC_CHECK_FILE(/usr/include/ptlib.h, HAS_PWLIB=1, )
+        if test "${HAS_PWLIB:-unset}" != "unset" ; then
+          AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/share/pwlib/make)
+          PWLIB_INCDIR="/usr/include"
+          PWLIB_LIBDIR="/usr/lib"
+        fi
+      fi
+    fi
+  fi
+fi
+
+#if test "${HAS_PWLIB:-unset}" = "unset" ; then
+#  echo "Cannot find pwlib - please install or set PWLIBDIR and try again"
+#  exit
+#fi
+
+if test "${HAS_PWLIB:-unset}" != "unset" ; then
+  if test "${PWLIBDIR:-unset}" = "unset" ; then
+    if test "${PTLIB_CONFIG:-unset}" != "unset" ; then
+      PWLIBDIR=`$PTLIB_CONFIG --prefix`
+    else
+      echo "Cannot find ptlib-config - please install and try again"
+      exit
+    fi
+  fi
+
+  if test "x$PWLIBDIR" = "x/usr" -o "x$PWLIBDIR" = "x/usr/"; then
+    PWLIBDIR="/usr/share/pwlib"
+    PWLIB_INCDIR="/usr/include"
+    PWLIB_LIBDIR="/usr/lib"
+  fi
+  if test "x$PWLIBDIR" = "x/usr/local" -o "x$PWLIBDIR" = "x/usr/"; then
+    PWLIBDIR="/usr/local/share/pwlib"
+    PWLIB_INCDIR="/usr/local/include"
+    PWLIB_LIBDIR="/usr/local/lib"
+  fi
+
+  if test "${PWLIB_INCDIR:-unset}" = "unset"; then
+    PWLIB_INCDIR="${PWLIBDIR}/include"
+  fi
+  if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
+    PWLIB_LIBDIR="${PWLIBDIR}/lib"
+  fi
+
+  AC_SUBST([PWLIBDIR])
+  AC_SUBST([PWLIB_INCDIR])
+  AC_SUBST([PWLIB_LIBDIR])
+fi
+])
+
+
+AC_DEFUN(
+[AST_CHECK_OPENH323_PLATFORM], [
+PWLIB_OSTYPE=
+case "$host_os" in
+  linux*)          PWLIB_OSTYPE=linux ;
+  		;;
+  freebsd* )       PWLIB_OSTYPE=FreeBSD ;
+  		;;
+  openbsd* )       PWLIB_OSTYPE=OpenBSD ;
+				   ENDLDLIBS="-lossaudio" ;
+		;;
+  netbsd* )        PWLIB_OSTYPE=NetBSD ;
+				   ENDLDLIBS="-lossaudio" ;
+		;;
+  solaris* | sunos* ) PWLIB_OSTYPE=solaris ;
+		;;
+  darwin* )	       PWLIB_OSTYPE=Darwin ;
+		;;
+  beos*)           PWLIB_OSTYPE=beos ;
+                   STDCCFLAGS="$STDCCFLAGS -D__BEOS__"
+		;;
+  cygwin*)         PWLIB_OSTYPE=cygwin ;
+		;;
+  mingw*)	       PWLIB_OSTYPE=mingw ;
+		           STDCCFLAGS="$STDCCFLAGS -mms-bitfields" ;
+		           ENDLDLIBS="-lwinmm -lwsock32 -lsnmpapi -lmpr -lcomdlg32 -lgdi32 -lavicap32" ;
+		;;
+  * )		       PWLIB_OSTYPE="$host_os" ;
+		           AC_MSG_WARN("OS $PWLIB_OSTYPE not recognized - proceed with caution!") ;
+		;;
+esac
+
+PWLIB_MACHTYPE=
+case "$host_cpu" in
+   x86 | i686 | i586 | i486 | i386 ) PWLIB_MACHTYPE=x86
+                   ;;
+
+   x86_64)	   PWLIB_MACHTYPE=x86_64 ;
+		   P_64BIT=1 ;
+                   LIB64=1 ;
+		   ;;
+
+   alpha | alphaev56 | alphaev6 | alphaev67 | alphaev7) PWLIB_MACHTYPE=alpha ;
+		   P_64BIT=1 ;
+		   ;;
+
+   sparc )         PWLIB_MACHTYPE=sparc ;
+		   ;;
+
+   powerpc )       PWLIB_MACHTYPE=ppc ;
+		   ;;
+
+   ppc )           PWLIB_MACHTYPE=ppc ;
+		   ;;
+
+   powerpc64 )     PWLIB_MACHTYPE=ppc64 ;
+		   P_64BIT=1 ;
+                   LIB64=1 ;
+		   ;;
+
+   ppc64 )         PWLIB_MACHTYPE=ppc64 ;
+		   P_64BIT=1 ;
+                   LIB64=1 ;
+		   ;;
+
+   ia64)	   PWLIB_MACHTYPE=ia64 ;
+		   P_64BIT=1 ;
+	  	   ;;
+
+   s390x)	   PWLIB_MACHTYPE=s390x ;
+		   P_64BIT=1 ;
+                   LIB64=1 ;
+		   ;;
+
+   s390)	   PWLIB_MACHTYPE=s390 ;
+		   ;;
+
+   * )		   PWLIB_MACHTYPE="$host_cpu";
+		   AC_MSG_WARN("CPU $PWLIB_MACHTYPE not recognized - proceed with caution!") ;;
+esac
+
+PWLIB_PLATFORM="${PWLIB_OSTYPE}_${PWLIB_MACHTYPE}"
+
+AC_SUBST([PWLIB_PLATFORM])
+])
+
+
+AC_DEFUN(
+[AST_CHECK_OPENH323], [
+OPENH323_INCDIR=
+OPENH323_LIBDIR=
+if test "${OPENH323DIR:-unset}" != "unset" ; then
+  AC_CHECK_FILE(${OPENH323DIR}/version.h, HAS_OPENH323=1, )
+fi
+if test "${HAS_OPENH323:-unset}" = "unset" ; then
+  AC_CHECK_FILE(${PWLIBDIR}/../openh323/version.h, OPENH323DIR="${PWLIBDIR}/../openh323"; HAS_OPENH323=1, )
+  if test "${HAS_OPENH323:-unset}" != "unset" ; then
+    OPENH323DIR="${PWLIBDIR}/../openh323"
+    AC_CHECK_FILE(${OPENH323DIR}/include/h323.h, , OPENH323_INCDIR="${PWLIB_INCDIR}/openh323"; OPENH323_LIBDIR="${PWLIB_LIBDIR}")
+  else
+    AC_CHECK_FILE(${HOME}/openh323/include/h323.h, HAS_OPENH323=1, )
+    if test "${HAS_OPENH323:-unset}" != "unset" ; then
+      OPENH323DIR="${HOME}/openh323"
+    else
+      AC_CHECK_FILE(/usr/local/include/openh323/h323.h, HAS_OPENH323=1, )
+      if test "${HAS_OPENH323:-unset}" != "unset" ; then
+        OPENH323DIR="/usr/local/share/openh323"
+        OPENH323_INCDIR="/usr/local/include/openh323"
+        OPENH323_LIBDIR="/usr/local/lib"
+      else
+        AC_CHECK_FILE(/usr/include/openh323/h323.h, HAS_OPENH323=1, )
+        if test "${HAS_OPENH323:-unset}" != "unset" ; then
+          OPENH323DIR="/usr/share/openh323"
+          OPENH323_INCDIR="/usr/include/openh323"
+          OPENH323_LIBDIR="/usr/lib"
+        fi
+      fi
+    fi
+  fi
+fi
+
+if test "${HAS_OPENH323:-unset}" != "unset" ; then
+  if test "${OPENH323_INCDIR:-unset}" = "unset"; then
+    OPENH323_INCDIR="${OPENH323DIR}/include"
+  fi
+  if test "${OPENH323_LIBDIR:-unset}" = "unset"; then
+    OPENH323_LIBDIR="${OPENH323DIR}/lib"
+  fi
+
+  AC_SUBST([OPENH323DIR])
+  AC_SUBST([OPENH323_INCDIR])
+  AC_SUBST([OPENH323_LIBDIR])
+fi
+])
+
+
+AC_DEFUN(
+[AST_CHECK_PWLIB_VERSION], [
+	if test "${HAS_$2:-unset}" != "unset"; then
+		$2_VERSION=`grep "$2_VERSION" ${$2_INCDIR}/$3 | cut -f2 -d ' ' | sed -e 's/"//g'`
+		$2_MAJOR_VERSION=`echo ${$2_VERSION} | cut -f1 -d.`
+		$2_MINOR_VERSION=`echo ${$2_VERSION} | cut -f2 -d.`
+		$2_BUILD_NUMBER=`echo ${$2_VERSION} | cut -f3 -d.`
+		let $2_VER=${$2_MAJOR_VERSION}*10000+${$2_MINOR_VERSION}*100+${$2_BUILD_NUMBER}
+		let $2_REQ=$4*10000+$5*100+$6
+
+		AC_MSG_CHECKING(if $1 version ${$2_VERSION} is compatible with chan_h323)
+		if test ${$2_VER} -lt ${$2_REQ}; then
+			AC_MSG_RESULT(no)
+			unset HAS_$2
+		else
+			AC_MSG_RESULT(yes)
+		fi
+	fi
+])
+
+
+AC_DEFUN(
+[AST_CHECK_PWLIB_BUILD], [
+	if test "${HAS_$2:-unset}" != "unset"; then
+	   AC_MSG_CHECKING($1 installation validity)
+
+	   saved_cppflags="${CPPFLAGS}"
+	   saved_libs="${LIBS}"
+	   LIBS="${LIBS} -L${$2_LIBDIR} -l${PLATFORM_$2} $7"
+	   CPPFLAGS="${CPPFLAGS} -I${$2_INCDIR} $6"
+
+	   AC_LANG_PUSH([C++])
+
+	   AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([$4],[$5])],
+		[	AC_MSG_RESULT(yes) 
+			ac_cv_lib_$2="yes" 
+		],
+		[	AC_MSG_RESULT(no) 
+			ac_cv_lib_$2="no" 
+		]
+		)
+
+	   AC_LANG_POP([C++])
+
+	   LIBS="${saved_libs}"
+	   CPPFLAGS="${saved_cppflags}"
+
+	   if test "${ac_cv_lib_$2}" = "yes"; then
+	      if test "${$2_LIBDIR}" != "" -a "${$2_LIBDIR}" != "/usr/lib"; then
+	         $2_LIB="-L${$2_LIBDIR} -l${PLATFORM_$2}"
+	      else
+	         $2_LIB="-l${PLATFORM_$2}"
+	      fi
+	      if test "${$2_INCDIR}" != "" -a "${$2_INCDIR}" != "/usr/include"; then
+	         $2_INCLUDE="-I${$2_INCDIR}"
+	      fi
+	   	  PBX_$2=1
+	   	  AC_DEFINE([HAVE_$2], 1, [$3])
+	   fi
+	fi
+])
+
+AC_DEFUN(
+[AST_CHECK_OPENH323_BUILD], [
+	if test "${HAS_OPENH323:-unset}" != "unset"; then
+		AC_MSG_CHECKING(OpenH323 build option)
+		OPENH323_SUFFIX=
+		files=`ls -l ${OPENH323_LIBDIR}/libh323_${PWLIB_PLATFORM}_*.so*`
+		libfile=
+		if test -n "$files"; then
+			for f in $files; do
+				if test -f $f -a ! -L $f; then
+					libfile=`basename $f`
+					break;
+				fi
+			done
+		fi
+		if test "${libfile:-unset}" != "unset"; then
+			OPENH323_SUFFIX=`eval "echo ${libfile} | sed -e 's/libh323_${PWLIB_PLATFORM}_\(@<:@^.@:>@*\)\..*/\1/'"`
+		fi
+		case "${OPENH323_SUFFIX}" in
+			n)
+				OPENH323_BUILD="notrace";;
+			r)
+				OPENH323_BUILD="opt";;
+			d)
+				OPENH323_BUILD="debug";;
+			*)
+				OPENH323_BUILD="notrace";;
+		esac
+		AC_MSG_RESULT(${OPENH323_BUILD})
+
+		AC_SUBST([OPENH323_SUFFIX])
+		AC_SUBST([OPENH323_BUILD])
+	fi
+])
+
+
 # AST_FUNC_FORK
 # -------------
 AN_FUNCTION([fork],  [AST_FUNC_FORK])

Modified: trunk/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/trunk/build_tools/cflags.xml?rev=43281&r1=43280&r2=43281&view=diff
==============================================================================
--- trunk/build_tools/cflags.xml (original)
+++ trunk/build_tools/cflags.xml Tue Sep 19 12:07:22 2006
@@ -6,6 +6,8 @@
 		<member name="DEBUG_THREADS" displayname="Enable Thread Debugging">
 		</member>
 		<member name="DETECT_DEADLOCKS" displayname="Detect Deadlocks">
+		</member>
+		<member name="DO_CRASH" displayname="Crash on fatal errors">
 		</member>
 		<member name="DONT_OPTIMIZE" displayname="Disable Optimizations by the Compiler">
 		</member>

Modified: trunk/build_tools/menuselect-deps.in
URL: http://svn.digium.com/view/asterisk/trunk/build_tools/menuselect-deps.in?rev=43281&r1=43280&r2=43281&view=diff
==============================================================================
--- trunk/build_tools/menuselect-deps.in (original)
+++ trunk/build_tools/menuselect-deps.in Tue Sep 19 12:07:22 2006
@@ -4,6 +4,7 @@
 GSM=@PBX_GSM@
 GTK=@PBX_GTK@
 H323=@PBX_H323@
+OPENH323=@PBX_OPENH323@
 IKSEMEL=@PBX_IKSEMEL@
 IMAP_TK=@PBX_IMAP_TK@
 IXJUSER=@PBX_IXJUSER@

Modified: trunk/channels/Makefile
URL: http://svn.digium.com/view/asterisk/trunk/channels/Makefile?rev=43281&r1=43280&r2=43281&view=diff
==============================================================================
--- trunk/channels/Makefile (original)
+++ trunk/channels/Makefile Tue Sep 19 12:07:22 2006
@@ -63,7 +63,20 @@
 	rm -f busy.h ringtone.h gentone
 	$(MAKE) -C misdn clean
 
--include $(PWD)/Makefile.ast
+ifneq ($(wildcard h323/Makefile.ast),)
+  include h323/Makefile.ast
+H323LDFLAGS += -Wl,--version-script=h323/noexport.map
+else
+h323/libchanh323.a h323/Makefile.ast:
+	$(CMD_PREFIX) $(MAKE) -C h323
+	$(CMD_PREFIX) rm -f ../main/asterisk
+	$(CMD_PREFIX) echo "***************************************************************"
+	$(CMD_PREFIX) echo
+	$(CMD_PREFIX) echo "********** Re-run 'make' to pick up H.323 parameters **********"
+	$(CMD_PREFIX) echo
+	$(CMD_PREFIX) echo "***************************************************************"
+	$(CMD_PREFIX) exit 1
+endif
 
 $(eval $(call ast_make_final_host,gentone,gentone.c))
 gentone: LIBS+=-lm
@@ -81,11 +94,13 @@
 chan_alsa.o: busy.h ringtone.h
 
 ifeq ($(OSARCH),linux-gnu)
-chan_h323.so: chan_h323.o h323_module_interface.so h323/libchanh323.a h323/Makefile.ast
-	$(CC) $(SOLINK) $(H323LDFLAGS) -o $@ $^ h323/libchanh323.a $(H323LDLIBS) -lstdc++
+chan_h323.so: chan_h323.o h323/libchanh323.a h323/Makefile.ast
+	$(ECHO_PREFIX) echo "   [LD] $^ -> $@"
+	$(CMD_PREFIX) $(CXX) $(SOLINK) $(H323LDFLAGS) -o $@ $< h323/libchanh323.a $(H323LDLIBS)
 else
-chan_h323.so: chan_h323.o h323_module_interface.so h323/libchanh323.a
-	$(CC) $(SOLINK) -o $@ $^ h323/libchanh323.a $(CHANH323LIB) -L$(PWLIBDIR)/lib $(PTLIB) -L$(OPENH323DIR)/lib $(H323LIB) -L/usr/lib -lcrypto -lssl -lexpat
+chan_h323.so: chan_h323.o h323/libchanh323.a
+	$(ECHO_PREFIX) echo "   [LD] $^ -> $@"
+	$(CMD_PREFIX) $(CXX) $(SOLINK) -o $@ $< h323/libchanh323.a $(CHANH323LIB) -L$(PWLIBDIR)/lib $(PTLIB) -L$(OPENH323DIR)/lib $(H323LIB) -L/usr/lib -lcrypto -lssl -lexpat
 endif
 
 chan_misdn.o: CFLAGS+=-Imisdn -DCHAN_MISDN_VERSION=\"0.3.0\" 

Modified: trunk/channels/chan_h323.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_h323.c?rev=43281&r1=43280&r2=43281&view=diff
==============================================================================
--- trunk/channels/chan_h323.c (original)
+++ trunk/channels/chan_h323.c Tue Sep 19 12:07:22 2006
@@ -5,7 +5,7 @@
  *
  * OpenH323 Channel Driver for ASTERISK PBX.
  *			By Jeremy McNamara
- *                      For The NuFone Network 
+ *                      For The NuFone Network
  *
  * chan_h323 has been derived from code created by
  *               Michael Manousos and Mark Spencer
@@ -34,12 +34,13 @@
  */
 
 /*** MODULEINFO
-	<depend>h323</depend>
+	<depend>openh323</depend>
+	<defaultenabled>no</defaultenabled>
  ***/
 
 #ifdef __cplusplus
 extern "C" {
-#endif   
+#endif
 
 #include "asterisk.h"
 
@@ -72,13 +73,14 @@
 
 #ifdef __cplusplus
 extern "C" {
-#endif   
+#endif
 
 #include "asterisk/lock.h"
 #include "asterisk/logger.h"
 #include "asterisk/channel.h"
 #include "asterisk/config.h"
 #include "asterisk/module.h"
+#include "asterisk/musiconhold.h"
 #include "asterisk/pbx.h"
 #include "asterisk/options.h"
 #include "asterisk/utils.h"
@@ -93,6 +95,7 @@
 #include "asterisk/causes.h"
 #include "asterisk/stringfields.h"
 #include "asterisk/abstract_jb.h"
+#include "asterisk/astobj.h"
 
 #ifdef __cplusplus
 }
@@ -100,11 +103,11 @@
 
 #include "h323/chan_h323.h"
 
-send_digit_cb on_send_digit; 
-on_rtp_cb on_external_rtp_create; 
-start_rtp_cb on_start_rtp_channel; 
+receive_digit_cb on_receive_digit;
+on_rtp_cb on_external_rtp_create;
+start_rtp_cb on_start_rtp_channel;
 setup_incoming_cb on_incoming_call;
-setup_outbound_cb on_outgoing_call; 
+setup_outbound_cb on_outgoing_call;
 chan_ringing_cb	on_chan_ringing;
 con_established_cb on_connection_established;
 clear_con_cb on_connection_cleared;
@@ -113,6 +116,7 @@
 rfc2833_cb on_set_rfc2833_payload;
 hangup_cb on_hangup;
 setcapabilities_cb on_setcapabilities;
+setpeercapabilities_cb on_setpeercapabilities;
 
 /* global debug flag */
 int h323debug;
@@ -128,7 +132,7 @@
 static struct ast_jb_conf global_jbconf;
 
 /** Variables required by Asterisk */
-static const char desc[] = "The NuFone Network's Open H.323 Channel Driver";
+static const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver";
 static const char config[] = "h323.conf";
 static char default_context[AST_MAX_CONTEXT] = "default";
 static struct sockaddr_in bindaddr;
@@ -140,10 +144,10 @@
 static char gatekeeper[100];
 static int gatekeeper_disable = 1;
 static int gatekeeper_discover = 0;
-static int usingGk = 0;
 static int gkroute = 0;
 /* Find user by alias (h.323 id) is default, alternative is the incomming call's source IP address*/
 static int userbyalias = 1;
+static int acceptAnonymous = 1;
 static int tos = 0;
 static char secret[50];
 static unsigned int unique = 0;
@@ -153,46 +157,53 @@
 /** Private structure of a OpenH323 channel */
 struct oh323_pvt {
 	ast_mutex_t lock;					/* Channel private lock */
-	call_options_t options;					/* Options to be used during call setup */
+	call_options_t options;				/* Options to be used during call setup */
 	int alreadygone;					/* Whether or not we've already been destroyed by our peer */
 	int needdestroy;					/* if we need to be destroyed */
 	call_details_t cd;					/* Call details */
-	struct ast_channel *owner;				/* Who owns us */
-	struct sockaddr_in sa;                  		/* Our peer */
-	struct sockaddr_in redirip; 			        /* Where our RTP should be going if not to us */
-	int nonCodecCapability;					/* non-audio capability */
+	struct ast_channel *owner;			/* Who owns us */
+	struct sockaddr_in sa;				/* Our peer */
+	struct sockaddr_in redirip;			/* Where our RTP should be going if not to us */
+	int nonCodecCapability;				/* non-audio capability */
 	int outgoing;						/* Outgoing or incoming call? */
-	char exten[AST_MAX_EXTENSION];				/* Requested extension */
-	char context[AST_MAX_CONTEXT];				/* Context where to start */
-	char accountcode[256];					/* Account code */
-	char cid_num[80];					/* Caller*id number, if available */
-	char cid_name[80];					/* Caller*id name, if available */
+	char exten[AST_MAX_EXTENSION];		/* Requested extension */
+	char context[AST_MAX_CONTEXT];		/* Context where to start */
+	char accountcode[256];				/* Account code */
 	char rdnis[80];						/* Referring DNIS, if available */
 	int amaflags;						/* AMA Flags */
-	struct ast_rtp *rtp;					/* RTP Session */
-	struct ast_dsp *vad;					/* Used for in-band DTMF detection */
+	struct ast_rtp *rtp;				/* RTP Session */
+	struct ast_dsp *vad;				/* Used for in-band DTMF detection */
 	int nativeformats;					/* Codec formats supported by a channel */
 	int needhangup;						/* Send hangup when Asterisk is ready */
 	int hangupcause;					/* Hangup cause from OpenH323 layer */
 	int newstate;						/* Pending state change */
 	int newcontrol;						/* Pending control to send */
 	int newdigit;						/* Pending DTMF digit to send */
+	int newduration;					/* Pending DTMF digit duration to send */
+	int pref_codec;						/* Preferred codec */
+	int peercapability;					/* Capabilities learned from peer */
+	int jointcapability;				/* Common capabilities for local and remote side */
+	int dtmf_pt;						/* Payload code used for RFC2833 messages */
+	int curDTMF;						/* DTMF tone being generated to Asterisk side */
+	int DTMFsched;						/* Scheduler descriptor for DTMF */
+	int update_rtp_info;				/* Configuration of fd's array is pending */
+	int recvonly;						/* Peer isn't wish to receive our voice stream */
+	int txDtmfDigit;					/* DTMF digit being to send to H.323 side */
+	int noInbandDtmf;					/* Inband DTMF processing by DSP isn't available */
+	int connection_established;			/* Call got CONNECT message */
 	struct oh323_pvt *next;				/* Next channel in list */
 } *iflist = NULL;
 
 static struct ast_user_list {
-	struct oh323_user *users;
-	ast_mutex_t lock;
+	ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user);
 } userl;
 
 static struct ast_peer_list {
-	struct oh323_peer *peers;
-	ast_mutex_t lock;
+	ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer);
 } peerl;
 
 static struct ast_alias_list {
-	struct oh323_alias *aliases;
-	ast_mutex_t lock;
+	ASTOBJ_CONTAINER_COMPONENTS(struct oh323_alias);
 } aliasl;
 
 /** Asterisk RTP stuff */
@@ -214,7 +225,7 @@
 static int h323_reloading = 0;
 
 /* This is the thread for the monitor which checks for input on the channels
-   which are not currently in use.  */
+   which are not currently in use. */
 static pthread_t monitor_thread = AST_PTHREADT_NULL;
 static int restart_monitor(void);
 static int h323_do_reload(void);
@@ -251,6 +262,76 @@
 #endif
 };
 
+static const char* redirectingreason2str(int redirectingreason)
+{
+	switch (redirectingreason) {
+	case 0:
+		return "UNKNOWN";
+	case 1:
+		return "BUSY";
+	case 2:
+		return "NO_REPLY";
+	case 0xF:
+		return "UNCONDITIONAL";
+	default:
+		return "NOREDIRECT";
+	}
+}
+
+static void oh323_destroy_alias(struct oh323_alias *alias)
+{
+	if (h323debug)
+		ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name);
+	free(alias);
+}
+
+static void oh323_destroy_user(struct oh323_user *user)
+{
+	if (h323debug)
+		ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name);
+	ast_free_ha(user->ha);
+	free(user);
+}
+
+static void oh323_destroy_peer(struct oh323_peer *peer)
+{
+	if (h323debug)
+		ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name);
+	ast_free_ha(peer->ha);
+	free(peer);
+}
+
+static int oh323_simulate_dtmf_end(void *data)
+{
+	struct oh323_pvt *pvt = data;
+
+	if (pvt) {
+		ast_mutex_lock(&pvt->lock);
+		/* Don't hold pvt lock while trying to lock the channel */
+		while(pvt->owner && ast_channel_trylock(pvt->owner)) {
+			ast_mutex_unlock(&pvt->lock);
+			usleep(1);
+			ast_mutex_lock(&pvt->lock);
+		}
+
+		if (pvt->owner) {
+			struct ast_frame f = {
+				.frametype = AST_FRAME_DTMF_END,
+				.subclass = pvt->curDTMF,
+				.samples = 0,
+				.src = "SIMULATE_DTMF_END",
+			};
+			ast_queue_frame(pvt->owner, &f);
+			ast_channel_unlock(pvt->owner);
+		}
+
+		pvt->DTMFsched = -1;
+		ast_mutex_unlock(&pvt->lock);
+	}
+
+	return 0;
+}
+
 /* Channel and private structures should be already locked */
 static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
 {
@@ -268,7 +349,7 @@
 		c->hangupcause = pvt->hangupcause;
 		ast_queue_hangup(c);
 		pvt->needhangup = 0;
-		pvt->newstate = pvt->newcontrol = pvt->newdigit = -1;
+		pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1;
 	}
 	if (pvt->newstate >= 0) {
 		ast_setstate(c, pvt->newstate);
@@ -280,14 +361,39 @@
 	}
 	if (pvt->newdigit >= 0) {
 		struct ast_frame f = {
-			.frametype = AST_FRAME_DTMF,
+			.frametype = AST_FRAME_DTMF_END,
 			.subclass = pvt->newdigit,
-			.samples = 800,
+			.samples = pvt->newduration * 8,
 			.src = "UPDATE_INFO",
 		};
-
+		if (pvt->newdigit == ' ') {		/* signalUpdate message */
+			f.subclass = pvt->curDTMF;
+			if (pvt->DTMFsched >= 0) {
+				ast_sched_del(sched, pvt->DTMFsched);
+				pvt->DTMFsched = -1;
+			}
+		} else {						/* Regular input or signal message */
+			if (pvt->newduration) {		/* This is a signal, signalUpdate follows */
+				f.frametype = AST_FRAME_DTMF_BEGIN;
+				if (pvt->DTMFsched >= 0)
+					ast_sched_del(sched, pvt->DTMFsched);
+				pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt);
+				if (h323debug)
+					ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched);
+			}
+			pvt->curDTMF = pvt->newdigit;
+		}
 		ast_queue_frame(c, &f);
 		pvt->newdigit = -1;
+	}
+	if (pvt->update_rtp_info > 0) {
+		if (pvt->rtp) {
+			ast_jb_configure(c, &global_jbconf);
+			c->fds[0] = ast_rtp_fd(pvt->rtp);
+			c->fds[1] = ast_rtcp_fd(pvt->rtp);
+			ast_queue_frame(pvt->owner, &ast_null_frame);	/* Tell Asterisk to apply changes */
+		}
+		pvt->update_rtp_info = -1;
 	}
 }
 
@@ -303,46 +409,55 @@
 	}
 }
 
-static void cleanup_call_details(call_details_t *cd) 
-{
-        if (cd->call_token) {
-                free(cd->call_token);
-                cd->call_token = NULL;
-        }
-        if (cd->call_source_aliases) {
-                free(cd->call_source_aliases);
-                cd->call_source_aliases = NULL;
-        }
-        if (cd->call_dest_alias) {
-                free(cd->call_dest_alias);
-                cd->call_dest_alias = NULL;
-	}
-        if (cd->call_source_name) { 
-                free(cd->call_source_name);
-                cd->call_source_name = NULL;
-        }
-        if (cd->call_source_e164) {
-                free(cd->call_source_e164);
-                cd->call_source_e164 = NULL;
-        }
-        if (cd->call_dest_e164) {
-                free(cd->call_dest_e164);
-                cd->call_dest_e164 = NULL;
-        }
-        if (cd->sourceIp) {
-                free(cd->sourceIp);
-                cd->sourceIp = NULL;
-        }
+static void cleanup_call_details(call_details_t *cd)
+{
+	if (cd->call_token) {
+		free(cd->call_token);
+		cd->call_token = NULL;
+	}
+	if (cd->call_source_aliases) {
+		free(cd->call_source_aliases);
+		cd->call_source_aliases = NULL;
+	}
+	if (cd->call_dest_alias) {
+		free(cd->call_dest_alias);
+		cd->call_dest_alias = NULL;
+	}
+	if (cd->call_source_name) {
+		free(cd->call_source_name);
+		cd->call_source_name = NULL;
+	}
+	if (cd->call_source_e164) {
+		free(cd->call_source_e164);
+		cd->call_source_e164 = NULL;
+	}
+	if (cd->call_dest_e164) {
+		free(cd->call_dest_e164);
+		cd->call_dest_e164 = NULL;
+	}
+	if (cd->sourceIp) {
+		free(cd->sourceIp);
+		cd->sourceIp = NULL;
+	}
+	if (cd->redirect_number) {
+		free(cd->redirect_number);
+		cd->redirect_number = NULL;
+	}
 }
 
 static void __oh323_destroy(struct oh323_pvt *pvt)
 {
 	struct oh323_pvt *cur, *prev = NULL;
-	
+
+	if (pvt->DTMFsched >= 0) {
+		ast_sched_del(sched, pvt->DTMFsched);
+		pvt->DTMFsched = -1;
+	}
+
 	if (pvt->rtp) {
 		ast_rtp_destroy(pvt->rtp);
 	}
-	
+
 	/* Free dsp used for in-band DTMF detection */
 	if (pvt->vad) {
 		ast_dsp_free(pvt->vad);
@@ -351,10 +466,11 @@
 
 	/* Unlink us from the owner if we have one */
 	if (pvt->owner) {
-		ast_mutex_lock(&pvt->owner->lock);
-		ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name);
+		ast_channel_lock(pvt->owner);
+		if (h323debug)
+			ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name);
 		pvt->owner->tech_pvt = NULL;
-		ast_mutex_unlock(&pvt->owner->lock);
+		ast_channel_unlock(pvt->owner);
 	}
 	cur = iflist;
 	while(cur) {
@@ -371,6 +487,7 @@
 	if (!cur) {
 		ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
 	} else {
+		ast_mutex_unlock(&pvt->lock);
 		ast_mutex_destroy(&pvt->lock);
 		free(pvt);
 	}
@@ -378,22 +495,16 @@
 
 static void oh323_destroy(struct oh323_pvt *pvt)
 {
+	if (h323debug) {
+		ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>"));
+	}
 	ast_mutex_lock(&iflock);
+	ast_mutex_lock(&pvt->lock);
 	__oh323_destroy(pvt);
 	ast_mutex_unlock(&iflock);
 }
 
-static int oh323_digit_begin(struct ast_channel *chan, char digit)
-{
-	/* XXX Implement me, plz, kthx */
-	return 0;
-}
-
-/**
- * Send (play) the specified digit to the channel.
- * 
- */
-static int oh323_digit_end(struct ast_channel *c, char digit)
+static int oh323_digit_begin(struct ast_channel *c, char digit)
 {
 	struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
 	char *token;
@@ -403,39 +514,79 @@
 		return -1;
 	}
 	ast_mutex_lock(&pvt->lock);
-	if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
+	if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
 		/* out-of-band DTMF */
 		if (h323debug) {
-			ast_log(LOG_DEBUG, "Sending out-of-band digit %c on %s\n", digit, c->name);
-		}
-		ast_rtp_senddigit(pvt->rtp, digit);
+			ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name);
+		}
+		ast_rtp_senddigit_begin(pvt->rtp, digit);
 		ast_mutex_unlock(&pvt->lock);
-	} else {
+	} else if (pvt->txDtmfDigit != digit) {
 		/* in-band DTMF */
 		if (h323debug) {
-			ast_log(LOG_DEBUG, "Sending inband digit %c on %s\n", digit, c->name);
-		}
+			ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name);
+		}
+		pvt->txDtmfDigit = digit;
 		token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
 		ast_mutex_unlock(&pvt->lock);
 		h323_send_tone(token, digit);
 		if (token) {
 			free(token);
 		}
-	}
+	} else
+		ast_mutex_unlock(&pvt->lock);
 	oh323_update_info(c);
 	return 0;
 }
 
 /**
- * Make a call over the specified channel to the specified 
+ * Send (play) the specified digit to the channel.
+ *
+ */
+static int oh323_digit_end(struct ast_channel *c, char digit)
+{
+	struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
+	char *token;
+
+	if (!pvt) {
+		ast_log(LOG_ERROR, "No private structure?! This is bad\n");
+		return -1;
+	}
+	ast_mutex_lock(&pvt->lock);
+	if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
+		/* out-of-band DTMF */
+		if (h323debug) {
+			ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s\n", digit, c->name);
+		}
+		ast_rtp_senddigit_end(pvt->rtp, digit);
+		ast_mutex_unlock(&pvt->lock);
+	} else {
+		/* in-band DTMF */
+		if (h323debug) {
+			ast_log(LOG_DTMF, "End sending inband digit %c on %s\n", digit, c->name);
+		}
+		pvt->txDtmfDigit = ' ';
+		token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
+		ast_mutex_unlock(&pvt->lock);
+		h323_send_tone(token, ' ');
+		if (token) {
+			free(token);
+		}
+	}
+	oh323_update_info(c);
+	return 0;
+}
+
+/**
+ * Make a call over the specified channel to the specified
  * destination.
  * Returns -1 on error, 0 on success.
  */
 static int oh323_call(struct ast_channel *c, char *dest, int timeout)
-{  
+{
 	int res = 0;
 	struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
-	char addr[INET_ADDRSTRLEN];
+	const char *addr;
 	char called_addr[1024];
 
 	if (h323debug) {
@@ -446,15 +597,15 @@
 		return -1;
 	}
 	ast_mutex_lock(&pvt->lock);
-	if (usingGk) {
+	if (!gatekeeper_disable) {
 		if (ast_strlen_zero(pvt->exten)) {
 			strncpy(called_addr, dest, sizeof(called_addr));
 		} else {
 			snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest);
 		}
 	} else {
-		ast_inet_ntoa(addr, sizeof(addr), pvt->sa.sin_addr);
 		res = htons(pvt->sa.sin_port);
+		addr = ast_inet_ntoa(pvt->sa.sin_addr);
 		if (ast_strlen_zero(pvt->exten)) {
 			snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res);
 		} else {
@@ -462,19 +613,37 @@
 		}
 	}
 	/* make sure null terminated */
-	called_addr[sizeof(called_addr) - 1] = '\0'; 
-
-	if (c->cid.cid_num) {
+	called_addr[sizeof(called_addr) - 1] = '\0';
+
+	if (c->cid.cid_num)
 		strncpy(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num));
-	}
-	if (c->cid.cid_name) {
+
+	if (c->cid.cid_name)
 		strncpy(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name));
-	}
+
+	if (c->cid.cid_rdnis) {
+		strncpy(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis));
+	}
+
+	if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) {
+		if (!strcasecmp(addr, "UNKNOWN"))
+			pvt->options.redirect_reason = 0;
+		else if (!strcasecmp(addr, "BUSY"))
+			pvt->options.redirect_reason = 1;
+		else if (!strcasecmp(addr, "NO_REPLY"))
+			pvt->options.redirect_reason = 2;
+		else if (!strcasecmp(addr, "UNCONDITIONAL"))
+			pvt->options.redirect_reason = 15;
+		else
+			pvt->options.redirect_reason = -1;
+	} else
+		pvt->options.redirect_reason = -1;
 
 	/* indicate that this is an outgoing call */
 	pvt->outgoing = 1;
 
-	ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec);
+	if (h323debug)
+		ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec);
 	ast_mutex_unlock(&pvt->lock);
 	res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
 	if (res) {
@@ -511,16 +680,15 @@
 static int oh323_hangup(struct ast_channel *c)
 {
 	struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
-	int needcancel = 0;
 	int q931cause = AST_CAUSE_NORMAL_CLEARING;
 	char *call_token;
 
 
 	if (h323debug)
-		ast_log(LOG_DEBUG, "Hanging up call %s\n", c->name);
+		ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name);
 
 	if (!c->tech_pvt) {
-		ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
+		ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
 		return 0;
 	}
 	ast_mutex_lock(&pvt->lock);
@@ -530,10 +698,7 @@
 		ast_mutex_unlock(&pvt->lock);
 		return 0;
 	}
-	if (!c || (c->_state != AST_STATE_UP)) {
-		needcancel = 1;
-	}
-	
+
 	pvt->owner = NULL;
 	c->tech_pvt = NULL;
 
@@ -562,25 +727,25 @@
 		if (call_token) {
 			/* Release lock to eliminate deadlock */
 			ast_mutex_unlock(&pvt->lock);
-			if (h323_clear_call(call_token, q931cause)) { 
-				ast_log(LOG_DEBUG, "ClearCall failed.\n");
+			if (h323_clear_call(call_token, q931cause)) {
+				ast_log(LOG_WARNING, "ClearCall failed.\n");
 			}
 			free(call_token);
 			ast_mutex_lock(&pvt->lock);
 		}
-	} 
+	}
 	pvt->needdestroy = 1;
+	ast_mutex_unlock(&pvt->lock);
 
 	/* Update usage counter */
-	ast_mutex_unlock(&pvt->lock);
-	ast_atomic_fetchadd_int(&__mod_desc->usecnt, -1);
-	ast_update_use_count();
+	ast_module_unref(ast_module_info->self);
+
 	return 0;
 }
 
 static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
 {
-	/* Retrieve audio/etc from channel.  Assumes pvt->lock is already held. */
+	/* Retrieve audio/etc from channel. Assumes pvt->lock is already held. */
 	struct ast_frame *f;
 
 	/* Only apply it for the first packet, we just need the correct ip/port */
@@ -599,27 +764,34 @@
 		if (f->frametype == AST_FRAME_VOICE) {
 			if (f->subclass != pvt->owner->nativeformats) {
 				/* Try to avoid deadlock */
-				if (ast_mutex_trylock(&pvt->owner->lock)) {
+				if (ast_channel_trylock(pvt->owner)) {
 					ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
 					return &ast_null_frame;
 				}
-				ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
+				if (h323debug)
+					ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
 				pvt->owner->nativeformats = f->subclass;
 				pvt->nativeformats = f->subclass;
 				ast_set_read_format(pvt->owner, pvt->owner->readformat);
 				ast_set_write_format(pvt->owner, pvt->owner->writeformat);
-				ast_mutex_unlock(&pvt->owner->lock);
-			}	
+				ast_channel_unlock(pvt->owner);
+			}
 			/* Do in-band DTMF detection */
 			if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
-				if (!ast_mutex_trylock(&pvt->owner->lock)) {
-					f = ast_dsp_process(pvt->owner,pvt->vad,f);
-					ast_mutex_unlock(&pvt->owner->lock);
+				if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) {
+					if (!ast_channel_trylock(pvt->owner)) {
+						f = ast_dsp_process(pvt->owner, pvt->vad, f);
+						ast_channel_unlock(pvt->owner);
+					}
+					else
+						ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
+				} else if (pvt->nativeformats && !pvt->noInbandDtmf) {
+					ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass));
+					pvt->noInbandDtmf = 1;
 				}
-				else
-					ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
 				if (f &&(f->frametype == AST_FRAME_DTMF)) {
-					ast_log(LOG_DEBUG, "Received in-band digit %c.\n", f->subclass);
+					if (h323debug)
+						ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass);
 				}
 			}
 		}
@@ -633,7 +805,21 @@
 	struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
 	ast_mutex_lock(&pvt->lock);
 	__oh323_update_info(c, pvt);
-	fr = oh323_rtp_read(pvt);
+	switch(c->fdno) {
+	case 0:
+		fr = oh323_rtp_read(pvt);
+		break;
+	case 1:
+		if (pvt->rtp)
+			fr = ast_rtcp_read(pvt->rtp);
+		else
+			fr = &ast_null_frame;
+		break;
+	default:
+		ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name);
+		fr = &ast_null_frame;
+		break;
+	}
 	ast_mutex_unlock(&pvt->lock);
 	return fr;
 }
@@ -658,9 +844,8 @@
 	}
 	if (pvt) {
 		ast_mutex_lock(&pvt->lock);
-		if (pvt->rtp) {
-			res =  ast_rtp_write(pvt->rtp, frame);
-		}
+		if (pvt->rtp && !pvt->recvonly)
+			res = ast_rtp_write(pvt->rtp, frame);
 		__oh323_update_info(c, pvt);
 		ast_mutex_unlock(&pvt->lock);
 	}
@@ -684,10 +869,10 @@
 	case AST_CONTROL_RINGING:
 		if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) {
 			h323_send_alerting(token);
- 			break;
- 		}
- 		if (token)
- 			free(token);
+			break;
+		}
+		if (token)
+			free(token);
 		return -1;
 	case AST_CONTROL_PROGRESS:
 		if (c->_state != AST_STATE_UP) {
@@ -697,14 +882,13 @@
 		if (token)
 			free(token);
 		return -1;
-
 	case AST_CONTROL_BUSY:
 		if (c->_state != AST_STATE_UP) {
 			h323_answering_call(token, 1);
 			ast_mutex_lock(&pvt->lock);
 			pvt->alreadygone = 1;
 			ast_mutex_unlock(&pvt->lock);
-			ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);			
+			ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
 			break;
 		}
 		if (token)
@@ -767,48 +951,102 @@
 	return 0;
 }
 
+static int __oh323_rtp_create(struct oh323_pvt *pvt)
+{
+	struct in_addr our_addr;
+
+	if (pvt->rtp)
+		return 0;
+
+	if (ast_find_ourip(&our_addr, bindaddr)) {
+		ast_mutex_unlock(&pvt->lock);
+		ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
+		return -1;
+	}
+	pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr);
+	if (!pvt->rtp) {
+		ast_mutex_unlock(&pvt->lock);
+		ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
+		return -1;
+	}
+	if (h323debug)
+		ast_log(LOG_DEBUG, "Created RTP channel\n");
+
+	ast_rtp_settos(pvt->rtp, tos);
+
+	if (h323debug)
+		ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
+	ast_rtp_setnat(pvt->rtp, pvt->options.nat);
+
+	if (pvt->dtmf_pt > 0)
+		ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0);
+
+	if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
+		ast_jb_configure(pvt->owner, &global_jbconf);
+		pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp);
+		pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp);
+		ast_queue_frame(pvt->owner, &ast_null_frame);	/* Tell Asterisk to apply changes */
+		ast_channel_unlock(pvt->owner);
+	} else
+		pvt->update_rtp_info = 1;
+
+	return 0;
+}
+
 /* Private structure should be locked on a call */
 static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host)
 {
 	struct ast_channel *ch;
 	int fmt;
-	
+
 	/* Don't hold a oh323_pvt lock while we allocate a chanel */
 	ast_mutex_unlock(&pvt->lock);
 	ch = ast_channel_alloc(1);
 	/* Update usage counter */
-	ast_atomic_fetchadd_int(&__mod_desc->usecnt, +1);
-	ast_update_use_count();
+	ast_module_ref(ast_module_info->self);
 	ast_mutex_lock(&pvt->lock);
 	if (ch) {
 		ch->tech = &oh323_tech;
 		ast_string_field_build(ch, name, "H323/%s", host);
-		ch->nativeformats = pvt->options.capability;
-		if (!ch->nativeformats) {
-			ch->nativeformats = global_options.capability;
-		}
+		if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
+			fmt = global_options.capability;
+		ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;
 		pvt->nativeformats = ch->nativeformats;
 		fmt = ast_best_codec(ch->nativeformats);
-		ch->fds[0] = ast_rtp_fd(pvt->rtp);
-		if (state == AST_STATE_RING) {
-			ch->rings = 1;
-		}
 		ch->writeformat = fmt;
 		ch->rawwriteformat = fmt;
 		ch->readformat = fmt;
 		ch->rawreadformat = fmt;
+#if 0
+		ch->fds[0] = ast_rtp_fd(pvt->rtp);
+		ch->fds[1] = ast_rtcp_fd(pvt->rtp);
+#endif
+#ifdef VIDEO_SUPPORT

[... 5885 lines stripped ...]


More information about the svn-commits mailing list