[asterisk-commits] nadi: branch crichter/0.4.0 r38730 - in /team/crichter/0.4.0/channels: ./ misdn/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Aug 2 01:14:42 MST 2006


Author: nadi
Date: Wed Aug  2 03:14:42 2006
New Revision: 38730

URL: http://svn.digium.com/view/asterisk?rev=38730&view=rev
Log:
advanced fax detection: configurable detect timeout and context to jump into

Modified:
    team/crichter/0.4.0/channels/chan_misdn.c
    team/crichter/0.4.0/channels/misdn/chan_misdn_config.h
    team/crichter/0.4.0/channels/misdn/isdn_lib.c
    team/crichter/0.4.0/channels/misdn/isdn_lib.h
    team/crichter/0.4.0/channels/misdn_config.c

Modified: team/crichter/0.4.0/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/crichter/0.4.0/channels/chan_misdn.c?rev=38730&r1=38729&r2=38730&view=diff
==============================================================================
--- team/crichter/0.4.0/channels/chan_misdn.c (original)
+++ team/crichter/0.4.0/channels/chan_misdn.c Wed Aug  2 03:14:42 2006
@@ -153,7 +153,9 @@
 	char ast_rd_buf[4096];
 	struct ast_frame frame;
 
-	int faxdetect;
+	int faxdetect; /* 0:no 1:yes 2:yes+nojump */
+	int faxdetect_timeout;
+	struct timeval faxdetect_tv;
 	int faxhandled;
 
 	int ast_dsp;
@@ -1653,7 +1655,7 @@
 
 	char faxdetect[BUFFERSIZE+1];
 	misdn_cfg_get( port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE);
-	
+
 	int hdlc=0;
 	misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
 	
@@ -1720,8 +1722,12 @@
 	if ( orig  == ORG_AST) {
 		misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
 
-		if (!strcasecmp(faxdetect,"outgoing")||	!strcasecmp(faxdetect,"both"))
-			ch->faxdetect=1;
+		if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
+			if (strstr(faxdetect, "nojump"))
+				ch->faxdetect=2;
+			else
+				ch->faxdetect=1;
+		}
 		
 		{
 			char callerid[BUFFERSIZE+1];
@@ -1747,8 +1753,12 @@
 
 		ch->overlap_dial = 0;
 	} else { /** ORIGINATOR MISDN **/
-		if (!strcasecmp(faxdetect,"incoming")||	!strcasecmp(faxdetect,"both"))
-			ch->faxdetect=1;
+		if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
+			if (strstr(faxdetect, "nojump"))
+				ch->faxdetect=2;
+			else
+				ch->faxdetect=1;
+		}
 	
 		misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
 		debug_numplan(port, bc->cpnnumplan,"CTON");
@@ -1818,6 +1828,16 @@
 
 	ch->overlap_dial_task = -1;
 	
+	if (ch->faxdetect) {
+		misdn_cfg_get( port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
+		if (!ch->dsp)
+			ch->dsp = ast_dsp_new();
+		if (ch->dsp)
+			ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT);
+		if (!ch->trans)
+			ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
+	}
+
 	return 0;
 }
 
@@ -2389,7 +2409,7 @@
 	int len;
 	
 	if (!ast) return NULL;
-	if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) return NULL;
+	if (!(tmp=MISDN_ASTERISK_TECH_PVT(ast))) return NULL;
 	if (!tmp->bc) return NULL;
 
 	len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
@@ -2403,17 +2423,40 @@
 	tmp->frame.frametype  = AST_FRAME_VOICE;
 	tmp->frame.subclass = AST_FORMAT_ALAW;
 	tmp->frame.datalen = len;
-	tmp->frame.samples = len ;
-	tmp->frame.mallocd =0 ;
-	tmp->frame.offset= 0 ;
+	tmp->frame.samples = len;
+	tmp->frame.mallocd = 0;
+	tmp->frame.offset = 0;
 	tmp->frame.src = NULL;
-	tmp->frame.data = tmp->ast_rd_buf ;
-	
-	if (tmp->faxdetect || tmp->ast_dsp ) {
-		return process_ast_dsp(tmp, &tmp->frame);
-	}
-	
-	return &tmp->frame;
+	tmp->frame.data = tmp->ast_rd_buf;
+
+	if (tmp->faxdetect && !tmp->faxhandled) {
+		if (tmp->faxdetect_timeout) {
+			if (ast_tvzero(tmp->faxdetect_tv)) {
+				tmp->faxdetect_tv = ast_tvnow();
+				chan_misdn_log(2,tmp->bc->port,"faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
+				return process_ast_dsp(tmp, &tmp->frame);
+			} else {
+				struct timeval tv_now = ast_tvnow();
+				int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
+				if (diff <= (tmp->faxdetect_timeout * 1000)) {
+					chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ...\n");
+					return process_ast_dsp(tmp, &tmp->frame);
+				} else {
+					chan_misdn_log(2,tmp->bc->port,"faxdetect: stopping detection (time ran out) ...\n");
+					tmp->faxdetect = 0;
+					return &tmp->frame;
+				}
+			}
+		} else {
+			chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ... (no timeout)\n");
+			return process_ast_dsp(tmp, &tmp->frame);
+		}
+	} else {
+		if (tmp->ast_dsp)
+			return process_ast_dsp(tmp, &tmp->frame);
+		else
+			return &tmp->frame;
+	}
 }
 
 
