[svn-commits] may: trunk r227898 - in /trunk/addons: ./ ooh323c/src/ ooh323c/src/h323/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Nov 4 16:10:59 CST 2009


Author: may
Date: Wed Nov  4 16:10:44 2009
New Revision: 227898

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=227898
Log:
Reworked chan_ooh323 channel module.

Many architectural and functional changes.
Main changes are threading model chanes (many thread in ooh323 stack
instead of one), modifications and improvements in signalling part,
additional codecs support (726, speex), t38 mode support.
This module tested and used in production environment.

(closes issue #15285)
Reported by: may213
Tested by: sles, c0w, OrNix

Review: https://reviewboard.asterisk.org/r/324/


Modified:
    trunk/addons/Makefile
    trunk/addons/chan_ooh323.c
    trunk/addons/chan_ooh323.h
    trunk/addons/ooh323c/src/context.c
    trunk/addons/ooh323c/src/decode.c
    trunk/addons/ooh323c/src/dlist.c
    trunk/addons/ooh323c/src/encode.c
    trunk/addons/ooh323c/src/errmgmt.c
    trunk/addons/ooh323c/src/eventHandler.c
    trunk/addons/ooh323c/src/eventHandler.h
    trunk/addons/ooh323c/src/h323/H235-SECURITY-MESSAGESDec.c
    trunk/addons/ooh323c/src/h323/H323-MESSAGESDec.c
    trunk/addons/ooh323c/src/h323/MULTIMEDIA-SYSTEM-CONTROLDec.c
    trunk/addons/ooh323c/src/memheap.c
    trunk/addons/ooh323c/src/memheap.h
    trunk/addons/ooh323c/src/ooCalls.c
    trunk/addons/ooh323c/src/ooCalls.h
    trunk/addons/ooh323c/src/ooCapability.c
    trunk/addons/ooh323c/src/ooCapability.h
    trunk/addons/ooh323c/src/ooCmdChannel.c
    trunk/addons/ooh323c/src/ooCmdChannel.h
    trunk/addons/ooh323c/src/ooCommon.h
    trunk/addons/ooh323c/src/ooDateTime.c
    trunk/addons/ooh323c/src/ooDateTime.h
    trunk/addons/ooh323c/src/ooGkClient.c
    trunk/addons/ooh323c/src/ooGkClient.h
    trunk/addons/ooh323c/src/ooLogChan.c
    trunk/addons/ooh323c/src/ooLogChan.h
    trunk/addons/ooh323c/src/ooSocket.c
    trunk/addons/ooh323c/src/ooSocket.h
    trunk/addons/ooh323c/src/ooStackCmds.c
    trunk/addons/ooh323c/src/ooStackCmds.h
    trunk/addons/ooh323c/src/ooTimer.c
    trunk/addons/ooh323c/src/ooUtils.c
    trunk/addons/ooh323c/src/ooasn1.h
    trunk/addons/ooh323c/src/oochannels.c
    trunk/addons/ooh323c/src/oochannels.h
    trunk/addons/ooh323c/src/ooh245.c
    trunk/addons/ooh323c/src/ooh245.h
    trunk/addons/ooh323c/src/ooh323.c
    trunk/addons/ooh323c/src/ooh323.h
    trunk/addons/ooh323c/src/ooh323ep.c
    trunk/addons/ooh323c/src/ooh323ep.h
    trunk/addons/ooh323c/src/ooports.c
    trunk/addons/ooh323c/src/ooq931.c
    trunk/addons/ooh323c/src/ooq931.h
    trunk/addons/ooh323c/src/ootrace.c
    trunk/addons/ooh323c/src/ootrace.h
    trunk/addons/ooh323c/src/ootypes.h
    trunk/addons/ooh323c/src/perutil.c
    trunk/addons/ooh323c/src/printHandler.c
    trunk/addons/ooh323c/src/printHandler.h
    trunk/addons/ooh323c/src/rtctype.c
    trunk/addons/ooh323cDriver.c
    trunk/addons/ooh323cDriver.h

Modified: trunk/addons/Makefile
URL: http://svnview.digium.com/svn/asterisk/trunk/addons/Makefile?view=diff&rev=227898&r1=227897&r2=227898
==============================================================================
--- trunk/addons/Makefile (original)
+++ trunk/addons/Makefile Wed Nov  4 16:10:44 2009
@@ -47,4 +47,5 @@
 chan_ooh323.o: _ASTCFLAGS+=$(H323CFLAGS)
 
 $(if $(filter chan_ooh323,$(EMBEDDED_MODS)),modules.link,chan_ooh323.so): _ASTCFLAGS+=$(H323CFLAGS)
+$(if $(filter chan_ooh323,$(EMBEDDED_MODS)),modules.link,chan_ooh323.so): _ASTLDFLAGS+=-lrt
 $(if $(filter chan_ooh323,$(EMBEDDED_MODS)),modules.link,chan_ooh323.so): $(addprefix ooh323c/src/,$(H323OBJS)) chan_ooh323.o ooh323cDriver.o

Modified: trunk/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/trunk/addons/chan_ooh323.c?view=diff&rev=227898&r1=227897&r2=227898
==============================================================================
--- trunk/addons/chan_ooh323.c (original)
+++ trunk/addons/chan_ooh323.c Wed Nov  4 16:10:44 2009
@@ -16,10 +16,9 @@
 
 
 #include "chan_ooh323.h"
-
-/*** MODULEINFO
-	<defaultenabled>no</defaultenabled>
- ***/
+#include <math.h>
+
+#define FORMAT_STRING_SIZE	512
 
 /* Defaults */
 #define DEFAULT_CONTEXT "default"
@@ -36,17 +35,33 @@
 #define H323_ALREADYGONE        (1<<5)
 #define H323_NEEDDESTROY        (1<<6)
 #define H323_DISABLEGK          (1<<7)
+#define H323_NEEDSTART		(1<<8)
+
+#define MAXT30	240
+#define T38TOAUDIOTIMEOUT 30
+#define T38_DISABLED 0
+#define T38_ENABLED 1
+#define T38_FAXGW 1
 
 /* Channel description */
 static const char type[] = "OOH323";
 static const char tdesc[] = "Objective Systems H323 Channel Driver";
-static const char config[] = "chan_ooh323.conf";
-static const char config_old[] = "ooh323.conf";
-
+static const char config[] = "ooh323.conf";
+
+struct ast_module *myself;
+
+static struct ast_jb_conf default_jbconf =
+{
+	.flags = 0,
+	.max_size = -1,
+	.resync_threshold = -1,
+	.impl = ""
+};
+static struct ast_jb_conf global_jbconf;
 
 /* Channel Definition */
 static struct ast_channel *ooh323_request(const char *type, int format, 
-                                        void *data, int *cause);
+			const struct ast_channel *requestor,  void *data, int *cause);
 static int ooh323_digit_begin(struct ast_channel *ast, char digit);
 static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int ooh323_call(struct ast_channel *ast, char *dest, int timeout);
