[asterisk-commits] irroot: branch irroot/t38gateway-1.8 r318990 - /team/irroot/t38gateway-1.8/ad...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat May 14 10:47:03 CDT 2011


Author: irroot
Date: Sat May 14 10:46:59 2011
New Revision: 318990

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=318990
Log:

T.38 Patches to chan_ooh323


Modified:
    team/irroot/t38gateway-1.8/addons/chan_ooh323.c

Modified: team/irroot/t38gateway-1.8/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/t38gateway-1.8/addons/chan_ooh323.c?view=diff&rev=318990&r1=318989&r2=318990
==============================================================================
--- team/irroot/t38gateway-1.8/addons/chan_ooh323.c (original)
+++ team/irroot/t38gateway-1.8/addons/chan_ooh323.c Sat May 14 10:46:59 2011
@@ -23,6 +23,42 @@
 
 #include "chan_ooh323.h"
 #include <math.h>
+
+/*** DOCUMENTATION
+	<function name="OOH323" language="en_US">
+		<synopsis>
+			Allow Setting / Reading OOH323 Settings
+		</synopsis>
+		<syntax>
+			<parameter name="name" required="true">
+				<enumlist>
+					<enum name="faxdetect">
+						<para>Fax Detect [R/W]</para>
+						<para>Returns 0 or 1</para>
+						<para>Write yes or no</para>
+					</enum>
+				</enumlist>
+				<enumlist>
+					<enum name="t38support">
+						<para>t38support [R/W]</para>
+						<para>Returns 0 or 1</para>
+						<para>Write yes or no</para>
+					</enum>
+				</enumlist>
+				<enumlist>
+					<enum name="h323id">
+						<para>Returns h323id [R]</para>
+					</enum>
+				</enumlist>
+			</parameter>
+		</syntax>
+		<description>
+			<para>Read and set channel parameters in the dialplan.
+			<replaceable>name</replaceable> is one of the above only those with a [W] can be writen to.
+			</para>
+		</description>
+	</function>
+***/
 
 #define FORMAT_STRING_SIZE	512
 
@@ -139,6 +175,8 @@
 	struct ast_rtp_instance *vrtp; /* Placeholder for now */
 
 	int t38support;			/* T.38 mode - disable, transparent, faxgw */
+	int faxdetect;
+	int faxdetected;
 	int rtptimeout;
 	struct ast_udptl *udptl;
 	int faxmode;
@@ -200,25 +238,26 @@
 /* Profile of H.323 user registered with PBX*/
 struct ooh323_user{
 	ast_mutex_t lock;
-	char        name[256];
-	char        context[AST_MAX_EXTENSION];
-	int         incominglimit;
-	unsigned    inUse;
-	char        accountcode[20];
-	int         amaflags;
-	format_t    capability;
+	char		name[256];
+	char		context[AST_MAX_EXTENSION];
+	int		incominglimit;
+	unsigned	inUse;
+	char		accountcode[20];
+	int		amaflags;
+	format_t	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];
-	int	    rtdrcount, rtdrinterval;
-	int	    faststart, h245tunneling;
-	int	    g729onlyA;
+	int		dtmfmode;
+	int		dtmfcodec;
+	int		faxdetect;
+	int		t38support;
+	int		rtptimeout;
+	int		mUseIP;        /* Use IP address or H323-ID to search user */
+	char		mIP[20];
+	struct OOH323Regex *rtpmask;
+	char		rtpmaskstr[120];
+	int		rtdrcount, rtdrinterval;
+	int		faststart, h245tunneling;
+	int		g729onlyA;
 	struct ooh323_user *next;
 };
 
@@ -234,6 +273,7 @@
 	int         amaflags;
 	int         dtmfmode;
 	int	    dtmfcodec;
+	int	    faxdetect;
 	int	    t38support;
 	int         mFriend;    /* indicates defined as friend */
 	char        ip[20];
@@ -294,6 +334,7 @@
 static struct ast_codec_pref gPrefs;
 static int  gDTMFMode = H323_DTMF_RFC2833;
 static int  gDTMFCodec = 101;
+static int  gFAXdetect = 1;
 static int  gT38Support = T38_FAXGW;
 static char gGatekeeper[100];
 static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper;
@@ -342,10 +383,12 @@
 
 
 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
-                                             const char *host, int capability, const char *linkedid) 
+                                             const char *host, int capability, const char *linkedid)
 {
 	struct ast_channel *ch = NULL;
 	int fmt = 0;
+	int features = 0;
+
 	if (gH323Debug)
 		ast_verbose("---   ooh323_new - %s, %d\n", host, capability);
 
@@ -389,16 +432,27 @@
 		ast_module_ref(myself);
 
 		/* Allocate dsp for in-band DTMF support */
+		if ((i->dtmfmode & H323_DTMF_INBAND) || i->faxdetect) {
+			i->vad = ast_dsp_new();
+		}
+
+		/* inband DTMF*/
 		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)
