[asterisk-commits] branch 1.2 - r7490 in /branches/1.2: channels/ channels/misdn/ doc/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Dec 15 04:52:39 CST 2005


Author: crichter
Date: Thu Dec 15 04:52:30 2005
New Revision: 7490

URL: http://svn.digium.com/view/asterisk?rev=7490&view=rev
Log:
* Added mISDN/mISDNuser Echo cancel Patch
* Fixed Makefiles so that chan_misdn can be compiled again
* added some hints, that mISDN cannot be compiled against gcc-4, SMP, Spinlock Debug
* fixed some Minor issues in chan_misdn, regarding Type Of Number and Presentation





Added:
    branches/1.2/channels/misdn/mISDN.patch
    branches/1.2/channels/misdn/mISDNuser.patch
Modified:
    branches/1.2/channels/Makefile
    branches/1.2/channels/chan_misdn.c
    branches/1.2/channels/chan_misdn_config.c
    branches/1.2/channels/misdn/Makefile
    branches/1.2/channels/misdn/chan_misdn_config.h
    branches/1.2/channels/misdn/ie.c
    branches/1.2/channels/misdn/isdn_lib.c
    branches/1.2/channels/misdn/isdn_lib.h
    branches/1.2/channels/misdn/isdn_lib_intern.h
    branches/1.2/channels/misdn/isdn_msg_parser.c
    branches/1.2/doc/README.misdn

Modified: branches/1.2/channels/Makefile
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/Makefile?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/Makefile (original)
+++ branches/1.2/channels/Makefile Thu Dec 15 04:52:30 2005
@@ -83,6 +83,7 @@
 
 ifneq ($(wildcard misdn/chan_misdn_lib.a),)
   CHANNEL_LIBS+=chan_misdn.so
+  CFLAGS+=-Imisdn 
 endif
 
 CFLAGS+=-Wno-missing-prototypes -Wno-missing-declarations
@@ -234,11 +235,10 @@
 endif
 
 chan_misdn.so: chan_misdn.o chan_misdn_config.o misdn/chan_misdn_lib.a
-	$(CC) -shared -Xlinker -x -o $@ $^ $(MISDNUSER)/i4lnet/libisdnnet.a $(MISDNUSER)/lib/libmISDN.a 
-
-chan_misdn_config.o: chan_misdn_config.c
-	$(CC) $(CFLAGS) -c chan_misdn_config.c
-
+	$(CC) -shared -Xlinker -x -L/usr/lib -o $@ $^ -lmISDN -lisdnnet
+
+chan_misdn.o: chan_misdn.c
+	$(CC) $(CFLAGS) -DCHAN_MISDN_VERSION=\"0.2.1\" -c $< -o $@
 
 #chan_modem.so : chan_modem.o
 #	$(CC) -rdynamic -shared -Xlinker -x -o $@ $<

Modified: branches/1.2/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/chan_misdn.c?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/chan_misdn.c (original)
+++ branches/1.2/channels/chan_misdn.c Thu Dec 15 04:52:30 2005
@@ -1092,12 +1092,11 @@
 		ast_setstate(ast, AST_STATE_DOWN);
 		return -1;
 	}
-	
+
 	port=newbc->port;
-	
+
 	ast_copy_string(newbc->dad, ext, sizeof(newbc->dad));
 	ast_copy_string(ast->exten, ext, sizeof(ast->exten));
-	
 	
 	chan_misdn_log(1, 0, "* CALL: %s\n",dest);
 	
@@ -1131,22 +1130,63 @@
 					strncpy(newbc->oad,callerid, l);
 					newbc->oad[l-1] = 0;
 				}
-				
-				misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &newbc->dnumplan, sizeof(int));
-				switch (newbc->dnumplan) {
-				case NUMPLAN_INTERNATIONAL:
-				case NUMPLAN_NATIONAL:
-				case NUMPLAN_SUBSCRIBER:
-				case NUMPLAN_UNKNOWN:
-					/* Maybe we should cut off the prefix if present ? */
-					break;
-				default:
+			}
+
+			
+			misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &newbc->dnumplan, sizeof(int));
+			switch (newbc->dnumplan) {
+			case NUMPLAN_INTERNATIONAL:
+				chan_misdn_log(2, port, " --> TON: International\n");
+				break;
+			case NUMPLAN_NATIONAL:
+				chan_misdn_log(2, port, " --> TON: National\n");
+				break;
+			case NUMPLAN_SUBSCRIBER:
+				chan_misdn_log(2, port, " --> TON: Subscriber\n");
+				break;
+			case NUMPLAN_UNKNOWN:
+				chan_misdn_log(2, port, " --> TON: Unknown\n");
+				break;
+				/* Maybe we should cut off the prefix if present ? */
+			default:
 					chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
 					break;
-				}
-				
-			}
-		}
+			}
+
+
+			misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &newbc->onumplan, sizeof(int));
+			switch (newbc->onumplan) {
+			case NUMPLAN_INTERNATIONAL:
+				chan_misdn_log(2, port, " --> TON: International\n");
+				break;
+			case NUMPLAN_NATIONAL:
+				chan_misdn_log(2, port, " --> TON: National\n");
+				break;
+			case NUMPLAN_SUBSCRIBER:
+				chan_misdn_log(2, port, " --> TON: Subscriber\n");
+				break;
+			case NUMPLAN_UNKNOWN:
+				chan_misdn_log(2, port, " --> TON: Unknown\n");
+				break;
+				/* Maybe we should cut off the prefix if present ? */
+			default:
+					chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
+					break;
+			}
+		}
+
+
+
+		
+		{
+			int eb3;
+			
+			misdn_cfg_get( port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
+			newbc->early_bconnect=eb3;
+			
+		}
+		
+
 		
 		/* Will be overridden by asterisk in head! */
 		{
@@ -1160,38 +1200,48 @@
 		int def_callingpres;
 		misdn_cfg_get( port, MISDN_CFG_USE_CALLINGPRES, &def_callingpres, sizeof(int));
 		if ( def_callingpres) {
+			
 			switch (ast->cid.cid_pres & 0x60){
 				
 			case AST_PRES_RESTRICTED:
+				chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n");
 				newbc->pres=1;
 				break;
 				
+				
 			case AST_PRES_UNAVAILABLE:
+				chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n");
 				newbc->pres=2;
 				break;
-			
+				
 			default:
+				chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n");
 				newbc->pres=0;
 			}
 			
 			switch (ast->cid.cid_pres & 0x3){
 				
 			case AST_PRES_USER_NUMBER_UNSCREENED:
+				chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
 				newbc->screen=0;
 				break;
 
 			case AST_PRES_USER_NUMBER_PASSED_SCREEN:
+				chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n");
 				newbc->screen=1;
 				break;
 			case AST_PRES_USER_NUMBER_FAILED_SCREEN:
+				chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n");
 				newbc->screen=2;
 				break;
 				
 			case AST_PRES_NETWORK_NUMBER:
+				chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n");
 				newbc->screen=3;
 				break;
 				
 			default:
+				chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
 				newbc->screen=0;
 			}
 		}
@@ -1210,9 +1260,11 @@
 				newbc->ec_deftaps=ec;
 			}
 
-			if ( !ectr ) {
-				newbc->ec_training=0;
-			}
+
+			if (ectr>=0) {
+				newbc->ec_training=ectr;
+			}
+			
 		}
 		
 	} 