@@ -55,18 +70,21 @@
 static struct ast_frame *ooh323_read(struct ast_channel *ast);
 static int ooh323_write(struct ast_channel *ast, struct ast_frame *f);
 static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
+static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 
-static enum ast_rtp_get_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp);
-static enum ast_rtp_get_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp **rtp);
-static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, 
-                             struct ast_rtp *vrtp, struct ast_rtp *trtp, int codecs, int nat_active);
+static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
+static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
+static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, 
+          struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, int codecs, int nat_active);
+
+static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan);
+static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
 
 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
 
-#if 0
-static void ast_ooh323c_exit();
-#endif
+struct ooh323_peer *find_friend(const char *name, int port);
+
 
 static const struct ast_channel_tech ooh323_tech = {
 	.type = type,
@@ -84,22 +102,50 @@
 	.indicate = ooh323_indicate,
 	.fixup = ooh323_fixup,
 	.send_html = 0,
-	.bridge = ast_rtp_bridge,
+	.queryoption = ooh323_queryoption,
+	.bridge = ast_rtp_instance_bridge,		/* XXX chan unlocked ? */
+	.early_bridge = ast_rtp_instance_early_bridge,
+
 };
 
-static struct ast_rtp_protocol ooh323_rtp = {
+static struct ast_rtp_glue ooh323_rtp = {
 	.type = type,
 	.get_rtp_info = ooh323_get_rtp_peer,
 	.get_vrtp_info = ooh323_get_vrtp_peer,
-	.set_rtp_peer = ooh323_set_rtp_peer
+	.update_peer = ooh323_set_rtp_peer,
 };
+
+static struct ast_udptl_protocol ooh323_udptl = {
+	type: "H323",
+	get_udptl_info: ooh323_get_udptl_peer,
+	set_udptl_peer: ooh323_set_udptl_peer,
+};
+
+
+
+struct ooh323_user;
 
 /* H.323 channel private structure */
 static struct ooh323_pvt {
 	ast_mutex_t lock;		/* Channel private lock */
-	struct ast_rtp *rtp;
-	struct ast_rtp *vrtp; /* Placeholder for now */
+	struct ast_rtp_instance *rtp;
+	struct ast_rtp_instance *vrtp; /* Placeholder for now */
+
+	int t38support;			/* T.38 mode - disable, transparent, faxgw */
+	int rtptimeout;
+	struct ast_udptl *udptl;
+	int faxmode;
+	int t38_tx_enable;
+	int t38_init;
+	struct sockaddr_in udptlredirip;
+	time_t lastTxT38;
+	int chmodepend;
+
 	struct ast_channel *owner;	/* Master Channel */
+   	union {
+    		char  *user;	/* cooperating user/peer */
+    		char  *peer;
+   	} neighbor;
 	time_t lastrtptx;
 	time_t lastrtprx;
 	unsigned int flags;
@@ -124,12 +170,16 @@
 	int capability;
 	struct ast_codec_pref prefs;
 	int dtmfmode;
+	int dtmfcodec;
 	char exten[AST_MAX_EXTENSION];	/* Requested extension */
 	char context[AST_MAX_EXTENSION];	/* Context where to start */
 	char accountcode[256];	/* Account code */
 	int nat;
 	int amaflags;
+	int progsent;			/* progress is sent */
 	struct ast_dsp *vad;
+	struct OOH323Regex *rtpmask;	/* rtp ip regexp */
+	char rtpmaskstr[120];
 	struct ooh323_pvt *next;	/* Next entity */
 } *iflist = NULL;
 
@@ -148,9 +198,13 @@
 	int         capability;
 	struct ast_codec_pref prefs;
 	int         dtmfmode;
+	int	    dtmfcodec;
+	int	    t38support;
 	int         rtptimeout;
 	int         mUseIP;        /* Use IP address or H323-ID to search user */
 	char        mIP[20];
+	struct OOH323Regex	    *rtpmask;
+	char	    rtpmaskstr[120];
 	struct ooh323_user *next;
 };
 
@@ -165,6 +219,8 @@
 	char        accountcode[20];
 	int         amaflags;
 	int         dtmfmode;
+	int	    dtmfcodec;
+	int	    t38support;
 	int         mFriend;    /* indicates defined as friend */
 	char        ip[20];
 	int         port;
@@ -173,6 +229,8 @@
 	char        *url;       /* url alias, which asterisk will register with gk to reach this peer*/
 	char        *e164;      /* e164 alias, which asterisk will register with gk to reach this peer*/
 	int         rtptimeout;
+	struct OOH323Regex	    *rtpmask;
+	char	    rtpmaskstr[120];
 	struct ooh323_peer *next;
 };
 
@@ -198,35 +256,51 @@
 
 AST_MUTEX_DEFINE_STATIC(ooh323c_cmd_lock);
 