+			features |= DSP_FEATURE_DIGIT_DETECT;
+			if (i->dtmfmode & H323_DTMF_INBANDRELAX) {
 				ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
+			}
+		}
+
+		/* fax detection*/
+		if (i->faxdetect) {
+			features |= DSP_FEATURE_FAX_DETECT;
+			ast_dsp_set_faxmode(i->vad,
+					DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED);
+		}
+
+		if (features) {
+			ast_dsp_set_features(i->vad, features);
 		}
 
 		ast_mutex_lock(&usecnt_lock);
@@ -516,6 +570,9 @@
 	ast_udptl_set_error_correction_scheme(pvt->udptl, UDPTL_ERROR_CORRECTION_NONE);
 	ast_udptl_set_far_max_datagram(pvt->udptl, 144);
 	pvt->faxmode = 0;
+	pvt->chmodepend = 0;
+	pvt->faxdetected = 0;
+	pvt->faxdetect = gFAXdetect;
 	pvt->t38support = gT38Support;
 	pvt->rtptimeout = gRTPTimeout;
 	pvt->rtdrinterval = gRTDRInterval;
@@ -645,6 +702,7 @@
 		p->g729onlyA = peer->g729onlyA;
 		p->dtmfmode |= peer->dtmfmode;
 		p->dtmfcodec  = peer->dtmfcodec;
+		p->faxdetect = peer->faxdetect;
 		p->t38support = peer->t38support;
 		p->rtptimeout = peer->rtptimeout;
 		p->faststart = peer->faststart;
@@ -674,6 +732,7 @@
 		p->g729onlyA = g729onlyA;
 		p->dtmfmode = gDTMFMode;
 		p->dtmfcodec = gDTMFCodec;
+		p->faxdetect = gFAXdetect;
 		p->t38support = gT38Support;
 		p->rtptimeout = gRTPTimeout;
 		p->capability = gCapability;
@@ -863,17 +922,7 @@
 	}
 	ast_mutex_lock(&p->lock);
 
-
-	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))) {
+	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) ||
@@ -1290,27 +1339,50 @@
 				(int)sizeof(enum ast_control_t38), (int)datalen);
 		} else {
 			const struct ast_control_t38_parameters *parameters = data;
+			struct ast_control_t38_parameters our_parameters;
 			enum ast_control_t38 message = parameters->request_response;
 			switch (message) {
 
+			case AST_T38_NEGOTIATED:
+				if (p->faxmode) {
+					res = 0;
+					break;
+				}
 			case AST_T38_REQUEST_NEGOTIATE:
 
-				if (!p->chmodepend && !p->faxmode) {
+				if (p->faxmode) {
+					/* T.38 already negotiated */
+					our_parameters.request_response = AST_T38_NEGOTIATED;
+					our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
+					our_parameters.rate = AST_T38_RATE_14400;
+					ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
+				} else if (!p->chmodepend) {
+					p->chmodepend = 1;
 					ooRequestChangeMode(p->callToken, 1);
-					p->chmodepend = 1;
 					res = 0;
 				}
 				break;
 
 			case AST_T38_REQUEST_TERMINATE:
 
-				if (!p->chmodepend && p->faxmode) {
+				if (!p->faxmode) {
+					/* T.38 already terminated */
+					our_parameters.request_response = AST_T38_TERMINATED;
+					ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
+				} else if (!p->chmodepend) {
+					p->chmodepend = 1;
 					ooRequestChangeMode(p->callToken, 0);
-					p->chmodepend = 1;
 					res = 0;
 				}
 				break;
 
+			case AST_T38_REQUEST_PARMS:
+				our_parameters.request_response = AST_T38_REQUEST_PARMS;
+				our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
+				our_parameters.rate = AST_T38_RATE_14400;
+				ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
+				res = AST_T38_REQUEST_PARMS;
+				break;
 
 			default:
 				;
@@ -1356,17 +1428,18 @@
 		case AST_OPTION_T38_STATE:
 
 			if (*datalen != sizeof(enum ast_t38_state)) {
-                        	ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
+				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;
-
+
+			if (p->t38support != T38_DISABLED) {
+				if (p->faxmode) {
+					state = (p->chmodepend) ? T38_STATE_NEGOTIATING : T38_STATE_NEGOTIATED;
+				} else {
+					state = T38_STATE_UNKNOWN;
+				}
+			}
 
 			*((enum ast_t38_state *) data) = state;
 			res = 0;
@@ -1784,6 +1857,7 @@
 		memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref));
 		p->dtmfmode |= user->dtmfmode;
 		p->dtmfcodec = user->dtmfcodec;
+		p->faxdetect = user->faxdetect;
 		p->t38support = user->t38support;
 		p->rtptimeout = user->rtptimeout;
 		p->h245tunneling = user->h245tunneling;
@@ -2206,6 +2280,7 @@
 		user->rtptimeout = gRTPTimeout;
 		user->dtmfmode = gDTMFMode;
 		user->dtmfcodec = gDTMFCodec;
+		user->faxdetect = gFAXdetect;
 		user->t38support = gT38Support;
 		user->faststart = gFastStart;
 		user->h245tunneling = gTunneling;
@@ -2281,7 +2356,13 @@
 				user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
 			} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
 				user->dtmfcodec = atoi(v->value);
-	 		} else if (!strcasecmp(v->name, "t38support")) {
+			} else if (!strcasecmp(v->name, "faxdetect")) {
+				if (ast_true(v->value)) {
+					user->faxdetect = 1;
+				} else {
+					user->faxdetect = 0;
+				}
+			} else if (!strcasecmp(v->name, "t38support")) {
 				if (!strcasecmp(v->value, "disabled"))
 					user->t38support = T38_DISABLED;
 				if (!strcasecmp(v->value, "no"))
@@ -2320,11 +2401,12 @@
 		peer->amaflags = gAMAFLAGS;
 		peer->dtmfmode = gDTMFMode;
 		peer->dtmfcodec = gDTMFCodec;
+		peer->faxdetect = gFAXdetect;
 		peer->t38support = gT38Support;
 		peer->faststart = gFastStart;
 		peer->h245tunneling = gTunneling;
 		peer->g729onlyA = g729onlyA;
-      		peer->port = 1720;
+		peer->port = 1720;
 		if (0 == friend_type) {
 			peer->mFriend = 1;
 		}
@@ -2420,7 +2502,13 @@
 				peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
 			} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
 				peer->dtmfcodec = atoi(v->value);
-	 		} else if (!strcasecmp(v->name, "t38support")) {
+			} else if (!strcasecmp(v->name, "faxdetect")) {
+				if (ast_true(v->value)) {
+					peer->faxdetect = 1;
+				} else {
+					peer->faxdetect = 0;
+				}
+			} else if (!strcasecmp(v->name, "t38support")) {
 				if (!strcasecmp(v->value, "disabled"))
 					peer->t38support = T38_DISABLED;
 				if (!strcasecmp(v->value, "no"))
@@ -2541,6 +2629,7 @@
 	memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
 	gDTMFMode = H323_DTMF_RFC2833;
 	gDTMFCodec = 101;
+	gFAXdetect = 1;
 	gT38Support = T38_FAXGW;
 	gTRCLVL = OOTRCLVLERR;
 	gRasGkMode = RasNoGatekeeper;
@@ -2737,7 +2826,13 @@
 			gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
 		} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
 			gDTMFCodec = atoi(v->value);