@@ -1533,9 +1585,8 @@
 	struct chan_list *p;
 	struct misdn_bchannel *bc=NULL;
 	
-	if (!ast || ! MISDN_ASTERISK_PVT(ast)) return -1;
-	p = MISDN_ASTERISK_TECH_PVT(ast) ;
-
+	if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1;
+	
 	release_lock;
 
 	chan_misdn_trace_call(ast,1,"*->I: EVENT_HANGUP cause=%d\n",ast->hangupcause);
@@ -1666,8 +1717,7 @@
 	int len =0 ;
 	
 	if (!ast) return NULL;
-	tmp = MISDN_ASTERISK_TECH_PVT(ast);
-	if (!tmp) return NULL;
+	if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) return NULL;
 	if (!tmp->bc) return NULL;
 	
 	
@@ -1699,8 +1749,7 @@
 	struct chan_list *p;
 	int i  = 0;
 	
-	if (!ast || ! MISDN_ASTERISK_PVT(ast)) return -1;
-	p = MISDN_ASTERISK_TECH_PVT(ast) ;
+	if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
 	
 	if (!p->bc ) {
 		ast_log(LOG_WARNING, "private but no bc\n");
@@ -2099,15 +2148,18 @@
 		tmp->priority=1;
     
 		
-		if (context)
+		if (context) {
 			ast_copy_string(tmp->context, context, sizeof(tmp->context));
-		else
+		}  else {
 			chan_misdn_log(1,0,"misdn_new: no context given.\n");
-		if (exten) 
-			ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
-		else
+		}
+		
+		if (exten) {
+			ast_copy_string(tmp->exten, exten,  sizeof(tmp->exten));
+		} else {
 			chan_misdn_log(1,0,"misdn_new: no exten given.\n");
-
+		}
+		
 		if (callerid) {
 			char *cid_name, *cid_num;
       
@@ -2863,31 +2915,24 @@
 		/** queue new chan **/
 		cl_queue_chan(&cl_te, ch) ;
 
-
+		
 		/*
 		  added support for s extension hope it will help those poor cretains
 		  which haven't overlap dial.
 		*/
 		{
 			
-			misdn_cfg_get( bc->port, MISDN_CFG_LANGUAGE, chan->language, sizeof(chan->language));
-			int ai;
-			misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
-			if ( ai ) {
-				do_immediate_setup(bc, ch , chan);
-				break;
-			}
-
-			int immediate;
-			misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &immediate, sizeof(int));
-			
-			if (ast_strlen_zero(bc->orig_dad) && immediate ) {
-				do_immediate_setup(bc, ch , chan);
-				break;
-			}
-			
-		}
-
+			misdn_cfg_get( bc->port, MISDN_CFG_LANGUAGE, chan->language, sizeof(chan->language));			
+			
+		}
+
+		{
+			int eb3;
+			
+			misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
+			bc->early_bconnect=eb3;
+			
+		}
 
 		{
 			int ec, ectr;
@@ -2902,8 +2947,8 @@
 				bc->ec_deftaps=ec;
 			}
 			
-			if ( !ectr ) {
-				bc->ec_training=0;
+			if ( ectr>=0 ) {
+				bc->ec_training=ectr;
 			}
 		}
 		
@@ -2912,6 +2957,29 @@
 			char buf[16];
 			snprintf(buf,16,"%d",bc->urate);
 			pbx_builtin_setvar_helper(chan,"MISDN_URATE",buf);
+		}
+
+
+
+		/**
+		   from here on  we start the PBX, so no configuration should
+		   be considered anymore
+		**/
+		
+		int ai;
+		misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
+		if ( ai ) {
+			do_immediate_setup(bc, ch , chan);
+			break;
+		}
+		
+			
+		int immediate;
+		misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &immediate, sizeof(int));
+		
+		if (ast_strlen_zero(bc->orig_dad) && immediate ) {
+			do_immediate_setup(bc, ch , chan);
+			break;
 		}
 		
 		/* Check for Pickup Request first */
@@ -3210,8 +3278,6 @@
 		struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
 		ch->state = MISDN_CONNECTED;
 		
-		//ast_moh_stop(ch->ast);
-		//start_bc_tones(ch);
 		if (hold_ast) {
 			ast_moh_stop(hold_ast);
 		}
@@ -3384,8 +3450,8 @@
 int unload_module(void)
 {
 	/* First, take us out of the channel loop */
-	chan_misdn_log(0, 0, "-- Unregistering mISDN Channel Driver --\n");
-
+	ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
+	
 	if (!g_config_initialized) return 0;
 	
 	ast_cli_unregister(&cli_send_display);

Modified: branches/1.2/channels/chan_misdn_config.c
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/chan_misdn_config.c?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/chan_misdn_config.c (original)
+++ branches/1.2/channels/chan_misdn_config.c Thu Dec 15 04:52:30 2005
@@ -29,6 +29,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "chan_misdn_config.h"
 
@@ -59,7 +60,8 @@
 	char *language;
 	char *callerid;
 	char *method;
-	int *dialplan; 
+	int *dialplan;
+	int *localdialplan; 
 	char *nationalprefix;
 	char *internationalprefix;
 	int *pres;
@@ -151,6 +153,7 @@
 			FREE_ELEM(callerid);
 			FREE_ELEM(method);
 			FREE_ELEM(dialplan);
+			FREE_ELEM(localdialplan);
 			FREE_ELEM(nationalprefix);
 			FREE_ELEM(internationalprefix);
 			FREE_ELEM(pres);
@@ -277,6 +280,8 @@
 						break;
 		case MISDN_CFG_DIALPLAN:	GET_PORTCFG_MEMCPY(dialplan);
 						break;
+	case MISDN_CFG_LOCALDIALPLAN:	GET_PORTCFG_MEMCPY(localdialplan);
+		break;
 		case MISDN_CFG_NATPREFIX:	GET_PORTCFG_STRCPY(nationalprefix);
 						break;
 		case MISDN_CFG_INTERNATPREFIX:
@@ -534,6 +539,8 @@
 									break;
 		case MISDN_CFG_DIALPLAN:	GET_CFG_INT(DIALPLAN, dialplan);
 									break;
+	case MISDN_CFG_LOCALDIALPLAN:	GET_CFG_INT(LOCALDIALPLAN, localdialplan);
+		break;
 		case MISDN_CFG_NATPREFIX:	GET_CFG_STRING(NATIONALPREFIX, nationalprefix);
 									break;
 		case MISDN_CFG_INTERNATPREFIX:
@@ -812,6 +819,7 @@
 		}
 		PARSE_CFG_STR(context);
 		PARSE_CFG_INT(dialplan);