+static long callnumber = 0;
+AST_MUTEX_DEFINE_STATIC(ooh323c_cn_lock);
+
 /* stack callbacks */
 int onAlerting(ooCallData *call);
+int onProgress(ooCallData *call);
 int onNewCallCreated(ooCallData *call);
+int onOutgoingCall(ooCallData *call);
 int onCallEstablished(ooCallData *call);
 int onCallCleared(ooCallData *call);
+void onModeChanged(ooCallData *call, int t38mode);
 
 static char gLogFile[256] = DEFAULT_LOGFILE;
 static int  gPort = 1720;
 static char gIP[20];
-static char gCallerID[AST_MAX_EXTENSION] = DEFAULT_H323ID;
+static char gCallerID[AST_MAX_EXTENSION] = "";
 static struct ooAliases *gAliasList;
 static int  gCapability = AST_FORMAT_ULAW;
 static struct ast_codec_pref gPrefs;
 static int  gDTMFMode = H323_DTMF_RFC2833;
+static int  gDTMFCodec = 101;
+static int  gT38Support = T38_FAXGW;
 static char gGatekeeper[100];
 static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
 
 static int  gIsGateway = 0;
 static int  gFastStart = 1;
 static int  gTunneling = 1;
+static int  gBeMaster = 0;
 static int  gMediaWaitForConnect = 0;
 static int  gTOS = 0;
 static int  gRTPTimeout = 60;
 static char gAccountcode[80] = DEFAULT_H323ACCNT;
 static int  gAMAFLAGS;
 static char gContext[AST_MAX_EXTENSION] = DEFAULT_CONTEXT;
-static int  gIncomingLimit = 4;
-static int  gOutgoingLimit = 4;
+static int  gIncomingLimit = 1024;
+static int  gOutgoingLimit = 1024;
 OOBOOL gH323Debug = FALSE;
+static int gTRCLVL = OOTRCLVLERR;
+
+static int t35countrycode = 0;
+static int t35extensions = 0;
+static int manufacturer = 0;
+static char vendor[AST_MAX_EXTENSION] =  "";
+static char version[AST_MAX_EXTENSION] = "";
 
 static struct ooh323_config
 {
@@ -249,45 +323,63 @@
 
 
 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
-                                             const char *host) 
+                                             const char *host, int capability, const char *linkedid) 
 {
 	struct ast_channel *ch = NULL;
-	int fmt;
-	if (gH323Debug)
-		ast_verbose("---   ooh323_new - %s\n", host);
+	int fmt = 0;
+	if (gH323Debug)
+		ast_verbose("---   ooh323_new - %s, %d\n", host, capability);
 
 
 	/* Don't hold a h323 pvt lock while we allocate a channel */
 	ast_mutex_unlock(&i->lock);
-	ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name, i->accountcode, i->exten, i->context, i->amaflags, "OOH323/%s-%08x", host, (unsigned int)(unsigned long) i);
+   	ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name, 
+				i->accountcode, i->exten, i->context, linkedid, i->amaflags,
+				"OOH323/%s-%ld", host, callnumber);
+   	ast_mutex_lock(&ooh323c_cn_lock);
+   	callnumber++;
+   	ast_mutex_unlock(&ooh323c_cn_lock);
+   
 	ast_mutex_lock(&i->lock);
 
 	if (ch) {
 		ast_channel_lock(ch);
 		ch->tech = &ooh323_tech;
 
-		ch->nativeformats = i->capability;
-
-		fmt = ast_best_codec(ch->nativeformats);
-
-		ch->fds[0] = ast_rtp_fd(i->rtp);
-		ch->fds[1] = ast_rtcp_fd(i->rtp);
+		if (capability)
+			fmt = ast_best_codec(capability);
+		if (!fmt) 
+			fmt = ast_codec_pref_index(&i->prefs, 0);
+
+		ch->nativeformats = ch->rawwriteformat = ch->rawreadformat = fmt;
+
+		ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(i->rtp, 0));
+		ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(i->rtp, 1));
+		ast_channel_set_fd(ch, 5, ast_udptl_fd(i->udptl));
+
+		ast_jb_configure(ch, &global_jbconf);
 
 		if (state == AST_STATE_RING)
 			ch->rings = 1;
 
 		ch->adsicpe = AST_ADSI_UNAVAILABLE;
-		ch->writeformat = fmt;
-		ch->rawwriteformat = fmt;
-		ch->readformat = fmt;
-		ch->rawreadformat = fmt;
+		ast_set_write_format(ch, fmt);
+		ast_set_read_format(ch, fmt);
 		ch->tech_pvt = i;
 		i->owner = ch;
+		ast_module_ref(myself);
 
 		/* Allocate dsp for in-band DTMF support */
 		if (i->dtmfmode & H323_DTMF_INBAND) {
 			i->vad = ast_dsp_new();
 			ast_dsp_set_features(i->vad, DSP_FEATURE_DIGIT_DETECT);
+       			ast_dsp_set_features(i->vad,
+						DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT);
+        		ast_dsp_set_faxmode(i->vad,
+						DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED);
+
+			if (i->dtmfmode & H323_DTMF_INBANDRELAX)
+				ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
 		}
 
 		ast_mutex_lock(&usecnt_lock);
@@ -301,15 +393,8 @@
 		ast_copy_string(ch->exten, i->exten, sizeof(ch->exten));
 
 		ch->priority = 1;
-		if (i->callerid_name) {
-			ch->cid.cid_name = strdup(i->callerid_name);
-		}
-		if (i->callerid_num) {
-
-			ch->cid.cid_num = strdup(i->callerid_num);
-		}
-
-		if (!ast_test_flag(i, H323_OUTGOING)) {
+
+      		if(!ast_test_flag(i, H323_OUTGOING)) {
 		
 			if (!ast_strlen_zero(i->caller_h323id)) {
 				pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id);
@@ -336,19 +421,21 @@
 
 		ast_setstate(ch, state);
 		if (state != AST_STATE_DOWN) {
-			if (ast_pbx_start(ch)) {
+         		if (ast_pbx_start(ch)) {
 				ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
-				ast_channel_unlock(ch);
+            			ast_channel_unlock(ch);
 				ast_hangup(ch);
 				ch = NULL;
-			}
-		}
+			} 
+	 	}
+
+		manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", "Channel: %s\r\nChanneltype: %s\r\n"
+				"CallRef: %d\r\n", ch->name, "OOH323", i->call_reference);
 	} else
 		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
 
 