-	 	} else if (!strcasecmp(v->name, "t38support")) {
+		} else if (!strcasecmp(v->name, "faxdetect")) {
+			if (ast_true(v->value)) {
+				gFAXdetect = 1;
+			} else {
+				gFAXdetect = 0;
+			}
+		} else if (!strcasecmp(v->name, "t38support")) {
 			if (!strcasecmp(v->value, "disabled"))
 				gT38Support = T38_DISABLED;
 			if (!strcasecmp(v->value, "no"))
@@ -2824,14 +2919,13 @@
 	if (a->argc != 4)
 		return CLI_SHOWUSAGE;
 
- 
 	ast_mutex_lock(&peerl.lock);
 	peer = peerl.peers;
 	while (peer) {
 		ast_mutex_lock(&peer->lock);
-      		if(!strcmp(peer->name, a->argv[3]))
+		if (!strcmp(peer->name, a->argv[3])) {
 			break;
-		else {
+		} else {
 			prev = peer;
 			peer = peer->next;
 			ast_mutex_unlock(&prev->lock);
@@ -2839,53 +2933,55 @@
 	}
 
 	if (peer) {
-      sprintf(ip_port, "%s:%d", peer->ip, peer->port);
-      ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
-      ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no",
+		sprintf(ip_port, "%s:%d", peer->ip, peer->port);
+		ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
+		ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no",
 					peer->h245tunneling?"yes":"no");
-      ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
-      print_codec_to_cli(a->fd, &peer->prefs);
-      ast_cli(a->fd, ")\n");
-      ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
+		ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
+		print_codec_to_cli(a->fd, &peer->prefs);
+		ast_cli(a->fd, ")\n");
+		ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
 		if (peer->dtmfmode & H323_DTMF_CISCO) {
-         ast_cli(a->fd, "%s\n", "cisco");
-	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
+			ast_cli(a->fd, "%s\n", "cisco");
+			ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
 		} else if (peer->dtmfmode & H323_DTMF_RFC2833) {
-         ast_cli(a->fd, "%s\n", "rfc2833");
-	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
-		} else if (peer->dtmfmode & H323_DTMF_Q931)
-         ast_cli(a->fd, "%s\n", "q931keypad");
-		else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC)
-         ast_cli(a->fd, "%s\n", "h245alphanumeric");
-		else if (peer->dtmfmode & H323_DTMF_H245SIGNAL)
-         ast_cli(a->fd, "%s\n", "h245signal");
-		else if (peer->dtmfmode & H323_DTMF_INBAND && peer->dtmfmode & H323_DTMF_INBANDRELAX)
-         ast_cli(a->fd, "%s\n", "inband-relaxed");
-		else if (peer->dtmfmode & H323_DTMF_INBAND)
-         ast_cli(a->fd, "%s\n", "inband");
-		else
-         ast_cli(a->fd, "%s\n", "unknown");
-
-	ast_cli(a->fd,"%-15s", "T.38 Mode: ");
-	if (peer->t38support == T38_DISABLED)
-		ast_cli(a->fd, "%s\n", "disabled");
-	else if (peer->t38support == T38_FAXGW)
-		ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
-
-	ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode);
-	ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", 
-		ast_cdr_flags2str(peer->amaflags));
-	ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port);
-	ast_cli(a->fd, "%-15.15s%d\n", "OutgoingLimit: ", peer->outgoinglimit);
-	ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout);
-	if (peer->rtpmaskstr[0])
-		ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr);
-	if (peer->rtdrcount && peer->rtdrinterval) 
-		ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", peer->rtdrcount, peer->rtdrinterval);
-	ast_mutex_unlock(&peer->lock);
+			ast_cli(a->fd, "%s\n", "rfc2833");
+			ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
+		} else if (peer->dtmfmode & H323_DTMF_Q931) {
+			ast_cli(a->fd, "%s\n", "q931keypad");
+		} else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC) {
+			ast_cli(a->fd, "%s\n", "h245alphanumeric");
+		} else if (peer->dtmfmode & H323_DTMF_H245SIGNAL) {
+			ast_cli(a->fd, "%s\n", "h245signal");
+		} else if (peer->dtmfmode & H323_DTMF_INBAND && peer->dtmfmode & H323_DTMF_INBANDRELAX) {
+			ast_cli(a->fd, "%s\n", "inband-relaxed");
+		} else if (peer->dtmfmode & H323_DTMF_INBAND) {
+			ast_cli(a->fd, "%s\n", "inband");
+		} else {
+			ast_cli(a->fd, "%s\n", "unknown");
+		}
+		ast_cli(a->fd,"%-15s", "T.38 Mode: ");
+		if (peer->t38support == T38_DISABLED) {
+			ast_cli(a->fd, "%s\n", "disabled");
+		} else if (peer->t38support == T38_FAXGW) {
+			ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
+		}
+		ast_cli(a->fd,"%-15s%s\n", "FAX Detect:", (peer->faxdetect) ? "Yes" : "No");
+		ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode);
+		ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", ast_cdr_flags2str(peer->amaflags));
+		ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port);
+		ast_cli(a->fd, "%-15.15s%d\n", "OutgoingLimit: ", peer->outgoinglimit);
+		ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout);
+		if (peer->rtpmaskstr[0]) {
+			ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr);
+		}
+		if (peer->rtdrcount && peer->rtdrinterval) {
+			ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", peer->rtdrcount, peer->rtdrinterval);
+		}
+		ast_mutex_unlock(&peer->lock);
 	} else {
-	ast_cli(a->fd, "Peer %s not found\n", a->argv[3]);
-	ast_cli(a->fd, "\n");
+		ast_cli(a->fd, "Peer %s not found\n", a->argv[3]);
+		ast_cli(a->fd, "\n");
 	}
 	ast_mutex_unlock(&peerl.lock);
 
