[svn-commits] irroot: branch irroot/distrotech-customers-trunk r319003 - in /team/irroot/di...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sat May 14 13:18:25 CDT 2011


Author: irroot
Date: Sat May 14 13:18:20 2011
New Revision: 319003

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

Merged app_queue / t38gateway


Modified:
    team/irroot/distrotech-customers-trunk/   (props changed)
    team/irroot/distrotech-customers-trunk/CHANGES
    team/irroot/distrotech-customers-trunk/addons/chan_ooh323.c
    team/irroot/distrotech-customers-trunk/apps/app_queue.c
    team/irroot/distrotech-customers-trunk/cel/cel_odbc.c   (props changed)
    team/irroot/distrotech-customers-trunk/channels/chan_local.c
    team/irroot/distrotech-customers-trunk/channels/chan_sip.c
    team/irroot/distrotech-customers-trunk/channels/sip/include/sip.h
    team/irroot/distrotech-customers-trunk/configs/cel_odbc.conf.sample   (props changed)
    team/irroot/distrotech-customers-trunk/configs/queues.conf.sample
    team/irroot/distrotech-customers-trunk/include/asterisk/res_fax.h
    team/irroot/distrotech-customers-trunk/res/res_fax.c
    team/irroot/distrotech-customers-trunk/res/res_fax_spandsp.c
    team/irroot/distrotech-customers-trunk/sounds/Makefile   (props changed)

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
    automerge-email = gregory at distrotech.co.za

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Sat May 14 13:18:20 2011
@@ -1,0 +1,2 @@
+/team/irroot/app_queue-trunk:318983-319002
+/team/irroot/t38gateway-trunk:318974-319002

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
    svnmerge-integrated = /trunk:1-318973

Modified: team/irroot/distrotech-customers-trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/CHANGES?view=diff&rev=319003&r1=319002&r2=319003
==============================================================================
--- team/irroot/distrotech-customers-trunk/CHANGES (original)
+++ team/irroot/distrotech-customers-trunk/CHANGES Sat May 14 13:18:20 2011
@@ -637,6 +637,9 @@
    applications will be lost, and that if the 'fax' logger level is directed to
    the console, the 'core set verbose' and 'core set debug' CLI commands will
    have no effect on whether the messages appear on the console or not.
+ * FAXOPT(faxgateway) will enable a framehook that will take care of T.38
+   negotiation on reciving a CED tone on a channel. this gateway is to allow
+   translation of Audio T.30 [alaw/ulaw] to IFP T.38 terminals.
 
 Miscellaneous
 -------------

Modified: team/irroot/distrotech-customers-trunk/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/addons/chan_ooh323.c?view=diff&rev=319003&r1=319002&r2=319003
==============================================================================
--- team/irroot/distrotech-customers-trunk/addons/chan_ooh323.c (original)
+++ team/irroot/distrotech-customers-trunk/addons/chan_ooh323.c Sat May 14 13:18:20 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
 
@@ -138,6 +174,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;
@@ -199,25 +237,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;
+	char		name[256];
+	char		context[AST_MAX_EXTENSION];
+	int		incominglimit;
+	unsigned	inUse;
+	char		accountcode[20];
+	int		amaflags;
 	struct ast_format_cap *cap;
 	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[4*8+7+2];  /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
-	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[4*8+7+2];  /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
+	struct OOH323Regex *rtpmask;
+	char		rtpmaskstr[120];
+	int		rtdrcount, rtdrinterval;
+	int		faststart, h245tunneling;
+	int		g729onlyA;
 	struct ooh323_user *next;
 };
 
@@ -233,6 +272,7 @@
 	int         amaflags;
 	int         dtmfmode;
 	int	    dtmfcodec;
+	int	    faxdetect;
 	int	    t38support;
 	int         mFriend;    /* indicates defined as friend */
 	char        ip[4*8+7+2]; /* Max for IPv6 - 2 brackets, 8 4hex, 7 - : */
@@ -295,6 +335,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;
@@ -343,10 +384,12 @@
 
 
 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
-                                             const char *host, struct ast_format_cap *cap, const char *linkedid) 
+                                             const char *host, struct ast_format_cap *cap, const char *linkedid)
 {
 	struct ast_channel *ch = NULL;
 	struct ast_format tmpfmt;
+	int features = 0;
+
 	if (gH323Debug)
 		ast_verbose("---   ooh323_new - %s\n", host);
 
@@ -388,16 +431,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);
@@ -484,6 +538,9 @@
 	ast_mutex_lock(&pvt->lock);
 
 	pvt->faxmode = 0;
+	pvt->chmodepend = 0;
+	pvt->faxdetected = 0;
+	pvt->faxdetect = gFAXdetect;
 	pvt->t38support = gT38Support;
 	pvt->rtptimeout = gRTPTimeout;
 	pvt->rtdrinterval = gRTDRInterval;