-	if (ch)
-		ast_channel_unlock(ch);
+   	if(ch)   ast_channel_unlock(ch);
 
 	if (gH323Debug)
 		ast_verbose("+++   h323_new\n");
@@ -361,6 +448,7 @@
 static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken) 
 {
 	struct ooh323_pvt *pvt = NULL;
+	struct sockaddr_in ouraddr;
 	struct in_addr ipAddr;
 	if (gH323Debug)
 		ast_verbose("---   ooh323_alloc\n");
@@ -372,25 +460,41 @@
 
 	ast_mutex_init(&pvt->lock);
 	ast_mutex_lock(&pvt->lock);
+
 
 	if (!inet_aton(gIP, &ipAddr)) {
 		ast_log(LOG_ERROR, "Invalid OOH323 driver ip address\n");
 		ast_mutex_unlock(&pvt->lock);
 		ast_mutex_destroy(&pvt->lock);
-		free(pvt);
+		ast_free(pvt);
 		return NULL;
 	}
 
-	if (!(pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, ipAddr))) {
+	ouraddr.sin_addr = ipAddr;
+	if (!(pvt->rtp = ast_rtp_instance_new("asterisk", sched, &ouraddr, NULL))) {
 		ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", 
 				  strerror(errno));
 		ast_mutex_unlock(&pvt->lock);
 		ast_mutex_destroy(&pvt->lock);
-		free(pvt);
+		ast_free(pvt);
 		return NULL;
 	}
  
-	ast_rtp_setqos(pvt->rtp, gTOS, 0, "ooh323");
+	ast_rtp_instance_set_qos(pvt->rtp, gTOS, 0, "ooh323-rtp");
+
+	if (!(pvt->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, ipAddr))) {
+		ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n",
+				strerror(errno));
+		ast_mutex_unlock(&pvt->lock);
+		ast_mutex_destroy(&pvt->lock);
+		ast_free(pvt);
+		return NULL;
+	}
+
+	ast_udptl_set_error_correction_scheme(pvt->udptl, UDPTL_ERROR_CORRECTION_NONE);
+	pvt->faxmode = 0;
+	pvt->t38support = gT38Support;
+	pvt->rtptimeout = gRTPTimeout;
 
 	pvt->call_reference = callref;
 	if (callToken)
@@ -401,8 +505,10 @@
 		OO_SETFLAG(pvt->flags, H323_DISABLEGK);
 
 	pvt->dtmfmode = gDTMFMode;
+	pvt->dtmfcodec = gDTMFCodec;
 	ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
 	ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
+
 	pvt->amaflags = gAMAFLAGS;
 	pvt->capability = gCapability;
 	memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs));
@@ -424,8 +530,9 @@
 /*
 	Possible data values - peername, exten/peername, exten at ip
  */
-static struct ast_channel *ooh323_request(const char *type, int format, const struct ast_channel *requestor,
-													 void *data, int *cause)
+static struct ast_channel *ooh323_request(const char *type, int format,
+		const struct ast_channel *requestor, void *data, int *cause)
+
 {
 	struct ast_channel *chan = NULL;
 	struct ooh323_pvt *p = NULL;
@@ -433,13 +540,13 @@
 	char *dest = NULL; 
 	char *ext = NULL;
 	char tmp[256];
-	char formats[512];
+	char formats[FORMAT_STRING_SIZE];
 	int oldformat;
 	int port = 0;
 
 	if (gH323Debug)
 		ast_verbose("---   ooh323_request - data %s format %s\n", (char*)data,  
-										ast_getformatname_multiple(formats,512,format));
+										ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,format));
 
 	oldformat = format;
 	format &= AST_FORMAT_AUDIO_MASK;
@@ -460,14 +567,16 @@
 	/* This is an outgoing call, since ooh323_request is called */
 	ast_set_flag(p, H323_OUTGOING);
 
-	ast_copy_string(tmp, data, sizeof(data));
+
+   	ast_copy_string(tmp, data, sizeof(tmp));
 
 	dest = strchr(tmp, '/');
 
 	if (dest) {  
 		*dest = '\0';
 		dest++;
-		ext = tmp;
+		ext = dest;
+		dest = tmp;
 	} else if ((dest = strchr(tmp, '@'))) {
 		*dest = '\0';
 		dest++;
@@ -497,22 +606,28 @@
 		p->host = strdup(peer->ip);
 		p->port = peer->port;
 		/* Disable gk as we are going to call a known peer*/
-		OO_SETFLAG(p->flags, H323_DISABLEGK);
+		/* OO_SETFLAG(p->flags, H323_DISABLEGK); */
 
 		if (ext)
 			ast_copy_string(p->exten, ext, sizeof(p->exten));
 
-		if (peer->capability & format) {
-			p->capability = peer->capability & format;
-		} else {
-		  p->capability = peer->capability;
-		}
+		p->capability = peer->capability;
 		memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));
-		p->dtmfmode = peer->dtmfmode;
+		p->dtmfmode |= peer->dtmfmode;
+		p->dtmfcodec  = peer->dtmfcodec;
+		p->t38support = peer->t38support;
+		p->rtptimeout = peer->rtptimeout;
+		if (peer->rtpmask && peer->rtpmaskstr[0]) {
+			p->rtpmask = peer->rtpmask;
+			ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
+		}
 		ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
 		p->amaflags = peer->amaflags;
 	} else {
 		p->dtmfmode = gDTMFMode;
+		p->dtmfcodec = gDTMFCodec;
+		p->t38support = gT38Support;
+		p->rtptimeout = gRTPTimeout;
 		p->capability = gCapability;
 
 		memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref));