@@ -2975,9 +3071,9 @@
 	user = userl.users;
 	while (user) {
 		ast_mutex_lock(&user->lock);
-      if(!strcmp(user->name, a->argv[3])) {
+		if (!strcmp(user->name, a->argv[3])) {
 			break;
-      } else {
+		} else {
 			prev = user;
 			user = user->next;
 			ast_mutex_unlock(&prev->lock);
@@ -2985,53 +3081,55 @@
 	}
 
 	if (user) {
-      ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name);
-      ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", user->faststart?"yes":"no",
+		ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name);
+		ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", user->faststart?"yes":"no",
 					user->h245tunneling?"yes":"no");
-      ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
-      print_codec_to_cli(a->fd, &user->prefs);
-      ast_cli(a->fd, ")\n");
-      ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
+		ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
+		print_codec_to_cli(a->fd, &user->prefs);
+		ast_cli(a->fd, ")\n");
+		ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
 		if (user->dtmfmode & H323_DTMF_CISCO) {
-         ast_cli(a->fd, "%s\n", "cisco");
-	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
+			ast_cli(a->fd, "%s\n", "cisco");
+			ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
 		} else if (user->dtmfmode & H323_DTMF_RFC2833) {
-         ast_cli(a->fd, "%s\n", "rfc2833");
-	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
-		} else if (user->dtmfmode & H323_DTMF_Q931)
-         ast_cli(a->fd, "%s\n", "q931keypad");
-		else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC)
-         ast_cli(a->fd, "%s\n", "h245alphanumeric");
-		else if (user->dtmfmode & H323_DTMF_H245SIGNAL)
-         ast_cli(a->fd, "%s\n", "h245signal");
-		else if (user->dtmfmode & H323_DTMF_INBAND && user->dtmfmode & H323_DTMF_INBANDRELAX)
-         ast_cli(a->fd, "%s\n", "inband-relaxed");
-		else if (user->dtmfmode & H323_DTMF_INBAND)
-         ast_cli(a->fd, "%s\n", "inband");
-		else
-         ast_cli(a->fd, "%s\n", "unknown");
-
-   	ast_cli(a->fd,"%-15s", "T.38 Mode: ");
-	if (user->t38support == T38_DISABLED)
-		ast_cli(a->fd, "%s\n", "disabled");
-	else if (user->t38support == T38_FAXGW)
-		ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
-
-      ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode);
-      ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", 
-                                            ast_cdr_flags2str(user->amaflags));
-      ast_cli(a->fd, "%-15.15s%s\n", "Context: ", user->context);
-      ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit);
-      ast_cli(a->fd, "%-15.15s%d\n", "InUse: ", user->inUse);
-      ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout);
-	if (user->rtpmaskstr[0])
-		ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr);
+			ast_cli(a->fd, "%s\n", "rfc2833");
+			ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
+		} else if (user->dtmfmode & H323_DTMF_Q931) {
+			ast_cli(a->fd, "%s\n", "q931keypad");
+		} else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC) {
+			ast_cli(a->fd, "%s\n", "h245alphanumeric");
+		} else if (user->dtmfmode & H323_DTMF_H245SIGNAL) {
+			ast_cli(a->fd, "%s\n", "h245signal");
+		} else if (user->dtmfmode & H323_DTMF_INBAND && user->dtmfmode & H323_DTMF_INBANDRELAX) {
+			ast_cli(a->fd, "%s\n", "inband-relaxed");
+		} else if (user->dtmfmode & H323_DTMF_INBAND) {
+			ast_cli(a->fd, "%s\n", "inband");
+		} else {
+			ast_cli(a->fd, "%s\n", "unknown");
+		}
+		ast_cli(a->fd,"%-15s", "T.38 Mode: ");
+		if (user->t38support == T38_DISABLED) {
+			ast_cli(a->fd, "%s\n", "disabled");
+		} else if (user->t38support == T38_FAXGW) {
+			ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
+		}
+		ast_cli(a->fd,"%-15s%s\n", "FAX Detect:", (user->faxdetect) ? "Yes" : "No");
+		ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode);
+		ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", ast_cdr_flags2str(user->amaflags));
+		ast_cli(a->fd, "%-15.15s%s\n", "Context: ", user->context);
+		ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit);
+		ast_cli(a->fd, "%-15.15s%d\n", "InUse: ", user->inUse);
+		ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout);
+		if (user->rtpmaskstr[0]) {
+			ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr);
+		}
 		ast_mutex_unlock(&user->lock);