@@ -2493,7 +2536,6 @@
 	}
 
 	chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples);
-	
 	if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
 		/* Buffered Transmit (triggert by read from isdn side)*/
 		if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) {
@@ -3025,44 +3067,64 @@
 struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
 {
 	struct ast_frame *f,*f2;
-	if (tmp->trans)
-		f2=ast_translate(tmp->trans, frame,0);
-	else {
+
+	if (tmp->trans) {
+		f2 = ast_translate(tmp->trans, frame, 0);
+		f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
+	} else {
 		chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
 		return NULL;
 	}
-	
-	f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
-	if (f && (f->frametype == AST_FRAME_DTMF)) {
-		ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass);
-		if (f->subclass == 'f' && tmp->faxdetect) {
-			/* Fax tone -- Handle and return NULL */
+
+	if (!f || (f->frametype != AST_FRAME_DTMF))
+		return frame;
+
+	ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass);
+
+	if (tmp->faxdetect && (f->subclass == 'f')) {
+		/* Fax tone -- Handle and return NULL */
+		if (!tmp->faxhandled) {
 			struct ast_channel *ast = tmp->ast;
-			if (!tmp->faxhandled) {
-				tmp->faxhandled++;
+			tmp->faxhandled++;
+			chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name);
+			tmp->bc->rxgain = 0;
+			isdn_lib_update_rxgain(tmp->bc);
+			tmp->bc->txgain = 0;
+			isdn_lib_update_txgain(tmp->bc);
+			tmp->bc->ec_enable = 0;
+			isdn_lib_update_ec(tmp->bc);
+			isdn_lib_stop_dtmf(tmp->bc);
+			switch (tmp->faxdetect) {
+			case 1:
 				if (strcmp(ast->exten, "fax")) {
-					if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) {
+					char *context;
+					char context_tmp[BUFFERSIZE];
+					misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
+					context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
+					if (ast_exists_extension(ast, context, "fax", 1, AST_CID_P(ast))) {
 						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
+							ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
 						/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
 						pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
-						if (ast_async_goto(ast, ast->context, "fax", 1))
-							ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context);
+						if (ast_async_goto(ast, context, "fax", 1))
+							ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
 					} else
-						ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten);
-				} else
+						ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten);
+				} else 
 					ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
-			} else
-				ast_log(LOG_DEBUG, "Fax already handled\n");
-			
-		}  else if ( tmp->ast_dsp) {
-			chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass);
-			return f;
-		}
-	}
-
-	frame->frametype = AST_FRAME_NULL;
-	frame->subclass = 0;
+				break;
+			case 2:
+				ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name);
+				break;
+			}
+		} else
+			ast_log(LOG_DEBUG, "Fax already handled\n");
+	}
+	
+	if (tmp->ast_dsp && (f->subclass != 'f')) {
+		chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass);
+	}
+
 	return frame;
 }
 
@@ -4736,6 +4798,7 @@
 		case 'f':
 			chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
 			ch->faxdetect=1;
+			misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
 			break;
 
 		case 'a':
@@ -4766,7 +4829,6 @@
 	
 	
 	if (ch->faxdetect || ch->ast_dsp) {
-		
 		if (!ch->dsp) ch->dsp = ast_dsp_new();
 		if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
 		if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);

Modified: team/crichter/0.4.0/channels/misdn/chan_misdn_config.h
URL: http://svn.digium.com/view/asterisk/team/crichter/0.4.0/channels/misdn/chan_misdn_config.h?rev=38730&r1=38729&r2=38730&view=diff
==============================================================================
--- team/crichter/0.4.0/channels/misdn/chan_misdn_config.h (original)
+++ team/crichter/0.4.0/channels/misdn/chan_misdn_config.h Wed Aug  2 03:14:42 2006
@@ -59,6 +59,8 @@
 	MISDN_CFG_MAX_IN,              /* int */
 	MISDN_CFG_MAX_OUT,             /* int */
 	MISDN_CFG_FAXDETECT,           /* char[] */
+	MISDN_CFG_FAXDETECT_CONTEXT,   /* char[] */
+	MISDN_CFG_FAXDETECT_TIMEOUT,   /* int */
 	MISDN_CFG_L1_TIMEOUT,          /* int */
 	MISDN_CFG_OVERLAP_DIAL,        /* int */
 	MISDN_CFG_MSNS,                /* char[] */