@@ -528,7 +643,8 @@
 	}
 
 
-	chan = ooh323_new(p, AST_STATE_DOWN, p->username);
+	chan = ooh323_new(p, AST_STATE_DOWN, p->username, format,
+				 requestor ? requestor->linkedid : NULL);
 	
 	ast_mutex_unlock(&p->lock);
 
@@ -536,6 +652,23 @@
 		ast_mutex_lock(&iflock);
 		ooh323_destroy(p);
 		ast_mutex_unlock(&iflock);
+   } else {
+      ast_mutex_lock(&p->lock);
+      p->callToken = (char*)ast_malloc(AST_MAX_EXTENSION);
+      if(!p->callToken)
+      {
+       ast_mutex_unlock(&p->lock);
+       ast_mutex_lock(&iflock);
+       ooh323_destroy(p);
+       ast_mutex_unlock(&iflock);
+       ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
+       return NULL;
+      }
+
+      ast_mutex_unlock(&p->lock);
+      ast_mutex_lock(&ooh323c_cmd_lock);
+      ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
+      ast_mutex_unlock(&ooh323c_cmd_lock);
 	}
 
 	restart_monitor();
@@ -574,9 +707,10 @@
 	struct ooh323_user *user;
 
 	if (gH323Debug)
-		ast_verbose("---   find_user\n");
+      ast_verbose("---   find_user: %s, %s\n",name,ip);
 
 	ast_mutex_lock(&userl.lock);
+
 	for (user = userl.users; user; user = user->next) {
 		if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
 			break;
@@ -585,6 +719,7 @@
 			break;
 		}
 	}
+
 	ast_mutex_unlock(&userl.lock);
 
 	if (gH323Debug)
@@ -631,6 +766,7 @@
 
 	if (gH323Debug)
 		ast_verbose("---   find_peer \"%s\"\n", name);
+
 
 	ast_mutex_lock(&peerl.lock);
 	for (peer = peerl.peers; peer; peer = peer->next) {
@@ -675,16 +811,25 @@
 		return -1;
 	}
 	ast_mutex_lock(&p->lock);
-	if (p->rtp && (p->dtmfmode & H323_DTMF_RFC2833)) {
-		ast_rtp_senddigit_begin(p->rtp, digit);
+
+
+	if (digit == 'e' && !p->faxmode && p->t38support != T38_DISABLED)  {
+		if (!p->chmodepend) {
+			if (gH323Debug)
+				ast_verbose("request to change %s to t.38 because fax cng\n",
+						p->callToken);
+			p->chmodepend = 1;
+			ooRequestChangeMode(p->callToken, 1);
+		}
+
+	} else if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
+		ast_rtp_instance_dtmf_begin(p->rtp, digit);
 	} else if (((p->dtmfmode & H323_DTMF_Q931) ||
 						 (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||
 						 (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
 		dtmf[0] = digit;
 		dtmf[1] = '\0';
-		ast_mutex_lock(&ooh323c_cmd_lock);
 		ooSendDTMFDigit(p->callToken, dtmf);
-		ast_mutex_unlock(&ooh323c_cmd_lock);
 	}
 	ast_mutex_unlock(&p->lock);
 	if (gH323Debug)
@@ -705,8 +850,8 @@
 		return -1;
 	}
 	ast_mutex_lock(&p->lock);
-	if (p->rtp && (p->dtmfmode & H323_DTMF_RFC2833)) 
-		ast_rtp_senddigit_end(p->rtp, digit);
+	if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) 
+		ast_rtp_instance_dtmf_end(p->rtp, digit);
 
 	ast_mutex_unlock(&p->lock);
 	if (gH323Debug)
@@ -720,43 +865,42 @@
 {
 	struct ooh323_pvt *p = ast->tech_pvt;
 	char destination[256];
-	int res = 0;
+   	int res=0, i;
 	const char *val = NULL;
 	ooCallOptions opts = {
 		.fastStart = TRUE,
 		.tunneling = TRUE,
 		.disableGk = TRUE,
-		.callMode = OO_CALLMODE_AUDIOCALL
+      		.callMode = OO_CALLMODE_AUDIOCALL,
+      		.transfercap = 0
 	};
+
 	if (gH323Debug)
 		ast_verbose("---   ooh323_call- %s\n", dest);
 
-	if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
+
+   if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) 
+   {
 		ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
 									"reserved\n", ast->name);
 		return -1;
 	}
 	ast_mutex_lock(&p->lock);
 	ast_set_flag(p, H323_OUTGOING);
-	if (ast->cid.cid_num) {
-		if (p->callerid_num) {
-			free(p->callerid_num);
-		}
-		p->callerid_num = strdup(ast->cid.cid_num);
-	}
-
-	if (ast->cid.cid_name) {
-		if (p->callerid_name) {
+	if (ast->connected.id.number) {
+     		if(p->callerid_num)   free(p->callerid_num);
+		p->callerid_num = strdup(ast->connected.id.number);
+	}
+
+	if (ast->connected.id.name) {
+      		if(p->callerid_name)
 			free(p->callerid_name);
-		}
-		p->callerid_name = strdup(ast->cid.cid_name);
-	}
-	else{
-		ast->cid.cid_name = strdup(gCallerID);
-		if (p->callerid_name) {
+		p->callerid_name = strdup(ast->connected.id.name);
+	} else {
+		ast->connected.id.name = strdup(gCallerID);
+      		if(p->callerid_name)
 			free(p->callerid_name);
-		}
-		p->callerid_name = strdup(ast->cid.cid_name);
+		p->callerid_name = strdup(ast->connected.id.name);
 	}
 
 	/* Retrieve vars */
@@ -768,9 +912,8 @@
 	
 	if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
 		ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits));
-		if (!p->callerid_num) {
+      		if(!p->callerid_num)
 			p->callerid_num = strdup(val);
-		}
 	}
 
 	if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