@@ -610,6 +667,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;
@@ -639,6 +697,7 @@
 		p->g729onlyA = g729onlyA;
 		p->dtmfmode = gDTMFMode;
 		p->dtmfcodec = gDTMFCodec;
+		p->faxdetect = gFAXdetect;
 		p->t38support = gT38Support;
 		p->rtptimeout = gRTPTimeout;
 		ast_format_cap_copy(p->cap, gCap);
@@ -828,17 +887,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) ||
@@ -1258,27 +1307,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:
 				;
@@ -1324,17 +1396,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;
@@ -1750,6 +1823,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;
@@ -2190,6 +2264,7 @@
 		user->rtptimeout = gRTPTimeout;
 		user->dtmfmode = gDTMFMode;
 		user->dtmfcodec = gDTMFCodec;
+		user->faxdetect = gFAXdetect;
 		user->t38support = gT38Support;
 		user->faststart = gFastStart;
 		user->h245tunneling = gTunneling;
@@ -2267,7 +2342,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"))
@@ -2310,11 +2391,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;
 		}
@@ -2414,7 +2496,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"))
@@ -2536,6 +2624,7 @@
 	memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
 	gDTMFMode = H323_DTMF_RFC2833;
 	gDTMFCodec = 101;
+	gFAXdetect = 1;
 	gT38Support = T38_FAXGW;
 	gTRCLVL = OOTRCLVLERR;
 	gRasGkMode = RasNoGatekeeper;
@@ -2739,7 +2828,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"))
@@ -2826,14 +2921,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);
@@ -2841,53 +2935,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);
 
@@ -2977,9 +3073,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);
@@ -2987,53 +3083,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);
 
@@ -3132,91 +3230,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,gCap));
-
-   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,gCap));
+	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;
 		}
 	}
@@ -3233,6 +3325,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)
 {
@@ -3401,6 +3567,9 @@
 		/* And start the monitor for the first time */
 		restart_monitor();
 	}
+
+	/* Register dialplan functions */
+	ast_custom_function_register(&ooh323_function);
 
 	return 0;
 }
@@ -3677,7 +3846,7 @@
 	ast_mutex_unlock(&userl.lock);
 	return 0;
 }
-  
+ 
 static int unload_module(void)
 {
 	struct ooh323_pvt *p;
@@ -3792,8 +3961,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");
 	}
 
 	gCap = ast_format_cap_destroy(gCap);
@@ -4298,6 +4470,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:
@@ -4324,25 +4497,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 (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
-            			ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(&f->subclass.format));
-				ast_format_cap_set(p->owner->nativeformats, &f->subclass.format);
-				ast_set_read_format(p->owner, &p->owner->readformat);
-				ast_set_write_format(p->owner, &p->owner->writeformat);
+		if (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
+			ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(&f->subclass.format));
+			ast_format_cap_set(p->owner->nativeformats, &f->subclass.format);
+			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.format.id == AST_FORMAT_SLINEAR || f->subclass.format.id == AST_FORMAT_ALAW ||
+		     f->subclass.format.id == 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.format.id == AST_FORMAT_SLINEAR || f->subclass.format.id == AST_FORMAT_ALAW ||
-					f->subclass.format.id == 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;
 }
@@ -4365,6 +4573,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;
 	}
@@ -4375,11 +4584,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;

Modified: team/irroot/distrotech-customers-trunk/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/apps/app_queue.c?view=diff&rev=319003&r1=319002&r2=319003
==============================================================================
--- team/irroot/distrotech-customers-trunk/apps/app_queue.c (original)
+++ team/irroot/distrotech-customers-trunk/apps/app_queue.c Sat May 14 13:18:20 2011
@@ -521,11 +521,25 @@
 					<enum name="count">
 						<para>Returns the total number of members for the specified queue.</para>
 					</enum>
+					<enum name="penalty">
+						<para>Gets or sets queue member penalty.</para>
+					</enum>
+					<enum name="paused">
+						<para>Gets or sets queue member paused status.</para>
+					</enum>
+					<enum name="ignorebusy">
+						<para>Gets or sets queue member ignorebusy.</para>
+					</enum>
 				</enumlist>
 			</parameter>
+			<parameter name="interface" required="false" />
 		</syntax>
 		<description>
-			<para>Returns the number of members currently associated with the specified <replaceable>queuename</replaceable>.</para>
+			<para>Allows access to queue counts [R] and member information [R/W].</para>
+			<para>
+				<replaceable>queuename</replaceable> is required for all operations 
+				<replaceable>interface</replaceable> is required for all member operations.
+			</para>
 		</description>
 		<see-also>
 			<ref type="application">Queue</ref>
@@ -934,6 +948,9 @@
 /*! \brief queues.conf [general] option */
 static int update_cdr = 0;
 
+/*! \brief queues.conf [genral] option */
+static int negitive_penalty_invalid = 0;
+

[... 1808 lines stripped ...]



More information about the svn-commits mailing list