-	if (user->rtdrcount && user->rtdrinterval) 
-		ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", user->rtdrcount, user->rtdrinterval);
+		if (user->rtdrcount && user->rtdrinterval) {
+			ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", user->rtdrcount, user->rtdrinterval);
+		}
 	} else {
-     ast_cli(a->fd, "User %s not found\n", a->argv[3]);
-     ast_cli(a->fd, "\n");
+		ast_cli(a->fd, "User %s not found\n", a->argv[3]);
+		ast_cli(a->fd, "\n");
 	}
 	ast_mutex_unlock(&userl.lock);
 
@@ -3130,91 +3228,85 @@
 	if (a->argc != 3)
 		return CLI_SHOWUSAGE;
 
-
-
-   ast_cli(a->fd, "\nObjective Open H.323 Channel Driver's Config:\n");
+	ast_cli(a->fd, "\nObjective Open H.323 Channel Driver's Config:\n");
 	snprintf(value, sizeof(value), "%s:%d", gIP, gPort);
-   ast_cli(a->fd, "%-20s%s\n", "IP:Port: ", value);
-   ast_cli(a->fd, "%-20s%d-%d\n", "H.225 port range: ", 
-      ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd);
-   ast_cli(a->fd, "%-20s%s\n", "FastStart", gFastStart?"yes":"no");
-   ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no");
-   ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID);
-   ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect", 
-      gMediaWaitForConnect?"yes":"no");
+	ast_cli(a->fd, "%-20s%s\n", "IP:Port: ", value);
+	ast_cli(a->fd, "%-20s%d-%d\n", "H.225 port range: ", ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd);
+	ast_cli(a->fd, "%-20s%s\n", "FastStart", gFastStart?"yes":"no");
+	ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no");
+	ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID);
+	ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect", gMediaWaitForConnect?"yes":"no");
 
 #if (0)
 		extern OOH323EndPoint gH323ep;