@@ -780,13 +923,6 @@
 	if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
 		ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
 	}
-
-
-	if (!(p->callToken = (char*)malloc(AST_MAX_EXTENSION))) {
-		ast_mutex_unlock(&p->lock);
-		ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
-		return -1; /* TODO: need to clean/hangup?? */
-	}		
 
 	if (p->host && p->port != 0)
 		snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
@@ -795,17 +931,22 @@
 	else
 		ast_copy_string(destination, dest, sizeof(destination));
 
-	ast_mutex_lock(&ooh323c_cmd_lock);
-	if (OO_TESTFLAG(p->flags, H323_DISABLEGK))
-		res = ooMakeCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
-	else
-		res = ooMakeCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
-	ast_mutex_unlock(&ooh323c_cmd_lock);
+   destination[sizeof(destination)-1]='\0';
+
+   opts.transfercap = ast->transfercapability;
+
+   for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
+
+   if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
+      res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
+   } else {
+      res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
+   }
 
 	ast_mutex_unlock(&p->lock);
 	if (res != OO_OK) {
 		ast_log(LOG_ERROR, "Failed to make call\n");
-		return -1; /* TODO: cleanup */
+      		return -1; /* ToDO: cleanup */
 	}
 	if (gH323Debug)
 		ast_verbose("+++   ooh323_call\n");
@@ -816,6 +957,7 @@
 static int ooh323_hangup(struct ast_channel *ast)
 {
 	struct ooh323_pvt *p = ast->tech_pvt;
+   	int q931cause = AST_CAUSE_NORMAL_CLEARING;
 
 	if (gH323Debug)
 		ast_verbose("---   ooh323_hangup\n");
@@ -823,23 +965,42 @@
 	if (p) {
 		ast_mutex_lock(&p->lock);
 
+        if (ast->hangupcause) {
+                q931cause = ast->hangupcause;
+        } else {
+                const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
+                if (cause) {
+                        if (!strcmp(cause, "CONGESTION")) {
+                                q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
+                        } else if (!strcmp(cause, "BUSY")) {
+                                q931cause = AST_CAUSE_USER_BUSY;
+                        } else if (!strcmp(cause, "CHANISUNVAIL")) {
+                                q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
+                        } else if (!strcmp(cause, "NOANSWER")) {
+                                q931cause = AST_CAUSE_NO_ANSWER;
+                        } else if (!strcmp(cause, "CANCEL")) {
+                                q931cause = AST_CAUSE_CALL_REJECTED;
+                        }
+                }
+        }
+
+
+
 		if (gH323Debug)
-			ast_verbose("	 hanging %s\n", p->username);
+			ast_verbose("    hanging %s with cause: %d\n", p->username, q931cause);
 		ast->tech_pvt = NULL; 
 		if (!ast_test_flag(p, H323_ALREADYGONE)) {
-			ast_mutex_lock(&ooh323c_cmd_lock);
-			ooHangCall(p->callToken, 
-				 ooh323_convert_hangupcause_asteriskToH323(p->owner->hangupcause));
-			ast_mutex_unlock(&ooh323c_cmd_lock);
+         		ooHangCall(p->callToken, 
+				ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
 			ast_set_flag(p, H323_ALREADYGONE);
 			/* ast_mutex_unlock(&p->lock); */
-		} else {
+      		} else 
 			ast_set_flag(p, H323_NEEDDESTROY);
-		}
 		/* detach channel here */
 		if (p->owner) {
 			p->owner->tech_pvt = NULL;
 			p->owner = NULL;
+			ast_module_unref(myself);
 		}
 
 		ast_mutex_unlock(&p->lock);
@@ -851,8 +1012,7 @@
 		ast_update_use_count();
 	  
 	} else {
-		ast_log(LOG_ERROR, "No call to hangup\n" );
-		return -1;
+		ast_log(LOG_DEBUG, "No call to hangup\n" );
 	}
 	
 	if (gH323Debug)
@@ -868,17 +1028,19 @@
 	if (gH323Debug)
 		ast_verbose("--- ooh323_answer\n");
 
-	ast_mutex_lock(&p->lock);
-	if (ast->_state != AST_STATE_UP) {
-		ast_channel_lock(ast);
-		ast_setstate(ast, AST_STATE_UP);
-		ast_debug(1, "ooh323_answer(%s)\n", ast->name);
-		ast_channel_unlock(ast);
-		ast_mutex_lock(&ooh323c_cmd_lock);
-		ooAnswerCall(p->callToken);
-		ast_mutex_unlock(&ooh323c_cmd_lock);
-	}
-	ast_mutex_unlock(&p->lock);
+	if (p) {
+
+		ast_mutex_lock(&p->lock);
+		if (ast->_state != AST_STATE_UP) {
+			ast_channel_lock(ast);
+			ast_setstate(ast, AST_STATE_UP);
+      			if (option_debug)
+				ast_debug(1, "ooh323_answer(%s)\n", ast->name);
+			ast_channel_unlock(ast);
+			ooAnswerCall(p->callToken);
+		}
+		ast_mutex_unlock(&p->lock);
+	}
 
 	if (gH323Debug)
 		ast_verbose("+++ ooh323_answer\n");
@@ -891,6 +1053,8 @@
 	struct ast_frame *fr;
 	static struct ast_frame null_frame = { AST_FRAME_NULL, };
 	struct ooh323_pvt *p = ast->tech_pvt;
+
+	if (!p) return &null_frame;
 
 	ast_mutex_lock(&p->lock);
 	if (p->rtp)
@@ -907,26 +1071,59 @@
 	struct ooh323_pvt *p = ast->tech_pvt;
 	int res = 0;
 
-	if (f->frametype == AST_FRAME_VOICE) {
-		if (!(f->subclass & ast->nativeformats)) {
-			ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native "
-									  "formats is %d (read/write = %d/%d)\n",
-									f->subclass, ast->nativeformats, ast->readformat,
+	if (p) {
+		ast_mutex_lock(&p->lock);
+
+		if (f->frametype == AST_FRAME_MODEM) {
+			ast_debug(1, "Send UDPTL %d/%d len %d for %s\n",
+				f->frametype, f->subclass, f->datalen, ast->name);
+			if (p->udptl)
+				res = ast_udptl_write(p->udptl, f);
+			ast_mutex_unlock(&p->lock);
+			return res;
+		}
+
+	
+		if (f->frametype == AST_FRAME_VOICE) {
+/* sending progress for first */
+			if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
+			 		p->callToken) {
+				ooManualProgress(p->callToken);
+				p->progsent = 1;
+			}
+
+
+			if (!(f->subclass & ast->nativeformats)) {
+				if (ast->nativeformats != 0) {
+					ast_log(LOG_WARNING, "Asked to transmit frame type %d,"
+						" while native "
+						 "formats is %d (read/write = %d/%d)\n",
+						f->subclass, ast->nativeformats, ast->readformat,
 										ast->writeformat);
+					ast_set_write_format(ast, f->subclass);
+				} else {
+					/* ast_set_write_format(ast, f->subclass);
+					ast->nativeformats = f->subclass; */
+				}
+			ast_mutex_unlock(&p->lock);
 			return 0;
-		}
-		if (p) {
-			ast_mutex_lock(&p->lock);
-			if (p->rtp)
-				res = ast_rtp_write(p->rtp, f);
+			}
+
+		if (p->rtp)
+			res = ast_rtp_instance_write(p->rtp, f);
+
+		ast_mutex_unlock(&p->lock);
+
+		} else if (f->frametype == AST_FRAME_IMAGE) {
 			ast_mutex_unlock(&p->lock);
-		}
-	} else if (f->frametype == AST_FRAME_IMAGE) {
-		return 0;
-	} else {
-		ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", 
+			return 0;
+		} else {
+			ast_log(LOG_WARNING, "Can't send %d type frames with OOH323 write\n", 
 									 f->frametype);
-		return 0;
+			ast_mutex_unlock(&p->lock);
+			return 0;
+		}
+
 	}
 
 	return res;
@@ -937,6 +1134,8 @@
 
 	struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
 	char *callToken = (char *)NULL;
+
+	if (!p) return -1;
 
 	ast_mutex_lock(&p->lock);
 	callToken = (p->callToken ? strdup(p->callToken) : NULL);
@@ -951,21 +1150,18 @@
 	if (gH323Debug)
 		ast_verbose("----- ooh323_indicate %d on call %s\n", condition, callToken);
 	 
-
+   	ast_mutex_lock(&p->lock);
 	switch (condition) {
 	case AST_CONTROL_CONGESTION:
 		if (!ast_test_flag(p, H323_ALREADYGONE)) {
-			ast_mutex_lock(&ooh323c_cmd_lock);
-			ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED);
-			ast_mutex_unlock(&ooh323c_cmd_lock);
+            		ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, 
+						AST_CAUSE_SWITCH_CONGESTION);
 			ast_set_flag(p, H323_ALREADYGONE);
 		}
 		break;
 	case AST_CONTROL_BUSY:
 		if (!ast_test_flag(p, H323_ALREADYGONE)) {
-			ast_mutex_lock(&ooh323c_cmd_lock);
-			ooHangCall(callToken, OO_REASON_LOCAL_BUSY);
-			ast_mutex_unlock(&ooh323c_cmd_lock);
+            		ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
 			ast_set_flag(p, H323_ALREADYGONE);
 		}
 		break;