+		PARSE_CFG_INT(localdialplan);
 		PARSE_CFG_STR(nationalprefix);
 		PARSE_CFG_STR(internationalprefix);
 		PARSE_CFG_STR(language);
@@ -963,6 +971,8 @@
 	}
 	if (!port_cfg[0]->dialplan)
 		port_cfg[0]->dialplan = (int *)calloc(1, sizeof(int));
+	if (!port_cfg[0]->localdialplan)
+		port_cfg[0]->localdialplan = (int *)calloc(1, sizeof(int));
 	if (!port_cfg[0]->nationalprefix) {
 		port_cfg[0]->nationalprefix = (char *)malloc(2 * sizeof(char));
 		sprintf(port_cfg[0]->nationalprefix, "0");

Modified: branches/1.2/channels/misdn/Makefile
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/Makefile?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/misdn/Makefile (original)
+++ branches/1.2/channels/misdn/Makefile Thu Dec 15 04:52:30 2005
@@ -5,41 +5,68 @@
 #
 
 # Verify those options with main Makefile
-ifndef LINUX
-LINUX=/lib/modules/$(shell uname -r)/build
-endif
-
-CFLAGS		+= -pipe -c
+CFLAGS		+= -pipe -c -DMISDNUSER_JOLLY
 SOURCES		= isdn_lib.c isdn_msg_parser.c 
 OBJDIR		= .
 OBJS		= isdn_lib.o isdn_msg_parser.o
 
-ifndef MISDNUSER
-MISDNUSER=/usr/src/install-misdn/mISDNuser
-endif
 
-MISDNCFLAGS	+= -I$(MISDNUSER)/include -I$(MISDNUSER)/i4lnet -I$(MISDNUSER)/lib
-MISDNCFLAGS	+= -DMISDNUSER_JOLLY -I$(LINUX)/include
-
-
-all: chan_misdn_lib.a Makefile.ast
+all: chan_misdn_lib.a 
 
 
 %.o: %.c
-	$(CC) $(MISDNCFLAGS) $(CFLAGS) -o $@ $<
-	
+	$(CC) $(CFLAGS) -o $@ $<
+
 
 chan_misdn_lib.a:	$(OBJS)
 	ar crv $@ $(OBJS)
 
-Makefile.ast:	FORCE
-	@echo CFLAGS+=$(MISDNCFLAGS) -Imisdn/ -DCHAN_MISDN_VERSION=\\\"0.2.0\\\" >$@.tmp
-	@echo MISDNUSER = $(MISDNUSER) >>$@.tmp
-	@if [ -r $@ ] && cmp -s $@ $@.tmp; then rm -f $@.tmp; else mv -f $@.tmp $@; fi
+misdn: test_preempt
+	if [ ! -d lib ] ; then \
+		mkdir lib; \
+		cd lib ; \
+		wget http://isdn.jolly.de/download/v3.1/mISDN_for_PBX4Linux-3.0.tar.gz ;\
+		tar xzf mISDN_for_PBX4Linux-3.0.tar.gz; \
+		wget http://isdn.jolly.de/download/v3.1/mISDNuser_for_PBX4Linux-3.0.tar.gz ;\
+		tar xzf mISDNuser_for_PBX4Linux-3.0.tar.gz ;\
+		cd mISDN; patch -p1 <../../mISDN.patch; \
+		cd ../mISDNuser ; patch -p1 <../../mISDNuser.patch; \
+	fi
+	cd lib/mISDN ; make install
+	cd lib/mISDNuser ; make install
+
+LINUX=/lib/modules/$(uname -r)/build
+GCCVERSION=$(shell $(CC) --version  | grep GCC  | cut -d " " -f 3  | cut -d "." -f 1)
+
+test_preempt:
+	@if  grep 'CONFIG_DEBUG_SPINLOCK=y' $(LINUX)/.config   ; then \
+		echo -e "\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!\nDisable the DEBUG_SPINLOCK Setting in your Kernel Config.\n with this option set, mISDN will not work! \n\n" ;\
+		read ; \
+		exit 1 ; \
+	fi
+	@if  grep 'CONFIG_DEBUG_SPINLOCK_SLEEP=y' $(LINUX)/.config   ; then \
+		echo -e "\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!\nDisable the DEBUG_SPINLOCK_SLEEP Setting in your Kernel Config.\n with this option set, mISDN will not work! \n\n" ;\
+		read ; \
+		exit 1 ; \
+	fi
+	@if  grep 'CONFIG_SMP=y' $(LINUX)/.config   ; then \
+		echo -e "\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!\nDisable the SMP Setting in your Kernel Config.\n\n" ; \
+		read ; \
+		exit 1 ; \
+	fi
+	@if test "$(GCCVERSION)" -gt 3 ; then \
+		echo -e "\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!\nYou're using GCC 4! Please downgrade to gcc-3.x and type:\nexport CC=gcc-3.x\nbefore issuing make again.\nyou won't have success with gcc-4!\n\n" ; \
+		read ; \
+		exit 1 ; \
+	fi
+
 
 
 FORCE:
 
+clean: 
+	rm -rf *.a *.o *.so
 
-clean: 
-	rm *.a *.o Makefile.ast
+misdn_clean:
+	rm -rf lib
+

Modified: branches/1.2/channels/misdn/chan_misdn_config.h
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/chan_misdn_config.h?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/misdn/chan_misdn_config.h (original)
+++ branches/1.2/channels/misdn/chan_misdn_config.h Thu Dec 15 04:52:30 2005
@@ -32,6 +32,7 @@
 	MISDN_CFG_CALLERID,            /* char[] */
 	MISDN_CFG_METHOD,              /* char[] */
 	MISDN_CFG_DIALPLAN,            /* int */
+	MISDN_CFG_LOCALDIALPLAN,       /* int */
 	MISDN_CFG_NATPREFIX,           /* char[] */
 	MISDN_CFG_INTERNATPREFIX,      /* char[] */
 	MISDN_CFG_PRES,                /* int (bool) */

Modified: branches/1.2/channels/misdn/ie.c
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/ie.c?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/misdn/ie.c (original)
+++ branches/1.2/channels/misdn/ie.c Thu Dec 15 04:52:30 2005
@@ -26,10 +26,10 @@
 
 #include "isdn_lib_intern.h"
 
-#include <mISDNlib.h>
-#include <isdn_net.h>
-#include <l3dss1.h>
-#include <net_l3.h>
+#include <mISDNuser/mISDNlib.h>
+#include <mISDNuser/isdn_net.h>
+#include <mISDNuser/l3dss1.h>
+#include <mISDNuser/net_l3.h>
 
 
 #define CENTREX_FAC     0x88

Modified: branches/1.2/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/isdn_lib.c?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/misdn/isdn_lib.c (original)
+++ branches/1.2/channels/misdn/isdn_lib.c Thu Dec 15 04:52:30 2005
@@ -91,8 +91,8 @@
 static enum global_states  global_state=MISDN_INITIALIZING;
 
 
-#include <../i4lnet/net_l2.h>
-#include <tone.h>
+#include <mISDNuser/net_l2.h>
+#include <mISDNuser/tone.h>
 #include <unistd.h>
 #include <semaphore.h>
 #include <pthread.h>
@@ -341,6 +341,10 @@
 
 int misdn_inband_avail(struct misdn_bchannel *bc)
 {
+
+	/*if ! early_bconnect we have never inband available*/
+	if ( ! bc->early_bconnect ) return 0;
+	
 	switch (bc->progress_indicator) {
 	case INFO_PI_INBAND_AVAILABLE:
 	case INFO_PI_CALL_NOT_E2E_ISDN:
@@ -421,7 +425,7 @@
 	bc->curptx=0; bc->curprx=0;
 	
 	bc->crypt_key[0] = 0;
-  
+	
 	bc->tone=TONE_NONE;
 	bc->tone_cnt2 = bc->tone_cnt=0;
   
@@ -429,12 +433,15 @@
 	bc->onumplan=NUMPLAN_UNKNOWN;
 	bc->rnumplan=NUMPLAN_UNKNOWN;
 	
+
 	bc->active = 0;
-  
+
+	bc->early_bconnect = 1;
+	
 	bc->ec_enable = 0;
 	bc->ec_deftaps = 128;
 	bc->ec_whenbridged = 0;
-	bc->ec_training = 400;
+	bc->ec_training = 1;
 	
 	
 	bc->orig=0;
@@ -3240,7 +3247,7 @@
 
 	struct misdn_stack *stack=get_stack_by_bc(bc);
 	
-	cb_log(1, stack?stack->port:0,"Sending Control ECHOCAN_ON enblock\n");
+	cb_log(1, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d training:%d\n",bc->ec_deftaps, bc->ec_training);
 	
 	switch (bc->ec_deftaps) {
 	case 4:
@@ -3266,6 +3273,7 @@
 }
 
 
+
 void manager_ec_disable(struct misdn_bchannel *bc)
 {
 	struct misdn_stack *stack=get_stack_by_bc(bc);

Modified: branches/1.2/channels/misdn/isdn_lib.h
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/isdn_lib.h?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/misdn/isdn_lib.h (original)
+++ branches/1.2/channels/misdn/isdn_lib.h Thu Dec 15 04:52:30 2005
@@ -184,6 +184,7 @@
 	
 
 	int te_choose_channel;
+	int early_bconnect;
 	
 	/* dtmf digit */
 	int dtmf;

Modified: branches/1.2/channels/misdn/isdn_lib_intern.h
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/isdn_lib_intern.h?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/misdn/isdn_lib_intern.h (original)
+++ branches/1.2/channels/misdn/isdn_lib_intern.h Thu Dec 15 04:52:30 2005
@@ -2,10 +2,10 @@
 #define ISDN_LIB_INTER
 
 
-#include <mISDNlib.h>
-#include <isdn_net.h>
-#include <l3dss1.h>
-#include <net_l3.h>
+#include <mISDNuser/mISDNlib.h>
+#include <mISDNuser/isdn_net.h>
+#include <mISDNuser/l3dss1.h>
+#include <mISDNuser/net_l3.h>
 
 #include <pthread.h>
 

Modified: branches/1.2/channels/misdn/isdn_msg_parser.c
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/isdn_msg_parser.c?rev=7490&r1=7489&r2=7490&view=diff
==============================================================================
--- branches/1.2/channels/misdn/isdn_msg_parser.c (original)
+++ branches/1.2/channels/misdn/isdn_msg_parser.c Thu Dec 15 04:52:30 2005
@@ -284,31 +284,30 @@
 	{
 		int coding=0, capability, mode=0 /*  2 for packet ! */
 			,user, rate=0x10;
+
+		switch (bc->law) {
+		case INFO_CODEC_ULAW: user=2;
+			break;
+		case INFO_CODEC_ALAW: user=3;
+			break;
+		default:
+			user=3;
+		}
+		
 		switch (bc->capability) {
 		case INFO_CAPABILITY_SPEECH: capability = 0;
-//			cb_log(2, bc->stack->port, " --> Speech\n");
 			break;
 		case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: capability = 8;
-//			cb_log(2, bc->stack->port, " --> cap unres Digital\n");
+			user=-1;
 			break;
 		case INFO_CAPABILITY_DIGITAL_RESTRICTED: capability = 9;
-//			cb_log(2, bc->stack->port, " --> cap res Digital\n");
+			user=-1;
 			break;
 		default:
-//			cb_log(2, bc->stack->port, " --> cap Speech\n");
 			capability=bc->capability; 
 		}
 		
-		switch (bc->law) {
-		case INFO_CODEC_ULAW: user=2;
-//			cb_log(2, bc->stack->port, " --> Codec Ulaw\n");
-			break;
-		case INFO_CODEC_ALAW: user=3;
-//			cb_log(2, bc->stack->port, " --> Codec Alaw\n");
-			break;
-		default:
-			user=3;
-		}
+		
     
 		enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
 	}

Added: branches/1.2/channels/misdn/mISDN.patch
URL: http://svn.digium.com/view/asterisk/branches/1.2/channels/misdn/mISDN.patch?rev=7490&view=auto
==============================================================================
--- branches/1.2/channels/misdn/mISDN.patch (added)
+++ branches/1.2/channels/misdn/mISDN.patch Thu Dec 15 04:52:30 2005
@@ -1,0 +1,2500 @@
+diff -u -r -P /tmp/mISDN/drivers/isdn/hardware/mISDN/arith.h mISDN/drivers/isdn/hardware/mISDN/arith.h
+--- /tmp/mISDN/drivers/isdn/hardware/mISDN/arith.h	1970-01-01 01:00:00.000000000 +0100
++++ mISDN/drivers/isdn/hardware/mISDN/arith.h	2005-12-02 09:57:08.000000000 +0100
+@@ -0,0 +1,347 @@
++#ifndef _ZAPTEL_ARITH_H
++#define _ZAPTEL_ARITH_H
++/*
++ * Handy add/subtract functions to operate on chunks of shorts.
++ * Feel free to add customizations for additional architectures
++ *
++ */
++
++#ifdef CONFIG_ZAPTEL_MMX
++#ifdef ZT_CHUNKSIZE
++static inline void __ACSS(volatile short *dst, const short *src)
++{
++	__asm__ __volatile__ (
++	        "movq 0(%0), %%mm0;\n"
++	        "movq 0(%1), %%mm1;\n"
++                "movq 8(%0), %%mm2;\n"
++	        "movq 8(%1), %%mm3;\n"
++	        "paddsw %%mm1, %%mm0;\n"
++	        "paddsw %%mm3, %%mm2;\n"
++                "movq %%mm0, 0(%0);\n"
++                "movq %%mm2, 8(%0);\n"
++	    : "=r" (dst)
++	    : "r" (src), "0" (dst)
++	    : "memory"
++#if CLOBBERMMX
++	    , "%mm0", "%mm1", "%mm2", "%mm3"
++#endif
++      );
++
++}
++static inline void __SCSS(volatile short *dst, const short *src)
++{
++	__asm__ __volatile__ (
++	        "movq 0(%0), %%mm0;\n"
++	        "movq 0(%1), %%mm1;\n"
++                "movq 8(%0), %%mm2;\n"
++	        "movq 8(%1), %%mm3;\n"
++	        "psubsw %%mm1, %%mm0;\n"
++	        "psubsw %%mm3, %%mm2;\n"
++                "movq %%mm0, 0(%0);\n"
++                "movq %%mm2, 8(%0);\n"
++	    : "=r" (dst)
++	    : "r" (src), "0" (dst)
++	    : "memory"
++#if CLOBBERMMX
++	    , "%mm0", "%mm1", "%mm2", "%mm3"
++#endif
++      );
++
++}
++
++#if (ZT_CHUNKSIZE == 8)
++#define ACSS(a,b) __ACSS(a,b)
++#define SCSS(a,b) __SCSS(a,b)
++#elif (ZT_CHUNKSIZE > 8)
++static inline void ACSS(volatile short *dst, const short *src)
++{
++	int x;
++	for (x=0;x<ZT_CHUNKSIZE;x+=8)
++		__ACSS(dst + x, src + x);
++}
++static inline void SCSS(volatile short *dst, const short *src)
++{
++	int x;
++	for (x=0;x<ZT_CHUNKSIZE;x+=8)
++		__SCSS(dst + x, src + x);
++}
++#else
++#error No MMX for ZT_CHUNKSIZE < 8
++#endif
++#endif
++static inline int CONVOLVE(const int *coeffs, const short *hist, int len)
++{
++	int sum;
++	/* Divide length by 16 */
++	len >>= 4;
++	
++	/* Clear our accumulator, mm4 */
++	
++	/* 
++	
++	   For every set of eight...
++	
++	   Load 16 coefficients into four registers...
++	   Shift each word right 16 to make them shorts...
++	   Pack the resulting shorts into two registers...
++	   With the coefficients now in mm0 and mm2, load the 
++	        history into mm1 and mm3...
++	   Multiply/add mm1 into mm0, and mm3 into mm2...
++	   Add mm2 into mm0 (without saturation, alas).  Now we have two half-results.
++	   Accumulate in mm4 (again, without saturation, alas)
++	*/
++	__asm__ (
++		"pxor %%mm4, %%mm4;\n"
++		"mov %1, %%edi;\n"
++		"mov %2, %%esi;\n"
++		"mov %3, %%ecx;\n"
++		"1:"
++			"movq  0(%%edi), %%mm0;\n"
++			"movq  8(%%edi), %%mm1;\n"
++			"movq 16(%%edi), %%mm2;\n"
++			"movq 24(%%edi), %%mm3;\n"
++			/* can't use 4/5 since 4 is the accumulator for us */
++			"movq 32(%%edi), %%mm6;\n"
++			"movq 40(%%edi), %%mm7;\n"
++			"psrad $16, %%mm0;\n"
++			"psrad $16, %%mm1;\n"
++			"psrad $16, %%mm2;\n"
++			"psrad $16, %%mm3;\n"
++			"psrad $16, %%mm6;\n"
++			"psrad $16, %%mm7;\n"
++			"packssdw %%mm1, %%mm0;\n"
++			"packssdw %%mm3, %%mm2;\n"
++			"packssdw %%mm7, %%mm6;\n"
++			"movq 0(%%esi), %%mm1;\n"
++			"movq 8(%%esi), %%mm3;\n"
++			"movq 16(%%esi), %%mm7;\n"
++			"pmaddwd %%mm1, %%mm0;\n"
++			"pmaddwd %%mm3, %%mm2;\n"
++			"pmaddwd %%mm7, %%mm6;\n"
++			"paddd %%mm6, %%mm4;\n"
++			"paddd %%mm2, %%mm4;\n"
++			"paddd %%mm0, %%mm4;\n"
++			/* Come back and do for the last few bytes */
++			"movq 48(%%edi), %%mm6;\n"
++			"movq 56(%%edi), %%mm7;\n"
++			"psrad $16, %%mm6;\n"
++			"psrad $16, %%mm7;\n"
++			"packssdw %%mm7, %%mm6;\n"
++			"movq 24(%%esi), %%mm7;\n"
++			"pmaddwd %%mm7, %%mm6;\n"
++			"paddd %%mm6, %%mm4;\n"
++			"add $64, %%edi;\n"
++			"add $32, %%esi;\n"
++			"dec %%ecx;\n"
++		"jnz 1b;\n"
++		"movq %%mm4, %%mm0;\n"
++		"psrlq $32, %%mm0;\n"
++		"paddd %%mm0, %%mm4;\n"
++		"movd %%mm4, %0;\n"
++		: "=r" (sum)
++		: "r" (coeffs), "r" (hist), "r" (len)
++		: "%ecx", "%edi", "%esi"
++	);
++		
++	return sum;
++}
++
++static inline void UPDATE(volatile int *taps, const short *history, const int nsuppr, const int ntaps)
++{
++	int i;
++	int correction;
++	for (i=0;i<ntaps;i++) {
++		correction = history[i] * nsuppr;
++		taps[i] += correction;
++	}
++}
++
++static inline void UPDATE2(volatile int *taps, volatile short *taps_short, const short *history, const int nsuppr, const int ntaps)
++{
++	int i;
++	int correction;
++#if 0
++	ntaps >>= 4;
++	/* First, load up taps, */
++	__asm__ (
++		"pxor %%mm4, %%mm4;\n"
++		"mov %0, %%edi;\n"
++		"mov %1, %%esi;\n"
++		"mov %3, %%ecx;\n"
++		"1:"
++		"jnz 1b;\n"
++		"movq %%mm4, %%mm0;\n"
++		"psrlq $32, %%mm0;\n"
++		"paddd %%mm0, %%mm4;\n"
++		"movd %%mm4, %0;\n"
++		: "=r" (taps), "=r" (taps_short)
++		: "r" (history), "r" (nsuppr), "r" (ntaps), "0" (taps)
++		: "%ecx", "%edi", "%esi"
++	);
++#endif
++#if 1
++	for (i=0;i<ntaps;i++) {
++		correction = history[i] * nsuppr;
++		taps[i] += correction;
++		taps_short[i] = taps[i] >> 16;
++	}
++#endif	
++}
++
++static inline int CONVOLVE2(const short *coeffs, const short *hist, int len)
++{
++	int sum;
++	/* Divide length by 16 */
++	len >>= 4;
++	
++	/* Clear our accumulator, mm4 */
++	
++	/* 
++	
++	   For every set of eight...
++	   Load in eight coefficients and eight historic samples, multliply add and
++	   accumulate the result
++	*/
++	__asm__ (
++		"pxor %%mm4, %%mm4;\n"
++		"mov %1, %%edi;\n"
++		"mov %2, %%esi;\n"
++		"mov %3, %%ecx;\n"
++		"1:"
++			"movq  0(%%edi), %%mm0;\n"
++			"movq  8(%%edi), %%mm2;\n"
++			"movq 0(%%esi), %%mm1;\n"
++			"movq 8(%%esi), %%mm3;\n"
++			"pmaddwd %%mm1, %%mm0;\n"
++			"pmaddwd %%mm3, %%mm2;\n"
++			"paddd %%mm2, %%mm4;\n"
++			"paddd %%mm0, %%mm4;\n"
++			"movq  16(%%edi), %%mm0;\n"
++			"movq  24(%%edi), %%mm2;\n"
++			"movq 16(%%esi), %%mm1;\n"
++			"movq 24(%%esi), %%mm3;\n"
++			"pmaddwd %%mm1, %%mm0;\n"
++			"pmaddwd %%mm3, %%mm2;\n"
++			"paddd %%mm2, %%mm4;\n"
++			"paddd %%mm0, %%mm4;\n"
++			"add $32, %%edi;\n"
++			"add $32, %%esi;\n"
++			"dec %%ecx;\n"
++		"jnz 1b;\n"
++		"movq %%mm4, %%mm0;\n"
++		"psrlq $32, %%mm0;\n"
++		"paddd %%mm0, %%mm4;\n"
++		"movd %%mm4, %0;\n"
++		: "=r" (sum)
++		: "r" (coeffs), "r" (hist), "r" (len)
++		: "%ecx", "%edi", "%esi"
++	);
++		
++	return sum;
++}
++static inline short MAX16(const short *y, int len, int *pos)
++{
++	int k;
++	short max = 0;
++	int bestpos = 0;
++	for (k=0;k<len;k++) {
++		if (max < y[k]) {
++			bestpos = k;
++			max = y[k];
++		}
++	}
++	*pos = (len - 1 - bestpos);
++	return max;
++}
++
++
++
++#else
++
++#ifdef ZT_CHUNKSIZE
++static inline void ACSS(short *dst, short *src)
++{
++	int x,sum;
++	/* Add src to dst with saturation, storing in dst */
++	for (x=0;x<ZT_CHUNKSIZE;x++) {
++		sum = dst[x]+src[x];
++		if (sum > 32767)
++			sum = 32767;
++		else if (sum < -32768)
++			sum = -32768;
++		dst[x] = sum;
++	}
++}
++
++static inline void SCSS(short *dst, short *src)
++{
++	int x,sum;
++	/* Add src to dst with saturation, storing in dst */
++	for (x=0;x<ZT_CHUNKSIZE;x++) {
++		sum = dst[x]-src[x];
++		if (sum > 32767)
++			sum = 32767;
++		else if (sum < -32768)
++			sum = -32768;
++		dst[x] = sum;
++	}
++}
++
++#endif	/* ZT_CHUNKSIZE */
++
++static inline int CONVOLVE(const int *coeffs, const short *hist, int len)
++{
++	int x;
++	int sum = 0;
++	for (x=0;x<len;x++)
++		sum += (coeffs[x] >> 16) * hist[x];
++	return sum;
++}
++
++static inline int CONVOLVE2(const short *coeffs, const short *hist, int len)
++{
++	int x;
++	int sum = 0;
++	for (x=0;x<len;x++)
++		sum += coeffs[x] * hist[x];
++	return sum;
++}
++
++static inline void UPDATE(int *taps, const short *history, const int nsuppr, const int ntaps)
++{
++	int i;
++	int correction;
++	for (i=0;i<ntaps;i++) {
++		correction = history[i] * nsuppr;
++		taps[i] += correction;
++	}
++}
++
++static inline void UPDATE2(int *taps, short *taps_short, const short *history, const int nsuppr, const int ntaps)
++{
++	int i;
++	int correction;
++	for (i=0;i<ntaps;i++) {
++		correction = history[i] * nsuppr;
++		taps[i] += correction;
++		taps_short[i] = taps[i] >> 16;
++	}
++}
++
++static inline short MAX16(const short *y, int len, int *pos)
++{
++	int k;
++	short max = 0;
++	int bestpos = 0;
++	for (k=0;k<len;k++) {
++		if (max < y[k]) {
++			bestpos = k;
++			max = y[k];
++		}
++	}
++	*pos = (len - 1 - bestpos);
++	return max;
++}
++
++#endif	/* MMX */
++#endif	/* _ZAPTEL_ARITH_H */
+diff -u -r -P /tmp/mISDN/drivers/isdn/hardware/mISDN/biquad.h mISDN/drivers/isdn/hardware/mISDN/biquad.h
+--- /tmp/mISDN/drivers/isdn/hardware/mISDN/biquad.h	1970-01-01 01:00:00.000000000 +0100
++++ mISDN/drivers/isdn/hardware/mISDN/biquad.h	2005-12-02 09:57:08.000000000 +0100
+@@ -0,0 +1,73 @@
++/*
++ * SpanDSP - a series of DSP components for telephony
++ *
++ * biquad.h - General telephony bi-quad section routines (currently this just
++ *            handles canonic/type 2 form)
++ *
++ * Written by Steve Underwood <steveu at coppice.org>
++ *
++ * Copyright (C) 2001 Steve Underwood
++ *
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++typedef struct
++{
++    int32_t gain;
++    int32_t a1;
++    int32_t a2;
++    int32_t b1;
++    int32_t b2;
++
++    int32_t z1;
++    int32_t z2;
++} biquad2_state_t;
++
++static inline void biquad2_init (biquad2_state_t *bq,
++                	 	 int32_t gain,
++		                 int32_t a1,
++            	                 int32_t a2,
++		                 int32_t b1,
++		                 int32_t b2)
++{
++    bq->gain = gain;
++    bq->a1 = a1;
++    bq->a2 = a2;
++    bq->b1 = b1;
++    bq->b2 = b2;
++    
++    bq->z1 = 0;
++    bq->z2 = 0;    
++}
++/*- End of function --------------------------------------------------------*/
++    
++static inline int16_t biquad2 (biquad2_state_t *bq, int16_t sample)
++{
++    int32_t y;
++    int32_t z0;
++    
++    z0 = sample*bq->gain + bq->z1*bq->a1 + bq->z2*bq->a2;
++    y = z0 + bq->z1*bq->b1 + bq->z2*bq->b2;
++
++    bq->z2 = bq->z1;
++    bq->z1 = z0 >> 15;
++    y >>= 15;
++    return  y;
++}
++/*- End of function --------------------------------------------------------*/
++/*- End of file ------------------------------------------------------------*/
+diff -u -r -P /tmp/mISDN/drivers/isdn/hardware/mISDN/dsp_cancel.c mISDN/drivers/isdn/hardware/mISDN/dsp_cancel.c
+--- /tmp/mISDN/drivers/isdn/hardware/mISDN/dsp_cancel.c	1970-01-01 01:00:00.000000000 +0100
++++ mISDN/drivers/isdn/hardware/mISDN/dsp_cancel.c	2005-12-02 09:57:08.000000000 +0100
+@@ -0,0 +1,390 @@
++/* $Id: mISDN_echo_cancel.patch,v 1.1 2005/11/07 16:01:31 nadi Exp $
++ *
++ * Simple but fast Echo cancellation for mISDN_dsp.
++ *
++ * Copyright Andreas Eversberg (jolly at jolly.de)
++ *
++ * This software may be used and distributed according to the terms
++ * of the GNU General Public License, incorporated herein by reference.
++ *
++ */
++
++#include "layer1.h"
++#include "helper.h"
++#include "debug.h"
++#include "dsp.h"
++
++
++/*
++ * how this works:
++ *
++ * 
++ * 
++ */
++void bchdev_echocancel_chunk(dsp_t* dev, uint8_t *rxchunk, uint8_t *txchunk, uint16_t size);
++int bchdev_echocancel_activate(dsp_t* dev, int deftaps, int train);
++void bchdev_echocancel_deactivate(dsp_t* dev);
++
++
++
++
++
++
++static char flip_table[256];
++
++void dsp_cancel_init_flip_bits()
++{
++	int i,k;
++	
++	for (i = 0 ; i < 256 ; i++) {
++		unsigned char sample = 0 ;
++		for (k = 0; k<8; k++) {
++			if ( i & 1 << k ) sample |= 0x80 >>  k;
++		}
++		flip_table[i] = sample;
++	}
++}
++
++static unsigned char * flip_buf_bits ( unsigned char * buf , int len)
++{
++	int i;
++	char * start = buf;
++	
++	for (i = 0 ; i < len; i++) {
++		buf[i] = flip_table[buf[i]];
++	}
++	
++	return start;
++}
++
++
++
++void
++dsp_cancel_tx(dsp_t *dsp, u8 *data, int len)
++{
++	if (!dsp ) return ;
++	if (!data) return;
++	
++	if (dsp->txbuflen + len < ECHOCAN_BUFLEN) {
++		memcpy(&dsp->txbuf[dsp->txbuflen],data,len);
++		dsp->txbuflen+=len;
++	} else {
++		printk("ECHOCAN: TXBUF Overflow len:%d newlen:%d\n",dsp->txbuflen,len);
++		dsp->txbuflen=0;
++	}
++	
++}
++
++void
++dsp_cancel_rx(dsp_t *dsp, u8 *data, int len)
++{
++	if (!dsp ) return ;
++	if (!data) return;
++	
++	if (len <= dsp->txbuflen) {
++		char tmp[ECHOCAN_BUFLEN];
++		
++		int delta=dsp->txbuflen-len;
++		
++		memcpy(tmp,&dsp->txbuf[len],delta);
++		
++		flip_buf_bits(data,len);
++		flip_buf_bits(dsp->txbuf,len);
++		bchdev_echocancel_chunk(dsp, data, dsp->txbuf, len);
++		flip_buf_bits(data,len);
++		
++		memcpy(dsp->txbuf,tmp,delta);
++		dsp->txbuflen=delta;
++		//dsp->txbuflen=0;
++		
++		//bchdev_echocancel_chunk(dsp,  dsp->txbuf, data, len);
++	} else {
++		printk("ECHOCAN: TXBUF Underrun len:%d newlen:%d\n",dsp->txbuflen,len);
++	}
++	
++}
++
++int
++dsp_cancel_init(dsp_t *dsp, int deftaps, int training, int delay)
++{
++	
++	if (!dsp) return -1;
++	
++	printk("DSP_CANCEL_INIT called\n");
++	
++	if (delay < 0)
++	{
++		printk("Disabling EC\n");
++		dsp->cancel_enable = 0;
++		
++		dsp->txbuflen=0;
++		
++		bchdev_echocancel_deactivate(dsp);
++		
++		return(0);
++	}
++	
++	dsp->txbuflen=0;
++	dsp->rxbuflen=0;
++	
++	
++	bchdev_echocancel_activate(dsp,deftaps, training);
++	
++	printk("Enabling EC\n");
++	dsp->cancel_enable = 1;
++	return(0);
++}
++
++
++
++
++
++/*****************************************************/
++#define __ECHO_STATE_MUTE                       (1 << 8)
++#define ECHO_STATE_IDLE                         (0)
++#define ECHO_STATE_PRETRAINING          (1 | (__ECHO_STATE_MUTE))
++#define ECHO_STATE_STARTTRAINING        (2 | (__ECHO_STATE_MUTE))
++#define ECHO_STATE_AWAITINGECHO         (3 | (__ECHO_STATE_MUTE))
++#define ECHO_STATE_TRAINING                     (4 | (__ECHO_STATE_MUTE))
++#define ECHO_STATE_ACTIVE                       (5)
++
++#define AMI_MASK 0x55
++
++
++static unsigned char linear2alaw (short linear)
++{
++	int mask;
++	int seg;
++	int pcm_val;
++	static int seg_end[8] =
++		{
++			0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
++		};
++    
++	pcm_val = linear;
++	if (pcm_val >= 0)
++	{
++		/* Sign (7th) bit = 1 */
++		mask = AMI_MASK | 0x80;
++	}
++	else
++	{
++		/* Sign bit = 0 */
++		mask = AMI_MASK;
++		pcm_val = -pcm_val;
++	}
++
++	/* Convert the scaled magnitude to segment number. */
++	for (seg = 0;  seg < 8;  seg++)
++	{
++		if (pcm_val <= seg_end[seg])
++			break;
++	}
++	/* Combine the sign, segment, and quantization bits. */
++	return  ((seg << 4) | ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;
++}
++
++/*- End of function --------------------------------------------------------*/
++
++static short int alaw2linear (uint8_t alaw)
++{
++	int i;
++	int seg;
++
++	alaw ^= AMI_MASK;
++	i = ((alaw & 0x0F) << 4);
++	seg = (((int) alaw & 0x70) >> 4);
++	if (seg)
++		i = (i + 0x100) << (seg - 1);
++	return (short int) ((alaw & 0x80)  ?  i  :  -i);
++}
++
++
++/** @return string of given echo cancellation state */
++char* bchdev_echocancel_statestr(uint16_t state)
++{
++  switch(state) {
++  case ECHO_STATE_IDLE:
++    return "idle";
++    break;
++  case ECHO_STATE_PRETRAINING:
++    return "pre-training";
++    break;
++  case ECHO_STATE_STARTTRAINING:
++    return "transmit impulse";
++    break;
++  case ECHO_STATE_AWAITINGECHO:
++    return "awaiting echo";
++    break;
++  case ECHO_STATE_TRAINING:
++    return "training start";
++    break;
++  case ECHO_STATE_ACTIVE:
++    return "training finished";
++    break;
++  default:
++    return "unknown";
++  }
++}
++
++/** Changes state of echo cancellation to given state */
++void bchdev_echocancel_setstate(dsp_t* dev, uint16_t state)
++{
++  char* statestr = bchdev_echocancel_statestr(state);
++  
++  printk("bchdev: echo cancel state %d (%s)\n", state & 0xff, statestr);
++  if (state == ECHO_STATE_ACTIVE)
++	  printk("bchdev: %d taps trained\n", dev->echolastupdate);
++  dev->echostate = state;
++}
++
++static int buf_size=0;
++static int ec_timer=2000;
++//static int ec_timer=1000;
++
++
++/** Activates echo cancellation for the given bch_dev, device must have been locked before! */
++int bchdev_echocancel_activate(dsp_t* dev, int deftaps, int training)
++{
++  int taps;
++  
++  if (! dev) return -EINVAL;
++  
++  if (dev->ec && dev->ecdis_rd && dev->ecdis_wr) {
++	  // already active
++    return 0;
++  }
++  
++  if (deftaps>0) {
++	  taps=deftaps;
++  } else {
++	  taps=128;
++  }
++  
++  
++  switch (buf_size) {
++  case  0: taps +=    0; break;
++  case  1: taps +=  256-128; break;
++  case  2: taps +=  512-128; break;
++  default: taps += 1024-128;
++  }
++  
++  if (!dev->ec) dev->ec = echo_can_create(taps, 0);
++  if (!dev->ec) {
++	  return -ENOMEM;
++  }
++  
++  dev->echolastupdate = 0;
++
++  if (!training) {
++	  dev->echotimer=0;
++	  bchdev_echocancel_setstate(dev, ECHO_STATE_IDLE);
++  } else {
++	  if (training<10) 
++		  training= ec_timer;
++	  
++	  dev->echotimer      = training;
++	  bchdev_echocancel_setstate(dev, ECHO_STATE_PRETRAINING);
++
++  }
++  
++  if (!dev->ecdis_rd) dev->ecdis_rd = kmalloc(sizeof(echo_can_disable_detector_state_t), GFP_KERNEL);
++  if (!dev->ecdis_rd) {
++	  kfree(dev->ec); dev->ec = NULL;
++	  return -ENOMEM;
++  }
++  echo_can_disable_detector_init(dev->ecdis_rd);
++  
++  if (!dev->ecdis_wr) dev->ecdis_wr = kmalloc(sizeof(echo_can_disable_detector_state_t), GFP_KERNEL);
++  if (!dev->ecdis_wr) {
++	  kfree(dev->ec); dev->ec = NULL;
++	  kfree(dev->ecdis_rd); dev->ecdis_rd = NULL;
++    return -ENOMEM;
++  }
++  echo_can_disable_detector_init(dev->ecdis_wr);
++
++  return 0;
++}
++
++/** Deactivates echo cancellation for the given bch_dev, device must have been locked before! */
++void bchdev_echocancel_deactivate(dsp_t* dev)
++{
++  if (! dev) return;
++

[... 2208 lines stripped ...]


More information about the asterisk-commits mailing list