-   ast_cli(a->fd, "%-20s%s\n", "FASTSTART", 
-			(OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART) != 0) ? "yes" : "no");
-   ast_cli(a->fd, "%-20s%s\n", "TUNNELING", 
-			(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING) != 0) ? "yes" : "no");
-   ast_cli(a->fd, "%-20s%s\n", "MEDIAWAITFORCONN",
-			(OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN) != 0) ? "yes" : "no");
+	ast_cli(a->fd, "%-20s%s\n", "FASTSTART",
+		(OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART) != 0) ? "yes" : "no");
+	ast_cli(a->fd, "%-20s%s\n", "TUNNELING",
+		(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING) != 0) ? "yes" : "no");
+	ast_cli(a->fd, "%-20s%s\n", "MEDIAWAITFORCONN",
+		(OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN) != 0) ? "yes" : "no");
 #endif
 
-	if (gRasGkMode == RasNoGatekeeper)
+	if (gRasGkMode == RasNoGatekeeper) {
 		snprintf(value, sizeof(value), "%s", "No Gatekeeper");
-	else if (gRasGkMode == RasDiscoverGatekeeper)
+	} else if (gRasGkMode == RasDiscoverGatekeeper) {
 		snprintf(value, sizeof(value), "%s", "Discover");
-	else
+	} else {
 		snprintf(value, sizeof(value), "%s", gGatekeeper);
-
-   ast_cli(a->fd,  "%-20s%s\n", "Gatekeeper:", value);
-
-   ast_cli(a->fd,  "%-20s%s\n", "H.323 LogFile:", gLogFile);   
-
-   ast_cli(a->fd,  "%-20s%s\n", "Context:", gContext);
-   
-   ast_cli(a->fd,  "%-20s%s\n", "Capability:", 
-           ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCapability));
-
-   ast_cli(a->fd, "%-20s", "DTMF Mode: ");
+	}
+	ast_cli(a->fd,  "%-20s%s\n", "Gatekeeper:", value);
+	ast_cli(a->fd,  "%-20s%s\n", "H.323 LogFile:", gLogFile);
+	ast_cli(a->fd,  "%-20s%s\n", "Context:", gContext);
+	ast_cli(a->fd,  "%-20s%s\n", "Capability:",
+		ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCapability));
+	ast_cli(a->fd, "%-20s", "DTMF Mode: ");
 	if (gDTMFMode & H323_DTMF_CISCO) {
-      ast_cli(a->fd, "%s\n", "cisco");
-      ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec);
+		ast_cli(a->fd, "%s\n", "cisco");
+		ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec);
 	} else if (gDTMFMode & H323_DTMF_RFC2833) {
-      ast_cli(a->fd, "%s\n", "rfc2833");
-      ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec);
-	} else if (gDTMFMode & H323_DTMF_Q931)
-      ast_cli(a->fd, "%s\n", "q931keypad");
-	else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC)
-      ast_cli(a->fd, "%s\n", "h245alphanumeric");
-	else if (gDTMFMode & H323_DTMF_H245SIGNAL)
-      ast_cli(a->fd, "%s\n", "h245signal");
-		else if (gDTMFMode & H323_DTMF_INBAND && gDTMFMode & H323_DTMF_INBANDRELAX)
-         ast_cli(a->fd, "%s\n", "inband-relaxed");
-		else if (gDTMFMode & H323_DTMF_INBAND)
-         ast_cli(a->fd, "%s\n", "inband");
-	else
+		ast_cli(a->fd, "%s\n", "rfc2833");
+		ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec);
+	} else if (gDTMFMode & H323_DTMF_Q931) {
+		ast_cli(a->fd, "%s\n", "q931keypad");
+	} else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC) {
+		ast_cli(a->fd, "%s\n", "h245alphanumeric");
+	} else if (gDTMFMode & H323_DTMF_H245SIGNAL) {
+		ast_cli(a->fd, "%s\n", "h245signal");
+	} else if (gDTMFMode & H323_DTMF_INBAND && gDTMFMode & H323_DTMF_INBANDRELAX) {
+		ast_cli(a->fd, "%s\n", "inband-relaxed");
+	} else if (gDTMFMode & H323_DTMF_INBAND) {
+		ast_cli(a->fd, "%s\n", "inband");
+	} else {
 		ast_cli(a->fd, "%s\n", "unknown");
-
-   	ast_cli(a->fd,"%-20s", "T.38 Mode: ");
-	if (gT38Support == T38_DISABLED)
+	}
+
+	ast_cli(a->fd,"%-20s", "T.38 Mode: ");
+	if (gT38Support == T38_DISABLED) {
 		ast_cli(a->fd, "%s\n", "disabled");
-	else if (gT38Support == T38_FAXGW)
+	} else if (gT38Support == T38_FAXGW) {
 		ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
-
-	if (gRTDRCount && gRTDRInterval)
-		ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval);
-
-   ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber);
-   ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode);
-
-   ast_cli(a->fd, "%-20s%s\n", "AMA flags: ", ast_cdr_flags2str(gAMAFLAGS));
+	}
+	ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", (gFAXdetect) ? "Yes" : "No");
+
+	if (gRTDRCount && gRTDRInterval) {
+		ast_cli(a->fd, "%-20.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval);
+	}
+
+	ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber);
+	ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode);
+	ast_cli(a->fd, "%-20s%s\n", "AMA flags: ", ast_cdr_flags2str(gAMAFLAGS));
 
 	pAlias = gAliasList;