Modified: team/crichter/0.4.0/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/team/crichter/0.4.0/channels/misdn/isdn_lib.c?rev=38730&r1=38729&r2=38730&view=diff
==============================================================================
--- team/crichter/0.4.0/channels/misdn/isdn_lib.c (original)
+++ team/crichter/0.4.0/channels/misdn/isdn_lib.c Wed Aug  2 03:14:42 2006
@@ -3891,6 +3891,32 @@
 }
 
 /*
+ * allow live control of channel parameters
+ */
+void isdn_lib_update_rxgain (struct misdn_bchannel *bc)
+{
+	manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
+}
+
+void isdn_lib_update_txgain (struct misdn_bchannel *bc)
+{
+	manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
+}
+
+void isdn_lib_update_ec (struct misdn_bchannel *bc)
+{
+	if (bc->ec_enable)
+		manager_ec_enable(bc);
+	else
+		manager_ec_disable(bc);
+}
+
+void isdn_lib_stop_dtmf (struct misdn_bchannel *bc)
+{
+	manager_ph_control(bc, DTMF_TONE_STOP, 0);
+}
+
+/*
  * send control information to the channel (dsp-module)
  */
 void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len)

Modified: team/crichter/0.4.0/channels/misdn/isdn_lib.h
URL: http://svn.digium.com/view/asterisk/team/crichter/0.4.0/channels/misdn/isdn_lib.h?rev=38730&r1=38729&r2=38730&view=diff
==============================================================================
--- team/crichter/0.4.0/channels/misdn/isdn_lib.h (original)
+++ team/crichter/0.4.0/channels/misdn/isdn_lib.h Wed Aug  2 03:14:42 2006
@@ -367,6 +367,10 @@
 
 void manager_ph_control(struct misdn_bchannel *bc, int c1, int c2);
 
+void isdn_lib_update_rxgain (struct misdn_bchannel *bc);
+void isdn_lib_update_txgain (struct misdn_bchannel *bc);
+void isdn_lib_update_ec (struct misdn_bchannel *bc);
+void isdn_lib_stop_dtmf (struct misdn_bchannel *bc);
 
 int misdn_lib_port_restart(int port);
 int misdn_lib_get_port_info(int port);

Modified: team/crichter/0.4.0/channels/misdn_config.c
URL: http://svn.digium.com/view/asterisk/team/crichter/0.4.0/channels/misdn_config.c?rev=38730&r1=38729&r2=38730&view=diff
==============================================================================
--- team/crichter/0.4.0/channels/misdn_config.c (original)
+++ team/crichter/0.4.0/channels/misdn_config.c Wed Aug  2 03:14:42 2006
@@ -209,7 +209,7 @@
 	{ "senddtmf", MISDN_CFG_SENDDTMF, MISDN_CTYPE_BOOL, "no", NONE,
 		"Enable this if we should produce DTMF Tones ourselves." },
 	{ "hold_allowed", MISDN_CFG_HOLD_ALLOWED, MISDN_CTYPE_BOOL, "no", NONE,
-		"Enable this to have support for hold and retrieve.\n" },
+		"Enable this to have support for hold and retrieve." },
 	{ "early_bconnect", MISDN_CFG_EARLY_BCONNECT, MISDN_CTYPE_BOOL, "yes", NONE,
 		"Disable this if you don't mind correct handling of Progress Indicators." },
 	{ "incoming_early_audio", MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CTYPE_BOOL, "no", NONE,
@@ -252,7 +252,19 @@
 		"Defines the maximum amount of outgoing calls per port for this group\n"
 		"\texceeding calls will be rejected" },
 	{ "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE,
-		"Context to jump into if we detect an incoming fax." },
+		"Setup fax detection:\n"
+		"\t    no        - no fax detection\n"
+		"\t    incoming  - fax detection for incoming calls\n"
+		"\t    outgoing  - fax detection for outgoing calls\n"
+		"\t    both      - fax detection for incoming and outgoing calls\n"
+		"\tAdd +nojump to your value (i.e. faxdetect=both+nojump) if you don't want to jump into the\n"
+		"\tfax-extension but still want to detect the fax and prepare the channel for fax transfer." },
+	{ "faxdetect_timeout", MISDN_CFG_FAXDETECT_TIMEOUT, MISDN_CTYPE_INT, "5", NONE,
+		"Number of seconds the fax detection should do its job. After the given period of time,\n"
+		"\twe assume that it's not a fax call and save some CPU time by turning off fax detection.\n"
+		"\tSet this to 0 if you don't want a timeout (never stop detecting)." },
+	{ "faxdetect_context", MISDN_CFG_FAXDETECT_CONTEXT, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
+		"Context to jump into if we detect a fax. Don't set this if you want to stay in the current context." },
 	{ "l1watcher_timeout", MISDN_CFG_L1_TIMEOUT, MISDN_CTYPE_BOOLINT, "0", 4,
 		"Watches the layer 1. If the layer 1 is down, it tries to\n"
 		"\tget it up. The timeout is given in seconds. with 0 as value it\n"



More information about the asterisk-commits mailing list