@@ -975,9 +1171,74 @@
 	case AST_CONTROL_UNHOLD:
 		ast_moh_stop(ast);
 		break;
-	case AST_CONTROL_PROCEEDING:
-	case AST_CONTROL_RINGING:
 	case AST_CONTROL_PROGRESS:
+		if (ast->_state != AST_STATE_UP) {
+	    		if (!p->progsent) {
+	     			if (gH323Debug) 
+					ast_log(LOG_DEBUG,"Sending manual progress for %s, res = %d\n", callToken,
+             				ooManualProgress(callToken));	
+				else
+	     				ooManualProgress(callToken);
+	     			p->progsent = 1;
+	    		}
+		}
+	    break;
+      case AST_CONTROL_RINGING:
+	    if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) {
+	    	if (gH323Debug) 
+			ast_log(LOG_DEBUG,"Sending manual ringback for %s, res = %d\n", 
+			callToken,
+            		ooManualRingback(callToken));
+		 else
+	    		ooManualRingback(callToken);
+	    }
+	 break;
+      case AST_CONTROL_SRCUPDATE:
+		ast_rtp_instance_new_source(p->rtp);
+		break;
+
+      case AST_CONTROL_T38_PARAMETERS:
+		if (p->t38support != T38_ENABLED) {
+			struct ast_control_t38_parameters parameters = { .request_response = 0 };
+			parameters.request_response = AST_T38_REFUSED;
+			ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS,
+						 &parameters, sizeof(parameters));
+			break;
+		}
+		if (datalen != sizeof(struct ast_control_t38_parameters)) {
+			ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
+					   "Expected %d, got %d\n",
+				(int)sizeof(enum ast_control_t38), (int)datalen);
+		} else {
+			const struct ast_control_t38_parameters *parameters = data;
+			enum ast_control_t38 message = parameters->request_response;
+			switch (message) {
+
+			case AST_T38_REQUEST_NEGOTIATE:
+
+				if (!p->chmodepend && !p->faxmode) {
+					ooRequestChangeMode(p->callToken, 1);
+					p->chmodepend = 1;
+				}
+				break;
+
+			case AST_T38_REQUEST_TERMINATE:
+
+				if (!p->chmodepend && p->faxmode) {
+					ooRequestChangeMode(p->callToken, 0);
+					p->chmodepend = 1;
+				}
+				break;
+
+
+			default:
+				;
+
+			}
+
+		}
+		break;
+      case AST_CONTROL_PROCEEDING:
 	case -1:
 		break;
 	default:
@@ -985,12 +1246,75 @@
 									condition, callToken);
 	}
 
+   	ast_mutex_unlock(&p->lock);
+
 	if (gH323Debug)
 		ast_verbose("++++  ooh323_indicate %d on %s\n", condition, callToken);
 
-
+   	free(callToken);
 	return -1;
 }
+
+static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
+{
+
+	struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;
+	int res = -1;
+	enum ast_t38_state state = T38_STATE_UNAVAILABLE;
+	char* cp;
+
+	if (!p) return -1;
+
+	ast_mutex_lock(&p->lock);
+
+	if (gH323Debug)
+		ast_verbose("----- ooh323_queryoption %d on channel %s\n", option, ast->name);
+	 
+	switch (option) {
+
+		case AST_OPTION_T38_STATE:
+
+			if (*datalen != sizeof(enum ast_t38_state)) {
+                        	ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
+				" Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
+				break;
+			}
+			if (p->t38support != T38_DISABLED)
+				state = T38_STATE_UNKNOWN;
+			if (p->faxmode)
+				state = (p->chmodepend) ? T38_STATE_UNKNOWN : T38_STATE_NEGOTIATED;
+			else if (p->chmodepend)
+				state = T38_STATE_NEGOTIATING;
+
+
+			*((enum ast_t38_state *) data) = state;
+			res = 0;
+			break;
+
+
+		case AST_OPTION_DIGIT_DETECT:
+
+			cp = (char *) data;
+			*cp = p->vad ? 1 : 0;
+			ast_debug(1, "Reporting digit detection %sabled on %s\n",
+							 *cp ? "en" : "dis", ast->name);
+
+			res = 0;
+			break;
+
+		default:	;
+
+	}
+
+	if (gH323Debug)
+		ast_verbose("+++++ ooh323_queryoption %d on channel %s\n", option, ast->name);
+	 
+   	ast_mutex_unlock(&p->lock);
+
+	return res;
+}
+
+
 
 static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
 {
@@ -1021,15 +1345,14 @@
 }
 
 
-void ooh323_set_write_format(ooCallData *call, int fmt)
-{
-#if 0
+void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
+{
 	struct ooh323_pvt *p = NULL;
-	char formats[512];
-#ifdef print_debug
-	printf("---   ooh323_update_writeformat %s\n", 
-										ast_getformatname_multiple(formats,512, fmt));
-#endif
+	char formats[FORMAT_STRING_SIZE];
+
+	if (gH323Debug)
+		ast_verbose("---   ooh323_update_writeformat %s/%d\n", 
+				ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt), txframes);
 	
 	p = find_call(call);
 	if (!p) {
@@ -1040,34 +1363,56 @@
 	ast_mutex_lock(&p->lock);
 
 	p->writeformat = fmt;
+
+	if (p->owner) {
+		while (p->owner && ast_channel_trylock(p->owner)) {
+			ast_debug(1,"Failed to grab lock, trying again\n");
+			DEADLOCK_AVOIDANCE(&p->lock);
+		}
+		if (!p->owner) {
+			ast_mutex_unlock(&p->lock);
+			ast_log(LOG_ERROR, "Channel has no owner\n");
+			return;
+		}
+		if (gH323Debug)
+	  		ast_verbose("Writeformat before update %s/%s\n", 
+			  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->writeformat),
+			  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->nativeformats));
+		if (txframes)
+			ast_codec_pref_setsize(&p->prefs, fmt, txframes);
+		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
+		if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
+			ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
+				 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
+		}
+		if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
+			ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
+				 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
+		}
+
+		p->owner->nativeformats = fmt;
+	  	ast_set_write_format(p->owner, p->owner->writeformat);
+	  	ast_set_read_format(p->owner, p->owner->readformat);
+		ast_channel_unlock(p->owner);
+   	} else
+		ast_log(LOG_ERROR, "No owner found\n");
+
+
 	ast_mutex_unlock(&p->lock);
 
-	if (p->owner) {
-	  printf("Writeformat before update %s\n", 
-				  ast_getformatname_multiple(formats,512, p->owner->writeformat));
-	  ast_set_write_format(p->owner, fmt);
-	}
-	else
-	  ast_log(LOG_ERROR, "No owner found\n");
-
-
-#ifdef print_debug
-  printf("+++   ooh323_update_writeformat\n");
-#endif
-#endif
-}
-
+	if (gH323Debug)
+		ast_verbose("+++   ooh323_update_writeformat\n");
+}
 
 void ooh323_set_read_format(ooCallData *call, int fmt)
 {
-#if 0
 	struct ooh323_pvt *p = NULL;
-	char formats[512];
-#ifdef print_debug
-	printf("---   ooh323_update_readformat %s\n", 
-											ast_getformatname_multiple(formats,512, fmt));
-#endif
-
+	char formats[FORMAT_STRING_SIZE];
+
+	if (gH323Debug)
+		ast_verbose("---   ooh323_update_readformat %s\n", 
+				ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt));
+	
 	p = find_call(call);
 	if (!p) {
 		ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
@@ -1075,15 +1420,36 @@
 	}
 
 	ast_mutex_lock(&p->lock);
+
 	p->readformat = fmt;
+
+
+	if (p->owner) {
+		while (p->owner && ast_channel_trylock(p->owner)) {
+			ast_debug(1,"Failed to grab lock, trying again\n");
+			DEADLOCK_AVOIDANCE(&p->lock);
+		}
+		if (!p->owner) {
+			ast_mutex_unlock(&p->lock);
+			ast_log(LOG_ERROR, "Channel has no owner\n");
+			return;
+		}
+
+		if (gH323Debug)
+	  		ast_verbose("Readformat before update %s\n", 
+				  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->readformat));
+		p->owner->nativeformats = fmt;

[... 19179 lines stripped ...]



More information about the svn-commits mailing list