-   if(pAlias) {
-     ast_cli(a->fd, "%-20s\n", "Aliases: ");
-   }
+	if(pAlias) {
+		ast_cli(a->fd, "%-20s\n", "Aliases: ");
+	}
 	while (pAlias) {
 		pAliasNext = pAlias->next;
 		if (pAliasNext) {
-         ast_cli(a->fd,"\t%-30s\t%-30s\n",pAlias->value, pAliasNext->value);
+			ast_cli(a->fd,"\t%-30s\t%-30s\n",pAlias->value, pAliasNext->value);
 			pAlias = pAliasNext->next;
-      }
-      else{
-         ast_cli(a->fd,"\t%-30s\n",pAlias->value);
+		} else {
+			ast_cli(a->fd,"\t%-30s\n",pAlias->value);
 			pAlias = pAlias->next;
 		}
 	}
@@ -3231,6 +3323,80 @@
         AST_CLI_DEFINE(handle_cli_ooh323_reload, "reload ooh323 config")
 };
 
+/*! \brief OOH323 Dialplan function - reads ooh323 settings */
+static int function_ooh323_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+	struct ooh323_pvt *p = chan->tech_pvt;
+
+	if (strcmp(chan->tech->type, "OOH323")) {
+		ast_log(LOG_ERROR, "This function is only supported on OOH323 channels Channel is %s\n", chan->tech->type);
+		return -1;
+	}
+
+	if (!strcasecmp(data, "faxdetect")) {
+		ast_copy_string(buf, p->faxdetect ? "1" : "0", len);
+	} else if (!strcasecmp(data, "t38support")) {
+		ast_copy_string(buf, p->t38support ? "1" : "0", len);
+	} else if (!strcasecmp(data, "caller_h323id")) {
+		ast_copy_string(buf, p->caller_h323id, len);
+	} else if (!strcasecmp(data, "caller_dialeddigits")) {
+		ast_copy_string(buf, p->caller_dialedDigits, len);
+	} else if (!strcasecmp(data, "caller_email")) {
+		ast_copy_string(buf, p->caller_email, len);
+	} else if (!strcasecmp(data, "h323id_url")) {
+		ast_copy_string(buf, p->caller_url, len);
+	} else if (!strcasecmp(data, "callee_h323id")) {
+		ast_copy_string(buf, p->callee_h323id, len);
+	} else if (!strcasecmp(data, "callee_dialeddigits")) {
+		ast_copy_string(buf, p->callee_dialedDigits, len);
+	} else if (!strcasecmp(data, "callee_email")) {
+		ast_copy_string(buf, p->callee_email, len);
+	} else if (!strcasecmp(data, "callee_url")) {
+		ast_copy_string(buf, p->callee_url, len);
+	}
+	return 0;
+}
+
+/*! \brief OOH323 Dialplan function - writes ooh323 settings */
+static int function_ooh323_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+	struct ooh323_pvt *p = chan->tech_pvt;
+
+	int res = -1;
+	if (strcmp(chan->tech->type, "OOH323")) {
+		ast_log(LOG_ERROR, "This function is only supported on OOH323 channels Channel is %s\n", chan->tech->type);
+		return res;
+	}
+
+	ast_mutex_lock(&p->lock);
+	if (!strcasecmp(data, "faxdetect")) {
+		if (ast_true(value)) {
+			p->faxdetect = 1;
+			res = 0;
+		} else {
+			p->faxdetect = 0;
+			res = 0;
+		}
+	} else if (!strcasecmp(data, "t38support")) {
+		if (ast_true(value)) {
+			p->t38support = 1;
+			res = 0;
+		} else {
+			p->t38support = 0;
+			res = 0;
+		}
+	}
+	ast_mutex_unlock(&p->lock);
+
+	return res;
+}
+
+/*! \brief Structure to declare a dialplan function: OOH323 */
+static struct ast_custom_function ooh323_function = {
+        .name = "OOH323",
+        .read = function_ooh323_read,
+        .write = function_ooh323_write,
+};
 
 static int load_module(void)
 {
@@ -3387,6 +3553,9 @@
 		/* And start the monitor for the first time */
 		restart_monitor();
 	}
+
+	/* Register dialplan functions */
+	ast_custom_function_register(&ooh323_function);
 
 	return 0;
 }
@@ -3662,7 +3831,7 @@
 	ast_mutex_unlock(&userl.lock);
 	return 0;
 }
-  
+
 static int unload_module(void)
 {
 	struct ooh323_pvt *p;
@@ -3777,8 +3946,11 @@
 	}
 	ooH323EpDestroy();
 
+	/* Unregister dial plan functions */
+	ast_custom_function_unregister(&ooh323_function);
+
 	if (gH323Debug) {
-		ast_verbose("+++ ooh323  unload_module \n");	
+		ast_verbose("+++ ooh323  unload_module \n");
 	}
 
 	return 0;
@@ -4243,6 +4415,7 @@
 {
 	/* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
 	struct ast_frame *f;
+	struct ast_frame *dfr = NULL;
 	static struct ast_frame null_frame = { AST_FRAME_NULL, };
 	switch (ast->fdno) {
 	case 0:
@@ -4267,24 +4440,60 @@
 		f = &null_frame;
 	}
 
-	if (p->owner) {
+	if (p->owner && (f->frametype == AST_FRAME_VOICE)) {
 		/* We already hold the channel lock */
-		if (f->frametype == AST_FRAME_VOICE && !p->faxmode) {
-			if (f->subclass.codec != p->owner->nativeformats) {
-            			ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(f->subclass.codec));
-				p->owner->nativeformats = f->subclass.codec;
-				ast_set_read_format(p->owner, p->owner->readformat);
-				ast_set_write_format(p->owner, p->owner->writeformat);
+		if (f->subclass.codec != p->owner->nativeformats) {
+			ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(f->subclass.codec));
+			p->owner->nativeformats = f->subclass.codec;
+			ast_set_read_format(p->owner, p->owner->readformat);
+			ast_set_write_format(p->owner, p->owner->writeformat);
+		}
+		if (((p->dtmfmode & H323_DTMF_INBAND) || p->faxdetect) && p->vad &&
+		    (f->subclass.codec == AST_FORMAT_SLINEAR || f->subclass.codec == AST_FORMAT_ALAW ||
+		     f->subclass.codec == AST_FORMAT_ULAW)) {
+			dfr = ast_frdup(f);
+			dfr = ast_dsp_process(p->owner, p->vad, dfr);
+		}
+	} else {
+		return f;
+	}
+
+	/* process INBAND DTMF*/
+	if (dfr && (dfr->frametype == AST_FRAME_DTMF) && ((dfr->subclass.integer == 'f') || (dfr->subclass.integer == 'e'))) {
+		ast_debug(1, "* Detected FAX Tone %s\n", (dfr->subclass.integer == 'e') ? "CED" : "CNG");
+		/* Switch to T.38 ON CED*/
+		if (!p->faxmode && !p->chmodepend && (dfr->subclass.integer == 'e') && (p->t38support != T38_DISABLED)) {
+			if (gH323Debug)
+				ast_verbose("request to change %s to t.38 because fax ced\n", p->callToken);
+			p->chmodepend = 1;
+			ooRequestChangeMode(p->callToken, 1);
+			p->faxdetect = 0;
+			if (!(p->dtmfmode & H323_DTMF_INBAND)) {
+				ast_dsp_free(p->vad);
+				p->vad = NULL;
 			}
-
-			if ((p->dtmfmode & H323_DTMF_INBAND) && p->vad &&
-				(f->subclass.codec == AST_FORMAT_SLINEAR || f->subclass.codec == AST_FORMAT_ALAW ||
-					f->subclass.codec == AST_FORMAT_ULAW)) {
-				f = ast_dsp_process(p->owner, p->vad, f);
-            			if (f && (f->frametype == AST_FRAME_DTMF)) 
-               				ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
+		} else if ((dfr->subclass.integer == 'f') && !p->faxdetected) {
+			const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
+			if ((strcmp(p->owner->exten, "fax")) &&
+			    (ast_exists_extension(p->owner, target_context, "fax", 1,
+		            S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL)))) {
+				ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n", p->owner->name);
+				pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
+				if (ast_async_goto(p->owner, target_context, "fax", 1)) {
+					ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name,target_context);
+				}
+				p->faxdetected = 1;
+				return &ast_null_frame;
 			}
 		}
+	} else if (dfr && dfr->frametype == AST_FRAME_DTMF) {
+		ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
+		ast_frfree(f);
+		return dfr;
+	}
+
+	if (dfr) {
+		ast_frfree(dfr);
 	}
 	return f;
 }
@@ -4307,6 +4516,7 @@
 		if (gH323Debug)
 			ast_debug(1, "mode for %s is already %d\n", call->callToken,
 					t38mode);
+		p->chmodepend = 0;
 		ast_mutex_unlock(&p->lock);
 		return;
 	}
@@ -4317,11 +4527,13 @@
 			DEADLOCK_AVOIDANCE(&p->lock);
 		}
 		if (!p->owner) {
+			p->chmodepend = 0;
 			ast_mutex_unlock(&p->lock);
 			ast_log(LOG_ERROR, "Channel has no owner\n");
 			return;
 		}
 	} else {
+		p->chmodepend = 0;
 		ast_mutex_unlock(&p->lock);
 		ast_log(LOG_ERROR, "Channel has no owner\n");
 		return;




More information about the asterisk-commits mailing list